Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
K
koko
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
koko
Commits
8b06c4a1
Commit
8b06c4a1
authored
May 09, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改 认证
parent
93d1b3f1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
128 additions
and
149 deletions
+128
-149
server.go
pkg/auth/server.go
+39
-33
client.go
pkg/common/client.go
+2
-2
session.go
pkg/handler/session.go
+71
-71
terminal.go
pkg/model/terminal.go
+1
-1
users.go
pkg/model/users.go
+2
-3
accesskey.go
pkg/service/accesskey.go
+5
-5
perms.go
pkg/service/perms.go
+2
-2
users.go
pkg/service/users.go
+5
-31
handler.go
pkg/webssh/handler.go
+1
-1
No files found.
pkg/auth/server.go
View file @
8b06c4a1
package
auth
package
auth
import
(
import
(
"cocogo/pkg/cctx"
"cocogo/pkg/i18n"
"strings"
"strings"
"github.com/gliderlabs/ssh"
"github.com/gliderlabs/ssh"
gossh
"golang.org/x/crypto/ssh"
gossh
"golang.org/x/crypto/ssh"
"cocogo/pkg/cctx"
"cocogo/pkg/common"
"cocogo/pkg/common"
"cocogo/pkg/i18n"
"cocogo/pkg/logger"
"cocogo/pkg/logger"
"cocogo/pkg/service"
"cocogo/pkg/service"
)
)
...
@@ -16,34 +16,34 @@ import (
...
@@ -16,34 +16,34 @@ import (
var
mfaInstruction
=
i18n
.
T
(
"Please enter 6 digits."
)
var
mfaInstruction
=
i18n
.
T
(
"Please enter 6 digits."
)
var
mfaQuestion
=
i18n
.
T
(
"[MFA auth]: "
)
var
mfaQuestion
=
i18n
.
T
(
"[MFA auth]: "
)
var
contentKeyMFASeed
=
"MFASeed"
const
(
actionAccepted
=
"Accepted"
actionFailed
=
"Failed"
actionPartialAccepted
=
"Partial accepted"
)
func
checkAuth
(
ctx
ssh
.
Context
,
password
,
publicKey
string
)
(
res
ssh
.
AuthResult
)
{
func
checkAuth
(
ctx
ssh
.
Context
,
password
,
publicKey
string
)
(
res
ssh
.
AuthResult
)
{
username
:=
ctx
.
User
()
username
:=
ctx
.
User
()
remoteAddr
:=
strings
.
Split
(
ctx
.
RemoteAddr
()
.
String
(),
":"
)[
0
]
resp
,
err
:=
service
.
Authenticate
(
username
,
password
,
publicKey
,
remoteAddr
,
"T"
)
authMethod
:=
"publickey"
authMethod
:=
"publickey"
action
:=
"Accepted"
action
:=
actionAccepted
res
=
ssh
.
AuthFailed
res
=
ssh
.
AuthFailed
if
password
!=
""
{
if
password
!=
""
{
authMethod
=
"password"
authMethod
=
"password"
}
}
if
err
!=
nil
{
remoteAddr
:=
strings
.
Split
(
ctx
.
RemoteAddr
()
.
String
(),
":"
)[
0
]
action
=
"Failed"
}
else
if
resp
.
Seed
!=
""
&&
resp
.
Token
==
""
{
resp
,
err
:=
service
.
Authenticate
(
username
,
password
,
publicKey
,
remoteAddr
,
"T"
)
ctx
.
SetValue
(
contentKeyMFASeed
,
resp
.
Seed
)
if
err
!=
nil
{
res
=
ssh
.
AuthPartiallySuccessful
action
=
actionFailed
}
else
{
logger
.
Infof
(
"%s %s for %s from %s"
,
action
,
authMethod
,
username
,
remoteAddr
)
re
s
=
ssh
.
AuthSuccessful
re
turn
}
}
if
resp
!=
nil
{
if
resp
!=
nil
{
switch
resp
.
User
.
IsMFA
{
switch
resp
.
User
.
OTPLevel
{
case
0
:
case
0
:
res
=
ssh
.
AuthSuccessful
res
=
ssh
.
AuthSuccessful
case
1
:
case
1
,
2
:
res
=
ssh
.
AuthPartiallySuccessful
action
=
actionPartialAccepted
case
2
:
res
=
ssh
.
AuthPartiallySuccessful
res
=
ssh
.
AuthPartiallySuccessful
default
:
default
:
}
}
...
@@ -51,14 +51,12 @@ func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult)
...
@@ -51,14 +51,12 @@ func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult)
ctx
.
SetValue
(
cctx
.
ContextKeySeed
,
resp
.
Seed
)
ctx
.
SetValue
(
cctx
.
ContextKeySeed
,
resp
.
Seed
)
ctx
.
SetValue
(
cctx
.
ContextKeyToken
,
resp
.
Token
)
ctx
.
SetValue
(
cctx
.
ContextKeyToken
,
resp
.
Token
)
}
}
logger
.
Infof
(
"%s %s for %s from %s"
,
action
,
authMethod
,
username
,
remoteAddr
)
logger
.
Infof
(
"%s %s for %s from %s"
,
action
,
authMethod
,
username
,
remoteAddr
)
return
res
return
res
}
}
func
CheckUserPassword
(
ctx
ssh
.
Context
,
password
string
)
ssh
.
AuthResult
{
func
CheckUserPassword
(
ctx
ssh
.
Context
,
password
string
)
ssh
.
AuthResult
{
res
:=
checkAuth
(
ctx
,
password
,
""
)
return
checkAuth
(
ctx
,
password
,
""
)
return
res
}
}
func
CheckUserPublicKey
(
ctx
ssh
.
Context
,
key
ssh
.
PublicKey
)
ssh
.
AuthResult
{
func
CheckUserPublicKey
(
ctx
ssh
.
Context
,
key
ssh
.
PublicKey
)
ssh
.
AuthResult
{
...
@@ -67,32 +65,40 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult {
...
@@ -67,32 +65,40 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult {
return
checkAuth
(
ctx
,
""
,
publicKey
)
return
checkAuth
(
ctx
,
""
,
publicKey
)
}
}
func
CheckMFA
(
ctx
ssh
.
Context
,
challenger
gossh
.
KeyboardInteractiveChallenge
)
ssh
.
AuthResult
{
func
CheckMFA
(
ctx
ssh
.
Context
,
challenger
gossh
.
KeyboardInteractiveChallenge
)
(
res
ssh
.
AuthResult
)
{
username
:=
ctx
.
User
()
username
:=
ctx
.
User
()
remoteAddr
:=
strings
.
Split
(
ctx
.
RemoteAddr
()
.
String
(),
":"
)[
0
]
res
=
ssh
.
AuthFailed
defer
func
()
{
authMethod
:=
"MFA"
if
res
==
ssh
.
AuthSuccessful
{
action
:=
actionAccepted
logger
.
Infof
(
"%s %s for %s from %s"
,
action
,
authMethod
,
username
,
remoteAddr
)
}
else
{
action
:=
actionFailed
logger
.
Errorf
(
"%s %s for %s from %s"
,
action
,
authMethod
,
username
,
remoteAddr
)
}
}()
answers
,
err
:=
challenger
(
username
,
mfaInstruction
,
[]
string
{
mfaQuestion
},
[]
bool
{
true
})
answers
,
err
:=
challenger
(
username
,
mfaInstruction
,
[]
string
{
mfaQuestion
},
[]
bool
{
true
})
if
err
!=
nil
{
if
err
!=
nil
||
len
(
answers
)
!=
1
{
return
ssh
.
AuthFailed
return
}
if
len
(
answers
)
!=
1
{
return
ssh
.
AuthFailed
}
}
mfaCode
:=
answers
[
0
]
mfaCode
:=
answers
[
0
]
seed
,
ok
:=
ctx
.
Value
(
c
ontentKeyMFA
Seed
)
.
(
string
)
seed
,
ok
:=
ctx
.
Value
(
c
ctx
.
ContextKey
Seed
)
.
(
string
)
if
!
ok
{
if
!
ok
{
logger
.
Error
(
"Mfa Auth failed, may be user password or publickey auth failed"
)
logger
.
Error
(
"Mfa Auth failed, may be user password or publickey auth failed"
)
return
ssh
.
AuthFailed
return
}
}
resp
,
err
:=
service
.
CheckUserOTP
(
seed
,
mfaCode
)
resp
,
err
:=
service
.
CheckUserOTP
(
seed
,
mfaCode
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
"Mfa Auth failed: "
,
err
)
logger
.
Error
(
"Mfa Auth failed: "
,
err
)
return
ssh
.
AuthFailed
return
}
}
if
resp
.
Token
!=
""
{
if
resp
.
Token
!=
""
{
return
ssh
.
AuthSuccessful
res
=
ssh
.
AuthSuccessful
return
}
}
return
ssh
.
AuthFailed
return
}
}
func
CheckUserNeedMFA
(
ctx
ssh
.
Context
)
(
methods
[]
string
)
{
func
CheckUserNeedMFA
(
ctx
ssh
.
Context
)
(
methods
[]
string
)
{
...
...
pkg/common/client.go
View file @
8b06c4a1
...
@@ -85,7 +85,7 @@ func (c *Client) parseUrlQuery(url string, params []map[string]string) string {
...
@@ -85,7 +85,7 @@ func (c *Client) parseUrlQuery(url string, params []map[string]string) string {
return
url
return
url
}
}
func
(
c
*
Client
)
P
arseUrl
(
url
string
,
params
[]
map
[
string
]
string
)
string
{
func
(
c
*
Client
)
p
arseUrl
(
url
string
,
params
[]
map
[
string
]
string
)
string
{
url
=
c
.
parseUrlQuery
(
url
,
params
)
url
=
c
.
parseUrlQuery
(
url
,
params
)
if
c
.
BaseHost
!=
""
{
if
c
.
BaseHost
!=
""
{
url
=
strings
.
TrimRight
(
c
.
BaseHost
,
"/"
)
+
url
url
=
strings
.
TrimRight
(
c
.
BaseHost
,
"/"
)
+
url
...
@@ -126,7 +126,7 @@ func (c *Client) SetReqHeaders(req *http.Request) {
...
@@ -126,7 +126,7 @@ func (c *Client) SetReqHeaders(req *http.Request) {
}
}
func
(
c
*
Client
)
NewRequest
(
method
,
url
string
,
body
interface
{},
params
[]
map
[
string
]
string
)
(
req
*
http
.
Request
,
err
error
)
{
func
(
c
*
Client
)
NewRequest
(
method
,
url
string
,
body
interface
{},
params
[]
map
[
string
]
string
)
(
req
*
http
.
Request
,
err
error
)
{
url
=
c
.
P
arseUrl
(
url
,
params
)
url
=
c
.
p
arseUrl
(
url
,
params
)
reader
,
err
:=
c
.
marshalData
(
body
)
reader
,
err
:=
c
.
marshalData
(
body
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
...
...
pkg/handler/session.go
View file @
8b06c4a1
...
@@ -59,19 +59,19 @@ type InteractiveHandler struct {
...
@@ -59,19 +59,19 @@ type InteractiveHandler struct {
mu
sync
.
RWMutex
mu
sync
.
RWMutex
}
}
func
(
i
*
InteractiveHandler
)
displayBanner
()
{
func
(
h
*
InteractiveHandler
)
displayBanner
()
{
displayBanner
(
i
.
sess
,
i
.
user
.
Name
)
displayBanner
(
h
.
sess
,
h
.
user
.
Name
)
}
}
func
(
i
*
InteractiveHandler
)
preDispatch
()
{
func
(
h
*
InteractiveHandler
)
preDispatch
()
{
i
.
displayBanner
()
h
.
displayBanner
()
i
.
onceLoad
.
Do
(
func
()
{
h
.
onceLoad
.
Do
(
func
()
{
i
.
loadUserAssets
()
h
.
loadUserAssets
()
i
.
loadUserAssetNodes
()
h
.
loadUserAssetNodes
()
})
})
}
}
func
(
i
*
InteractiveHandler
)
watchWinSizeChange
(
winCh
<-
chan
ssh
.
Window
,
done
<-
chan
struct
{})
{
func
(
h
*
InteractiveHandler
)
watchWinSizeChange
(
winCh
<-
chan
ssh
.
Window
,
done
<-
chan
struct
{})
{
for
{
for
{
select
{
select
{
case
<-
done
:
case
<-
done
:
...
@@ -82,19 +82,19 @@ func (i *InteractiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <-
...
@@ -82,19 +82,19 @@ func (i *InteractiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <-
return
return
}
}
logger
.
Debugf
(
"Term change: %d*%d"
,
win
.
Height
,
win
.
Width
)
logger
.
Debugf
(
"Term change: %d*%d"
,
win
.
Height
,
win
.
Width
)
_
=
i
.
term
.
SetSize
(
win
.
Width
,
win
.
Height
)
_
=
h
.
term
.
SetSize
(
win
.
Width
,
win
.
Height
)
}
}
}
}
}
}
func
(
i
*
InteractiveHandler
)
Dispatch
(
ctx
cctx
.
Context
)
{
func
(
h
*
InteractiveHandler
)
Dispatch
(
ctx
cctx
.
Context
)
{
i
.
preDispatch
()
h
.
preDispatch
()
fmt
.
Println
(
i
.
user
)
fmt
.
Println
(
h
.
user
)
_
,
winCh
,
_
:=
i
.
sess
.
Pty
()
_
,
winCh
,
_
:=
h
.
sess
.
Pty
()
for
{
for
{
doneChan
:=
make
(
chan
struct
{})
doneChan
:=
make
(
chan
struct
{})
go
i
.
watchWinSizeChange
(
winCh
,
doneChan
)
go
h
.
watchWinSizeChange
(
winCh
,
doneChan
)
line
,
err
:=
i
.
term
.
ReadLine
()
line
,
err
:=
h
.
term
.
ReadLine
()
close
(
doneChan
)
close
(
doneChan
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -110,37 +110,37 @@ func (i *InteractiveHandler) Dispatch(ctx cctx.Context) {
...
@@ -110,37 +110,37 @@ func (i *InteractiveHandler) Dispatch(ctx cctx.Context) {
case
0
,
1
:
case
0
,
1
:
switch
strings
.
ToLower
(
line
)
{
switch
strings
.
ToLower
(
line
)
{
case
""
,
"p"
:
case
""
,
"p"
:
i
.
Proxy
(
ctx
)
h
.
Proxy
(
ctx
)
case
"g"
:
case
"g"
:
i
.
displayNodes
(
i
.
nodes
)
h
.
displayNodes
(
h
.
nodes
)
case
"s"
:
case
"s"
:
i
.
changeLanguage
()
h
.
changeLanguage
()
case
"h"
:
case
"h"
:
i
.
displayBanner
()
h
.
displayBanner
()
case
"r"
:
case
"r"
:
i
.
refreshAssetsAndNodesData
()
h
.
refreshAssetsAndNodesData
()
case
"q"
:
case
"q"
:
logger
.
Info
(
"exit session"
)
logger
.
Info
(
"exit session"
)
return
return
default
:
default
:
assets
:=
i
.
searchAsset
(
line
)
assets
:=
h
.
searchAsset
(
line
)
i
.
searchResult
=
assets
h
.
searchResult
=
assets
i
.
displayAssetsOrProxy
(
assets
)
h
.
displayAssetsOrProxy
(
assets
)
}
}
default
:
default
:
switch
{
switch
{
case
strings
.
Index
(
line
,
"/"
)
==
0
:
case
strings
.
Index
(
line
,
"/"
)
==
0
:
searchWord
:=
strings
.
TrimSpace
(
line
[
1
:
])
searchWord
:=
strings
.
TrimSpace
(
line
[
1
:
])
assets
:=
i
.
searchAsset
(
searchWord
)
assets
:=
h
.
searchAsset
(
searchWord
)
i
.
searchResult
=
assets
h
.
searchResult
=
assets
i
.
displayAssets
(
assets
)
h
.
displayAssets
(
assets
)
case
strings
.
Index
(
line
,
"g"
)
==
0
:
case
strings
.
Index
(
line
,
"g"
)
==
0
:
searchWord
:=
strings
.
TrimSpace
(
strings
.
TrimPrefix
(
line
,
"g"
))
searchWord
:=
strings
.
TrimSpace
(
strings
.
TrimPrefix
(
line
,
"g"
))
if
num
,
err
:=
strconv
.
Atoi
(
searchWord
);
err
==
nil
{
if
num
,
err
:=
strconv
.
Atoi
(
searchWord
);
err
==
nil
{
if
num
>=
0
{
if
num
>=
0
{
assets
:=
i
.
searchNodeAssets
(
num
)
assets
:=
h
.
searchNodeAssets
(
num
)
i
.
displayAssets
(
assets
)
h
.
displayAssets
(
assets
)
i
.
searchResult
=
assets
h
.
searchResult
=
assets
continue
continue
}
}
}
}
...
@@ -149,15 +149,15 @@ func (i *InteractiveHandler) Dispatch(ctx cctx.Context) {
...
@@ -149,15 +149,15 @@ func (i *InteractiveHandler) Dispatch(ctx cctx.Context) {
}
}
}
}
func
(
i
*
InteractiveHandler
)
chooseSystemUser
(
systemUsers
[]
model
.
SystemUser
)
model
.
SystemUser
{
func
(
h
*
InteractiveHandler
)
chooseSystemUser
(
systemUsers
[]
model
.
SystemUser
)
model
.
SystemUser
{
table
:=
tablewriter
.
NewWriter
(
i
.
sess
)
table
:=
tablewriter
.
NewWriter
(
h
.
sess
)
table
.
SetHeader
([]
string
{
"ID"
,
"UserName"
})
table
.
SetHeader
([]
string
{
"ID"
,
"UserName"
})
for
i
:=
0
;
i
<
len
(
systemUsers
);
i
++
{
for
i
:=
0
;
i
<
len
(
systemUsers
);
i
++
{
table
.
Append
([]
string
{
strconv
.
Itoa
(
i
+
1
),
systemUsers
[
i
]
.
UserName
})
table
.
Append
([]
string
{
strconv
.
Itoa
(
i
+
1
),
systemUsers
[
i
]
.
UserName
})
}
}
table
.
SetBorder
(
false
)
table
.
SetBorder
(
false
)
count
:=
0
count
:=
0
term
:=
terminal
.
NewTerminal
(
i
.
sess
,
"num:"
)
term
:=
terminal
.
NewTerminal
(
h
.
sess
,
"num:"
)
for
count
<
3
{
for
count
<
3
{
table
.
Render
()
table
.
Render
()
line
,
err
:=
term
.
ReadLine
()
line
,
err
:=
term
.
ReadLine
()
...
@@ -175,44 +175,44 @@ func (i *InteractiveHandler) chooseSystemUser(systemUsers []model.SystemUser) mo
...
@@ -175,44 +175,44 @@ func (i *InteractiveHandler) chooseSystemUser(systemUsers []model.SystemUser) mo
}
}
// 当资产的数量为1的时候,就进行代理转化
// 当资产的数量为1的时候,就进行代理转化
func
(
i
*
InteractiveHandler
)
displayAssetsOrProxy
(
assets
[]
model
.
Asset
)
{
func
(
h
*
InteractiveHandler
)
displayAssetsOrProxy
(
assets
[]
model
.
Asset
)
{
//if len(assets) == 1 {
//if len(assets) == 1 {
// var systemUser model.SystemUser
// var systemUser model.SystemUser
// switch len(assets[0].SystemUsers) {
// switch len(assets[0].SystemUsers) {
// case 0:
// case 0:
// // 有授权的资产,但是资产用户信息,无法登陆
// // 有授权的资产,但是资产用户信息,无法登陆
//
i
.displayAssets(assets)
//
h
.displayAssets(assets)
// return
// return
// case 1:
// case 1:
// systemUser = assets[0].SystemUsers[0]
// systemUser = assets[0].SystemUsers[0]
// default:
// default:
// systemUser =
i
.chooseSystemUser(assets[0].SystemUsers)
// systemUser =
h
.chooseSystemUser(assets[0].SystemUsers)
// }
// }
//
//
// authInfo, err := model.GetSystemUserAssetAuthInfo(systemUser.I
d, assets[0].Id
)
// authInfo, err := model.GetSystemUserAssetAuthInfo(systemUser.I
D, assets[0].ID
)
// if err != nil {
// if err != nil {
// return
// return
// }
// }
// if ok := service.ValidateUserAssetPermission(
i.user.Id, systemUser.Id, assets[0].Id
); !ok {
// if ok := service.ValidateUserAssetPermission(
h.user.ID, systemUser.ID, assets[0].ID
); !ok {
// // 检查user 是否对该资产有权限
// // 检查user 是否对该资产有权限
// return
// return
// }
// }
//
//
// err =
i
.Proxy(assets[0], authInfo)
// err =
h
.Proxy(assets[0], authInfo)
// if err != nil {
// if err != nil {
// logger.Info(err)
// logger.Info(err)
// }
// }
// return
// return
//} else {
//} else {
//
i
.displayAssets(assets)
//
h
.displayAssets(assets)
//}
//}
}
}
func
(
i
*
InteractiveHandler
)
displayAssets
(
assets
model
.
AssetList
)
{
func
(
h
*
InteractiveHandler
)
displayAssets
(
assets
model
.
AssetList
)
{
if
len
(
assets
)
==
0
{
if
len
(
assets
)
==
0
{
_
,
_
=
io
.
WriteString
(
i
.
sess
,
"
\r\n
No Assets
\r\n\r
"
)
_
,
_
=
io
.
WriteString
(
h
.
sess
,
"
\r\n
No Assets
\r\n\r
"
)
}
else
{
}
else
{
table
:=
tablewriter
.
NewWriter
(
i
.
sess
)
table
:=
tablewriter
.
NewWriter
(
h
.
sess
)
table
.
SetHeader
([]
string
{
"ID"
,
"Hostname"
,
"IP"
,
"LoginAs"
,
"Comment"
})
table
.
SetHeader
([]
string
{
"ID"
,
"Hostname"
,
"IP"
,
"LoginAs"
,
"Comment"
})
for
index
,
assetItem
:=
range
assets
{
for
index
,
assetItem
:=
range
assets
{
sysUserArray
:=
make
([]
string
,
len
(
assetItem
.
SystemUsers
))
sysUserArray
:=
make
([]
string
,
len
(
assetItem
.
SystemUsers
))
...
@@ -229,44 +229,44 @@ func (i *InteractiveHandler) displayAssets(assets model.AssetList) {
...
@@ -229,44 +229,44 @@ func (i *InteractiveHandler) displayAssets(assets model.AssetList) {
}
}
func
(
i
*
InteractiveHandler
)
displayNodes
(
nodes
[]
model
.
Node
)
{
func
(
h
*
InteractiveHandler
)
displayNodes
(
nodes
[]
model
.
Node
)
{
tree
:=
ConstructAssetNodeTree
(
nodes
)
tree
:=
ConstructAssetNodeTree
(
nodes
)
tipHeaderMsg
:=
"
\r\n
Node: [ ID.Name(Asset amount) ]"
tipHeaderMsg
:=
"
\r\n
Node: [ ID.Name(Asset amount) ]"
tipEndMsg
:=
"Tips: Enter g+NodeID to display the host under the node, such as g1
\r\n\r
"
tipEndMsg
:=
"Tips: Enter g+NodeID to display the host under the node, such as g1
\r\n\r
"
_
,
err
:=
io
.
WriteString
(
i
.
sess
,
tipHeaderMsg
)
_
,
err
:=
io
.
WriteString
(
h
.
sess
,
tipHeaderMsg
)
_
,
err
=
io
.
WriteString
(
i
.
sess
,
tree
.
String
())
_
,
err
=
io
.
WriteString
(
h
.
sess
,
tree
.
String
())
_
,
err
=
io
.
WriteString
(
i
.
sess
,
tipEndMsg
)
_
,
err
=
io
.
WriteString
(
h
.
sess
,
tipEndMsg
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Info
(
"displayAssetNodes err:"
,
err
)
logger
.
Info
(
"displayAssetNodes err:"
,
err
)
}
}
}
}
func
(
i
*
InteractiveHandler
)
refreshAssetsAndNodesData
()
{
func
(
h
*
InteractiveHandler
)
refreshAssetsAndNodesData
()
{
_
,
err
:=
io
.
WriteString
(
i
.
sess
,
"Refresh done
\r\n
"
)
_
,
err
:=
io
.
WriteString
(
h
.
sess
,
"Refresh done
\r\n
"
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
"refresh Assets Nodes err:"
,
err
)
logger
.
Error
(
"refresh Assets Nodes err:"
,
err
)
}
}
}
}
func
(
i
*
InteractiveHandler
)
loadUserAssets
()
{
func
(
h
*
InteractiveHandler
)
loadUserAssets
()
{
i
.
assets
=
service
.
GetUserAssets
(
i
.
user
.
Id
,
"1"
)
h
.
assets
=
service
.
GetUserAssets
(
h
.
user
.
ID
,
"1"
)
}
}
func
(
i
*
InteractiveHandler
)
loadUserAssetNodes
()
{
func
(
h
*
InteractiveHandler
)
loadUserAssetNodes
()
{
i
.
nodes
=
service
.
GetUserNodes
(
i
.
user
.
Id
,
"1"
)
h
.
nodes
=
service
.
GetUserNodes
(
h
.
user
.
ID
,
"1"
)
}
}
func
(
i
*
InteractiveHandler
)
changeLanguage
()
{
func
(
h
*
InteractiveHandler
)
changeLanguage
()
{
}
}
func
(
i
*
InteractiveHandler
)
JoinShareRoom
(
roomID
string
)
{
func
(
h
*
InteractiveHandler
)
JoinShareRoom
(
roomID
string
)
{
//sshConn := userhome.NewSSHConn(
i
.sess)
//sshConn := userhome.NewSSHConn(
h
.sess)
//ctx, cancelFuc := context.WithCancel(
i
.sess.Context())
//ctx, cancelFuc := context.WithCancel(
h
.sess.Context())
//
//
//_, winCh, _ :=
i
.sess.Pty()
//_, winCh, _ :=
h
.sess.Pty()
//go func() {
//go func() {
// for {
// for {
// select {
// select {
...
@@ -286,21 +286,21 @@ func (i *InteractiveHandler) JoinShareRoom(roomID string) {
...
@@ -286,21 +286,21 @@ func (i *InteractiveHandler) JoinShareRoom(roomID string) {
}
}
func
(
i
*
InteractiveHandler
)
searchAsset
(
key
string
)
(
assets
[]
model
.
Asset
)
{
func
(
h
*
InteractiveHandler
)
searchAsset
(
key
string
)
(
assets
[]
model
.
Asset
)
{
//if indexNum, err := strconv.Atoi(key); err == nil {
//if indexNum, err := strconv.Atoi(key); err == nil {
// if indexNum > 0 && indexNum <= len(
i
.searchResult) {
// if indexNum > 0 && indexNum <= len(
h
.searchResult) {
// return []model.Asset{
i
.searchResult[indexNum-1]}
// return []model.Asset{
h
.searchResult[indexNum-1]}
// }
// }
//}
//}
//
//
//if assetsData, ok :=
i
.assetData.Load(AssetsMapKey); ok {
//if assetsData, ok :=
h
.assetData.Load(AssetsMapKey); ok {
// for _, assetValue := range assetsData.([]model.Asset) {
// for _, assetValue := range assetsData.([]model.Asset) {
// if isSubstring([]string{assetValue.Ip, assetValue.Hostname, assetValue.Comment}, key) {
// if isSubstring([]string{assetValue.Ip, assetValue.Hostname, assetValue.Comment}, key) {
// assets = append(assets, assetValue)
// assets = append(assets, assetValue)
// }
// }
// }
// }
//} else {
//} else {
// assetsData, _ := Cached.Load(
i.user.Id
)
// assetsData, _ := Cached.Load(
h.user.ID
)
// for _, assetValue := range assetsData.([]model.Asset) {
// for _, assetValue := range assetsData.([]model.Asset) {
// if isSubstring([]string{assetValue.Ip, assetValue.Hostname, assetValue.Comment}, key) {
// if isSubstring([]string{assetValue.Ip, assetValue.Hostname, assetValue.Comment}, key) {
// assets = append(assets, assetValue)
// assets = append(assets, assetValue)
...
@@ -311,9 +311,9 @@ func (i *InteractiveHandler) searchAsset(key string) (assets []model.Asset) {
...
@@ -311,9 +311,9 @@ func (i *InteractiveHandler) searchAsset(key string) (assets []model.Asset) {
return
assets
return
assets
}
}
func
(
i
*
InteractiveHandler
)
searchNodeAssets
(
num
int
)
(
assets
[]
model
.
Asset
)
{
func
(
h
*
InteractiveHandler
)
searchNodeAssets
(
num
int
)
(
assets
[]
model
.
Asset
)
{
//var assetNodesData []model.Node
//var assetNodesData []model.Node
//if assetNodes, ok :=
i
.assetData.Load(AssetNodesMapKey); ok {
//if assetNodes, ok :=
h
.assetData.Load(AssetNodesMapKey); ok {
// assetNodesData = assetNodes.([]model.Node)
// assetNodesData = assetNodes.([]model.Node)
// if num > len(assetNodesData) || num == 0 {
// if num > len(assetNodesData) || num == 0 {
// return assets
// return assets
...
@@ -324,14 +324,14 @@ func (i *InteractiveHandler) searchNodeAssets(num int) (assets []model.Asset) {
...
@@ -324,14 +324,14 @@ func (i *InteractiveHandler) searchNodeAssets(num int) (assets []model.Asset) {
}
}
func
(
i
*
InteractiveHandler
)
Proxy
(
ctx
context
.
Context
)
{
func
(
h
*
InteractiveHandler
)
Proxy
(
ctx
context
.
Context
)
{
i
.
assetSelect
=
&
model
.
Asset
{
Hostname
:
"centos"
,
Port
:
32768
,
Ip
:
"127.0.0.1"
}
h
.
assetSelect
=
&
model
.
Asset
{
Hostname
:
"centos"
,
Port
:
32768
,
Ip
:
"127.0.0.1"
}
i
.
systemUserSelect
=
&
model
.
SystemUser
{
Name
:
"web"
,
UserName
:
"root"
,
Password
:
"screencast"
}
h
.
systemUserSelect
=
&
model
.
SystemUser
{
Name
:
"web"
,
UserName
:
"root"
,
Password
:
"screencast"
}
p
:=
proxy
.
ProxyServer
{
p
:=
proxy
.
ProxyServer
{
Session
:
i
.
sess
,
Session
:
h
.
sess
,
User
:
i
.
user
,
User
:
h
.
user
,
Asset
:
i
.
assetSelect
,
Asset
:
h
.
assetSelect
,
SystemUser
:
i
.
systemUserSelect
,
SystemUser
:
h
.
systemUserSelect
,
}
}
p
.
Proxy
()
p
.
Proxy
()
}
}
...
...
pkg/model/terminal.go
View file @
8b06c4a1
...
@@ -7,7 +7,7 @@ type Terminal struct {
...
@@ -7,7 +7,7 @@ type Terminal struct {
Id
string
`json:"id"`
Id
string
`json:"id"`
Name
string
`json:"name"`
Name
string
`json:"name"`
AccessKey
struct
{
AccessKey
struct
{
I
d
string
`json:"id"`
I
D
string
`json:"id"`
Secret
string
`json:"secret"`
Secret
string
`json:"secret"`
}
`json:"access_key"`
}
`json:"access_key"`
}
`json:"service_account"`
}
`json:"service_account"`
...
...
pkg/model/users.go
View file @
8b06c4a1
...
@@ -25,15 +25,14 @@ type AuthResponse struct {
...
@@ -25,15 +25,14 @@ type AuthResponse struct {
}
}
type
User
struct
{
type
User
struct
{
I
d
string
`json:"id"`
I
D
string
`json:"id"`
Name
string
`json:"name"`
Name
string
`json:"name"`
Username
string
`json:"username"`
Username
string
`json:"username"`
Email
string
`json:"email"`
Email
string
`json:"email"`
OTPLevel
int
`json:"otp_level"`
Role
string
`json:"role"`
Role
string
`json:"role"`
IsValid
bool
`json:"is_valid"`
IsValid
bool
`json:"is_valid"`
IsActive
bool
`json:"is_active"`
IsActive
bool
`json:"is_active"`
IsMFA
int
`json:"otp_level"`
OTPLevel
int
`json:"otp_level"`
}
}
type
TokenUser
struct
{
type
TokenUser
struct
{
...
...
pkg/service/accesskey.go
View file @
8b06c4a1
...
@@ -20,7 +20,7 @@ var (
...
@@ -20,7 +20,7 @@ var (
)
)
type
AccessKey
struct
{
type
AccessKey
struct
{
I
d
string
I
D
string
Secret
string
Secret
string
Path
string
Path
string
Value
string
Value
string
...
@@ -29,7 +29,7 @@ type AccessKey struct {
...
@@ -29,7 +29,7 @@ type AccessKey struct {
func
(
ak
AccessKey
)
Sign
()
(
string
,
string
)
{
func
(
ak
AccessKey
)
Sign
()
(
string
,
string
)
{
date
:=
common
.
HTTPGMTDate
()
date
:=
common
.
HTTPGMTDate
()
signature
:=
common
.
MakeSignature
(
ak
.
Secret
,
date
)
signature
:=
common
.
MakeSignature
(
ak
.
Secret
,
date
)
return
date
,
fmt
.
Sprintf
(
"Sign %s:%s"
,
ak
.
I
d
,
signature
)
return
date
,
fmt
.
Sprintf
(
"Sign %s:%s"
,
ak
.
I
D
,
signature
)
}
}
func
(
ak
*
AccessKey
)
LoadAccessKeyFromStr
(
key
string
)
error
{
func
(
ak
*
AccessKey
)
LoadAccessKeyFromStr
(
key
string
)
error
{
...
@@ -40,7 +40,7 @@ func (ak *AccessKey) LoadAccessKeyFromStr(key string) error {
...
@@ -40,7 +40,7 @@ func (ak *AccessKey) LoadAccessKeyFromStr(key string) error {
if
len
(
keySlice
)
!=
2
{
if
len
(
keySlice
)
!=
2
{
return
AccessKeyInvalid
return
AccessKeyInvalid
}
}
ak
.
I
d
=
keySlice
[
0
]
ak
.
I
D
=
keySlice
[
0
]
ak
.
Secret
=
keySlice
[
1
]
ak
.
Secret
=
keySlice
[
1
]
return
nil
return
nil
}
}
...
@@ -74,7 +74,7 @@ func (ak *AccessKey) SaveToFile() error {
...
@@ -74,7 +74,7 @@ func (ak *AccessKey) SaveToFile() error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
_
,
err
=
f
.
WriteString
(
fmt
.
Sprintf
(
"%s:%s"
,
ak
.
I
d
,
ak
.
Secret
))
_
,
err
=
f
.
WriteString
(
fmt
.
Sprintf
(
"%s:%s"
,
ak
.
I
D
,
ak
.
Secret
))
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
err
)
logger
.
Error
(
err
)
}
}
...
@@ -92,7 +92,7 @@ func (ak *AccessKey) Register(times int) error {
...
@@ -92,7 +92,7 @@ func (ak *AccessKey) Register(times int) error {
logger
.
Error
(
msg
)
logger
.
Error
(
msg
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
ak
.
I
d
=
res
.
ServiceAccount
.
AccessKey
.
Id
ak
.
I
D
=
res
.
ServiceAccount
.
AccessKey
.
ID
ak
.
Secret
=
res
.
ServiceAccount
.
AccessKey
.
Secret
ak
.
Secret
=
res
.
ServiceAccount
.
AccessKey
.
Secret
return
nil
return
nil
}
}
...
...
pkg/service/perms.go
View file @
8b06c4a1
...
@@ -7,12 +7,12 @@ import (
...
@@ -7,12 +7,12 @@ import (
"cocogo/pkg/model"
"cocogo/pkg/model"
)
)
func
GetUserAssets
(
userI
d
,
cachePolicy
string
)
(
assets
model
.
AssetList
)
{
func
GetUserAssets
(
userI
D
,
cachePolicy
string
)
(
assets
model
.
AssetList
)
{
if
cachePolicy
==
""
{
if
cachePolicy
==
""
{
cachePolicy
=
"0"
cachePolicy
=
"0"
}
}
payload
:=
map
[
string
]
string
{
"cache_policy"
:
cachePolicy
}
payload
:=
map
[
string
]
string
{
"cache_policy"
:
cachePolicy
}
Url
:=
fmt
.
Sprintf
(
UserAssetsURL
,
userI
d
)
Url
:=
fmt
.
Sprintf
(
UserAssetsURL
,
userI
D
)
err
:=
authClient
.
Get
(
Url
,
&
assets
,
payload
)
err
:=
authClient
.
Get
(
Url
,
&
assets
,
payload
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
"GetUserAssets---err"
)
logger
.
Error
(
"GetUserAssets---err"
)
...
...
pkg/service/users.go
View file @
8b06c4a1
...
@@ -23,8 +23,7 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
...
@@ -23,8 +23,7 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
"remote_addr"
:
remoteAddr
,
"remote_addr"
:
remoteAddr
,
"login_type"
:
loginType
,
"login_type"
:
loginType
,
}
}
Url
:=
client
.
ParseUrl
(
UserAuthURL
,
nil
)
err
=
client
.
Post
(
UserAuthURL
,
data
,
&
resp
)
err
=
client
.
Post
(
Url
,
data
,
&
resp
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
err
)
logger
.
Error
(
err
)
...
@@ -32,33 +31,8 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
...
@@ -32,33 +31,8 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
return
return
}
}
func
AuthenticateMFA
(
seed
,
code
,
loginType
string
)
(
resp
*
model
.
AuthResponse
,
err
error
)
{
func
GetUserProfile
(
userID
string
)
(
user
*
model
.
User
)
{
/*
Url
:=
fmt
.
Sprintf
(
UserDetailURL
,
userID
)
data = {
'seed': seed,
'otp_code': otp_code,
'login_type': login_type,
}
*/
data
:=
map
[
string
]
string
{
"seed"
:
seed
,
"otp_code"
:
code
,
"login_type"
:
loginType
,
}
Url
:=
client
.
ParseUrl
(
AuthMFAURL
,
nil
)
err
=
client
.
Post
(
Url
,
data
,
resp
)
if
err
!=
nil
{
logger
.
Error
(
err
)
}
return
}
func
GetUserProfile
(
userId
string
)
(
user
*
model
.
User
)
{
Url
:=
fmt
.
Sprintf
(
UserDetailURL
,
userId
)
err
:=
authClient
.
Get
(
Url
,
user
)
err
:=
authClient
.
Get
(
Url
,
user
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
err
)
logger
.
Error
(
err
)
...
@@ -98,9 +72,9 @@ func CheckUserOTP(seed, code string) (resp *AuthResp, err error) {
...
@@ -98,9 +72,9 @@ func CheckUserOTP(seed, code string) (resp *AuthResp, err error) {
return
return
}
}
func
CheckUserCookie
(
sessionI
d
,
csrfToken
string
)
(
user
*
model
.
User
)
{
func
CheckUserCookie
(
sessionI
D
,
csrfToken
string
)
(
user
*
model
.
User
)
{
client
.
SetCookie
(
"csrftoken"
,
csrfToken
)
client
.
SetCookie
(
"csrftoken"
,
csrfToken
)
client
.
SetCookie
(
"sessionid"
,
sessionI
d
)
client
.
SetCookie
(
"sessionid"
,
sessionI
D
)
err
:=
client
.
Get
(
UserProfileURL
,
&
user
)
err
:=
client
.
Get
(
UserProfileURL
,
&
user
)
if
err
!=
nil
{
if
err
!=
nil
{
logger
.
Error
(
err
)
logger
.
Error
(
err
)
...
...
pkg/webssh/handler.go
View file @
8b06c4a1
...
@@ -28,7 +28,7 @@ func AuthDecorator(handler http.HandlerFunc) http.HandlerFunc {
...
@@ -28,7 +28,7 @@ func AuthDecorator(handler http.HandlerFunc) http.HandlerFunc {
}
}
}
}
user
:=
service
.
CheckUserCookie
(
sessionid
,
csrfToken
)
user
:=
service
.
CheckUserCookie
(
sessionid
,
csrfToken
)
if
user
.
I
d
==
""
{
if
user
.
I
D
==
""
{
// Todo: 构建login的url
// Todo: 构建login的url
http
.
Redirect
(
responseWriter
,
request
,
""
,
http
.
StatusFound
)
http
.
Redirect
(
responseWriter
,
request
,
""
,
http
.
StatusFound
)
return
return
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment