Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
accountserver
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Monitor
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ai3
accountserver
Commits
cc4053f8
Commit
cc4053f8
authored
6 years ago
by
ale
Browse files
Options
Downloads
Patches
Plain Diff
Implement basic audit logging and resource creation
parent
8bf80917
No related branches found
No related tags found
1 merge request
!1
Txn
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
actions.go
+78
-17
78 additions, 17 deletions
actions.go
actions_test.go
+27
-3
27 additions, 3 deletions
actions_test.go
audit.go
+39
-0
39 additions, 0 deletions
audit.go
config.go
+19
-6
19 additions, 6 deletions
config.go
service.go
+32
-6
32 additions, 6 deletions
service.go
with
195 additions
and
32 deletions
actions.go
+
78
−
17
View file @
cc4053f8
...
@@ -5,6 +5,8 @@ import (
...
@@ -5,6 +5,8 @@ import (
"crypto/rand"
"crypto/rand"
"encoding/base64"
"encoding/base64"
"errors"
"errors"
"fmt"
"log"
"git.autistici.org/ai3/go-common/pwhash"
"git.autistici.org/ai3/go-common/pwhash"
"github.com/pquerna/otp/totp"
"github.com/pquerna/otp/totp"
...
@@ -97,7 +99,7 @@ func (s *AccountService) setResourceStatus(ctx context.Context, tx TX, r *Resour
...
@@ -97,7 +99,7 @@ func (s *AccountService) setResourceStatus(ctx context.Context, tx TX, r *Resour
if
err
:=
tx
.
UpdateResource
(
ctx
,
r
);
err
!=
nil
{
if
err
:=
tx
.
UpdateResource
(
ctx
,
r
);
err
!=
nil
{
return
newBackendError
(
err
)
return
newBackendError
(
err
)
}
}
//
s.audit.Log(
r.ID.User(), authUser
, r.ID, fmt.Sprintf("status
changed
to %s", status)
, comment
)
s
.
audit
.
Log
(
ctx
,
r
.
ID
,
fmt
.
Sprintf
(
"status
set
to %s"
,
status
))
return
nil
return
nil
}
}
...
@@ -210,9 +212,10 @@ func (s *AccountService) ResetPassword(ctx context.Context, tx TX, req *ResetPas
...
@@ -210,9 +212,10 @@ func (s *AccountService) ResetPassword(ctx context.Context, tx TX, req *ResetPas
return
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
return
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
// Disable 2FA.
// Disable 2FA.
if
err
:=
tx
.
DeleteUserTOTPSecret
(
c
tx
,
user
);
err
!=
nil
{
if
err
:=
s
.
disable2FA
(
ctx
,
tx
,
user
);
err
!=
nil
{
return
err
return
err
}
}
// Reset encryption keys and set the new password.
// Reset encryption keys and set the new password.
return
s
.
changeUserPasswordAndResetEncryptionKeys
(
ctx
,
tx
,
user
,
req
.
Password
)
return
s
.
changeUserPasswordAndResetEncryptionKeys
(
ctx
,
tx
,
user
,
req
.
Password
)
})
})
...
@@ -286,6 +289,9 @@ func (s *AccountService) changeUserPasswordAndUpdateEncryptionKeys(ctx context.C
...
@@ -286,6 +289,9 @@ func (s *AccountService) changeUserPasswordAndUpdateEncryptionKeys(ctx context.C
if
err
:=
tx
.
SetUserPassword
(
ctx
,
user
,
encPass
);
err
!=
nil
{
if
err
:=
tx
.
SetUserPassword
(
ctx
,
user
,
encPass
);
err
!=
nil
{
return
newBackendError
(
err
)
return
newBackendError
(
err
)
}
}
s
.
audit
.
Log
(
ctx
,
ResourceID
{},
"password changed"
)
return
nil
return
nil
}
}
...
@@ -303,23 +309,28 @@ func (s *AccountService) changeUserPasswordAndResetEncryptionKeys(ctx context.Co
...
@@ -303,23 +309,28 @@ func (s *AccountService) changeUserPasswordAndResetEncryptionKeys(ctx context.Co
return
newBackendError
(
err
)
return
newBackendError
(
err
)
}
}
// Wipe all 2FA credentials that had corresponding encryption keys as well.
if
err
:=
s
.
wipeApplicationSpecificPasswords
(
ctx
,
tx
,
user
);
err
!=
nil
{
return
err
}
// Set the encrypted password attribute on the user (will set it on emails too).
// Set the encrypted password attribute on the user (will set it on emails too).
encPass
:=
pwhash
.
Encrypt
(
newPassword
)
encPass
:=
pwhash
.
Encrypt
(
newPassword
)
if
err
:=
tx
.
SetUserPassword
(
ctx
,
user
,
encPass
);
err
!=
nil
{
if
err
:=
tx
.
SetUserPassword
(
ctx
,
user
,
encPass
);
err
!=
nil
{
return
newBackendError
(
err
)
return
newBackendError
(
err
)
}
}
s
.
audit
.
Log
(
ctx
,
ResourceID
{},
"password reset"
)
return
nil
return
nil
}
}
func
(
s
*
AccountService
)
wipeApplicationSpecificPasswords
(
ctx
context
.
Context
,
tx
TX
,
user
*
User
)
error
{
// Disable 2FA for a user account.
func
(
s
*
AccountService
)
disable2FA
(
ctx
context
.
Context
,
tx
TX
,
user
*
User
)
error
{
// Disable OTP.
if
err
:=
tx
.
DeleteUserTOTPSecret
(
ctx
,
user
);
err
!=
nil
{
return
newBackendError
(
err
)
}
// Wipe all app-specific passwords.
for
_
,
asp
:=
range
user
.
AppSpecificPasswords
{
for
_
,
asp
:=
range
user
.
AppSpecificPasswords
{
if
err
:=
tx
.
DeleteApplicationSpecificPassword
(
ctx
,
user
,
asp
.
ID
);
err
!=
nil
{
if
err
:=
tx
.
DeleteApplicationSpecificPassword
(
ctx
,
user
,
asp
.
ID
);
err
!=
nil
{
return
err
return
newBackendError
(
err
)
}
}
}
}
return
nil
return
nil
...
@@ -569,6 +580,9 @@ type AddEmailAliasRequest struct {
...
@@ -569,6 +580,9 @@ type AddEmailAliasRequest struct {
// Validate the request.
// Validate the request.
func
(
r
*
AddEmailAliasRequest
)
Validate
(
ctx
context
.
Context
,
s
*
AccountService
)
error
{
func
(
r
*
AddEmailAliasRequest
)
Validate
(
ctx
context
.
Context
,
s
*
AccountService
)
error
{
if
r
.
ResourceID
.
Type
()
!=
ResourceTypeEmail
{
return
errors
.
New
(
"this operation only works on email resources"
)
}
return
s
.
emailValidator
(
ctx
,
r
.
Addr
)
return
s
.
emailValidator
(
ctx
,
r
.
Addr
)
}
}
...
@@ -580,9 +594,6 @@ func (s *AccountService) AddEmailAlias(ctx context.Context, tx TX, req *AddEmail
...
@@ -580,9 +594,6 @@ func (s *AccountService) AddEmailAlias(ctx context.Context, tx TX, req *AddEmail
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
r
.
ID
.
Type
()
!=
ResourceTypeEmail
{
return
errors
.
New
(
"this operation only works on email resources"
)
}
return
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
return
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
// Allow at most 5 aliases.
// Allow at most 5 aliases.
...
@@ -591,7 +602,12 @@ func (s *AccountService) AddEmailAlias(ctx context.Context, tx TX, req *AddEmail
...
@@ -591,7 +602,12 @@ func (s *AccountService) AddEmailAlias(ctx context.Context, tx TX, req *AddEmail
}
}
r
.
Email
.
Aliases
=
append
(
r
.
Email
.
Aliases
,
req
.
Addr
)
r
.
Email
.
Aliases
=
append
(
r
.
Email
.
Aliases
,
req
.
Addr
)
return
tx
.
UpdateResource
(
ctx
,
r
)
if
err
:=
tx
.
UpdateResource
(
ctx
,
r
);
err
!=
nil
{
return
err
}
s
.
audit
.
Log
(
ctx
,
r
.
ID
,
fmt
.
Sprintf
(
"added alias %s"
,
req
.
Addr
))
return
nil
})
})
}
}
...
@@ -601,15 +617,20 @@ type DeleteEmailAliasRequest struct {
...
@@ -601,15 +617,20 @@ type DeleteEmailAliasRequest struct {
Addr
string
`json:"addr"`
Addr
string
`json:"addr"`
}
}
// Validate the request.
func
(
r
*
DeleteEmailAliasRequest
)
Validate
(
ctx
context
.
Context
,
s
*
AccountService
)
error
{
if
r
.
ResourceID
.
Type
()
!=
ResourceTypeEmail
{
return
errors
.
New
(
"this operation only works on email resources"
)
}
return
nil
}
// DeleteEmailAlias removes an alias from an email resource.
// DeleteEmailAlias removes an alias from an email resource.
func
(
s
*
AccountService
)
DeleteEmailAlias
(
ctx
context
.
Context
,
tx
TX
,
req
*
DeleteEmailAliasRequest
)
error
{
func
(
s
*
AccountService
)
DeleteEmailAlias
(
ctx
context
.
Context
,
tx
TX
,
req
*
DeleteEmailAliasRequest
)
error
{
ctx
,
r
,
err
:=
s
.
authorizeResource
(
ctx
,
tx
,
req
.
ResourceRequestBase
)
ctx
,
r
,
err
:=
s
.
authorizeResource
(
ctx
,
tx
,
req
.
ResourceRequestBase
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
r
.
ID
.
Type
()
!=
ResourceTypeEmail
{
return
errors
.
New
(
"this operation only works on email resources"
)
}
return
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
return
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
var
aliases
[]
string
var
aliases
[]
string
...
@@ -619,10 +640,50 @@ func (s *AccountService) DeleteEmailAlias(ctx context.Context, tx TX, req *Delet
...
@@ -619,10 +640,50 @@ func (s *AccountService) DeleteEmailAlias(ctx context.Context, tx TX, req *Delet
}
}
}
}
r
.
Email
.
Aliases
=
aliases
r
.
Email
.
Aliases
=
aliases
return
tx
.
UpdateResource
(
ctx
,
r
)
if
err
:=
tx
.
UpdateResource
(
ctx
,
r
);
err
!=
nil
{
return
err
}
s
.
audit
.
Log
(
ctx
,
r
.
ID
,
fmt
.
Sprintf
(
"removed alias %s"
,
req
.
Addr
))
return
nil
})
})
}
}
// CreateResourcesRequest is the request type for AccountService.CreateResources().
type
CreateResourcesRequest
struct
{
SSO
string
`json:"sso"`
Resources
[]
*
Resource
`json:"resources"`
}
// CreateResourcesResponse is the response type for AccountService.CreateResources().
type
CreateResourcesResponse
struct
{
IDs
[]
ResourceID
`json:"ids"`
}
// CreateResources can create one or more resources.
func
(
s
*
AccountService
)
CreateResources
(
ctx
context
.
Context
,
tx
TX
,
req
*
CreateResourcesRequest
)
(
*
CreateResourcesResponse
,
error
)
{
ctx
,
err
:=
s
.
authorizeAdminGeneric
(
ctx
,
tx
,
req
.
SSO
)
if
err
!=
nil
{
return
nil
,
err
}
var
resp
CreateResourcesResponse
err
=
s
.
withRequest
(
ctx
,
req
,
func
(
ctx
context
.
Context
)
error
{
for
_
,
r
:=
range
req
.
Resources
{
if
err
:=
s
.
resourceValidator
.
validateResource
(
ctx
,
r
);
err
!=
nil
{
log
.
Printf
(
"validation error while creating resource %+v: %v"
,
r
,
err
)
return
err
}
if
err
:=
tx
.
UpdateResource
(
ctx
,
r
);
err
!=
nil
{
return
err
}
resp
.
IDs
=
append
(
resp
.
IDs
,
r
.
ID
)
}
return
nil
})
return
&
resp
,
err
}
const
appSpecificPasswordLen
=
64
const
appSpecificPasswordLen
=
64
func
randomBase64
(
n
int
)
string
{
func
randomBase64
(
n
int
)
string
{
...
...
This diff is collapsed.
Click to expand it.
actions_test.go
+
27
−
3
View file @
cc4053f8
...
@@ -147,7 +147,7 @@ func testConfig() *Config {
...
@@ -147,7 +147,7 @@ func testConfig() *Config {
func
testService
(
admin
string
)
(
*
AccountService
,
TX
)
{
func
testService
(
admin
string
)
(
*
AccountService
,
TX
)
{
be
:=
createFakeBackend
()
be
:=
createFakeBackend
()
svc
:=
newAccountServiceWithSSO
(
be
,
testConfig
(),
&
fakeValidator
{
admin
})
svc
,
_
:=
newAccountServiceWithSSO
(
be
,
testConfig
(),
&
fakeValidator
{
admin
})
tx
,
_
:=
be
.
NewTransaction
()
tx
,
_
:=
be
.
NewTransaction
()
return
svc
,
tx
return
svc
,
tx
}
}
...
@@ -203,7 +203,7 @@ func TestService_Auth(t *testing.T) {
...
@@ -203,7 +203,7 @@ func TestService_Auth(t *testing.T) {
func
TestService_ChangePassword
(
t
*
testing
.
T
)
{
func
TestService_ChangePassword
(
t
*
testing
.
T
)
{
fb
:=
createFakeBackend
()
fb
:=
createFakeBackend
()
tx
,
_
:=
fb
.
NewTransaction
()
tx
,
_
:=
fb
.
NewTransaction
()
svc
:=
newAccountServiceWithSSO
(
fb
,
testConfig
(),
&
fakeValidator
{})
svc
,
_
:=
newAccountServiceWithSSO
(
fb
,
testConfig
(),
&
fakeValidator
{})
testdata
:=
[]
struct
{
testdata
:=
[]
struct
{
password
string
password
string
...
@@ -250,7 +250,7 @@ func TestService_ChangePassword(t *testing.T) {
...
@@ -250,7 +250,7 @@ func TestService_ChangePassword(t *testing.T) {
// directly.
// directly.
func
TestService_EncryptionKeys
(
t
*
testing
.
T
)
{
func
TestService_EncryptionKeys
(
t
*
testing
.
T
)
{
fb
:=
createFakeBackend
()
fb
:=
createFakeBackend
()
svc
:=
newAccountServiceWithSSO
(
fb
,
testConfig
(),
&
fakeValidator
{})
svc
,
_
:=
newAccountServiceWithSSO
(
fb
,
testConfig
(),
&
fakeValidator
{})
tx
,
_
:=
fb
.
NewTransaction
()
tx
,
_
:=
fb
.
NewTransaction
()
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
...
@@ -306,3 +306,27 @@ func TestService_AddEmailAlias(t *testing.T) {
...
@@ -306,3 +306,27 @@ func TestService_AddEmailAlias(t *testing.T) {
}
}
}
}
}
}
func
TestService_Create
(
t
*
testing
.
T
)
{
svc
,
tx
:=
testService
(
""
)
_
,
err
:=
svc
.
CreateResources
(
context
.
Background
(),
tx
,
&
CreateResourcesRequest
{
Resources
:
[]
*
Resource
{
&
Resource
{
ID
:
NewResourceID
(
ResourceTypeDomain
,
"testuser"
,
"example2.com"
),
Name
:
"example2.com"
,
Status
:
ResourceStatusActive
,
Shard
:
"host2"
,
OriginalShard
:
"host2"
,
Website
:
&
Website
{
URL
:
"https://example2.com"
,
DocumentRoot
:
"/home/sites/example2.com"
,
AcceptMail
:
true
,
},
},
},
})
if
err
!=
nil
{
t
.
Fatal
(
"CreateResources"
,
err
)
}
}
This diff is collapsed.
Click to expand it.
audit.go
0 → 100644
+
39
−
0
View file @
cc4053f8
package
accountserver
import
(
"context"
"encoding/json"
"log"
)
type
auditLogger
interface
{
Log
(
context
.
Context
,
ResourceID
,
string
)
}
type
auditLogEntry
struct
{
User
string
`json:"user,omitempty"`
By
string
`json:"by"`
Message
string
`json:"message"`
Comment
string
`json:"comment,omitempty"`
ResourceName
string
`json:"resource_name,omitempty"`
ResourceType
string
`json:"resource_type,omitempty"`
}
type
syslogAuditLogger
struct
{}
func
(
l
*
syslogAuditLogger
)
Log
(
ctx
context
.
Context
,
resourceID
ResourceID
,
what
string
)
{
e
:=
auditLogEntry
{
User
:
userFromContext
(
ctx
),
By
:
authUserFromContext
(
ctx
),
Message
:
what
,
Comment
:
commentFromContext
(
ctx
),
}
if
!
resourceID
.
Empty
()
{
e
.
ResourceName
=
resourceID
.
Name
()
e
.
ResourceType
=
resourceID
.
Type
()
}
data
,
_
:=
json
.
Marshal
(
&
e
)
log
.
Printf
(
"@cee:%s"
,
data
)
}
This diff is collapsed.
Click to expand it.
config.go
+
19
−
6
View file @
cc4053f8
...
@@ -9,6 +9,9 @@ import (
...
@@ -9,6 +9,9 @@ import (
// Config holds the configuration for the AccountService.
// Config holds the configuration for the AccountService.
type
Config
struct
{
type
Config
struct
{
ForbiddenUsernames
[]
string
`yaml:"forbidden_usernames"`
ForbiddenUsernames
[]
string
`yaml:"forbidden_usernames"`
ForbiddenUsernamesFile
string
`yaml:"forbidden_usernames_file"`
ForbiddenPasswords
[]
string
`yaml:"forbidden_passwords"`
ForbiddenPasswordsFile
string
`yaml:"forbidden_passwords_file"`
AvailableDomains
map
[
string
][]
string
`yaml:"available_domains"`
AvailableDomains
map
[
string
][]
string
`yaml:"available_domains"`
SSO
struct
{
SSO
struct
{
...
@@ -28,13 +31,23 @@ func (c *Config) domainBackend() domainBackend {
...
@@ -28,13 +31,23 @@ func (c *Config) domainBackend() domainBackend {
return
b
return
b
}
}
func
(
c
*
Config
)
validationConfig
()
*
validationConfig
{
func
(
c
*
Config
)
validationConfig
(
be
Backend
)
(
*
validationConfig
,
error
)
{
fu
,
err
:=
newStringSetFromFileOrList
(
c
.
ForbiddenUsernames
,
c
.
ForbiddenUsernamesFile
)
if
err
!=
nil
{
return
nil
,
err
}
fp
,
err
:=
newStringSetFromFileOrList
(
c
.
ForbiddenPasswords
,
c
.
ForbiddenPasswordsFile
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
validationConfig
{
return
&
validationConfig
{
forbiddenUsernames
:
newStringSetFromList
(
c
.
ForbiddenUsernames
)
,
forbiddenUsernames
:
fu
,
forbiddenPasswords
:
newStringSetFromList
([]
string
{
"123456"
,
"password"
,
"password1"
})
,
forbiddenPasswords
:
fp
,
minPasswordLength
:
6
,
minPasswordLength
:
6
,
maxPasswordLength
:
128
,
maxPasswordLength
:
128
,
}
domains
:
c
.
domainBackend
(),
backend
:
be
,
},
nil
}
}
func
(
c
*
Config
)
ssoValidator
()
(
sso
.
Validator
,
error
)
{
func
(
c
*
Config
)
ssoValidator
()
(
sso
.
Validator
,
error
)
{
...
...
This diff is collapsed.
Click to expand it.
service.go
+
32
−
6
View file @
cc4053f8
...
@@ -68,8 +68,12 @@ type AccountService struct {
...
@@ -68,8 +68,12 @@ type AccountService struct {
ssoGroups
[]
string
ssoGroups
[]
string
ssoAdminGroup
string
ssoAdminGroup
string
audit
auditLogger
passwordValidator
ValidatorFunc
passwordValidator
ValidatorFunc
emailValidator
ValidatorFunc
emailValidator
ValidatorFunc
listValidator
ValidatorFunc
resourceValidator
*
resourceValidator
}
}
// NewAccountService builds a new AccountService with the specified configuration.
// NewAccountService builds a new AccountService with the specified configuration.
...
@@ -79,23 +83,28 @@ func NewAccountService(backend Backend, config *Config) (*AccountService, error)
...
@@ -79,23 +83,28 @@ func NewAccountService(backend Backend, config *Config) (*AccountService, error)
return
nil
,
err
return
nil
,
err
}
}
return
newAccountServiceWithSSO
(
backend
,
config
,
ssoValidator
)
,
nil
return
newAccountServiceWithSSO
(
backend
,
config
,
ssoValidator
)
}
}
func
newAccountServiceWithSSO
(
backend
Backend
,
config
*
Config
,
ssoValidator
sso
.
Validator
)
*
AccountService
{
func
newAccountServiceWithSSO
(
backend
Backend
,
config
*
Config
,
ssoValidator
sso
.
Validator
)
(
*
AccountService
,
error
)
{
s
:=
&
AccountService
{
s
:=
&
AccountService
{
validator
:
ssoValidator
,
validator
:
ssoValidator
,
ssoService
:
config
.
SSO
.
Service
,
ssoService
:
config
.
SSO
.
Service
,
ssoGroups
:
config
.
SSO
.
Groups
,
ssoGroups
:
config
.
SSO
.
Groups
,
ssoAdminGroup
:
config
.
SSO
.
AdminGroup
,
ssoAdminGroup
:
config
.
SSO
.
AdminGroup
,
audit
:
&
syslogAuditLogger
{},
}
}
validationConfig
:=
config
.
validationConfig
()
validationConfig
,
err
:=
config
.
validationConfig
(
backend
)
domainBackend
:=
config
.
domainBackend
()
if
err
!=
nil
{
return
nil
,
err
}
s
.
passwordValidator
=
validPassword
(
validationConfig
)
s
.
passwordValidator
=
validPassword
(
validationConfig
)
s
.
emailValidator
=
validHostedEmail
(
validationConfig
,
domainBackend
,
backend
)
s
.
emailValidator
=
validHostedEmail
(
validationConfig
)
s
.
listValidator
=
validHostedMailingList
(
validationConfig
)
s
.
resourceValidator
=
newResourceValidator
(
validationConfig
)
return
s
return
s
,
nil
}
}
func
(
s
*
AccountService
)
isAdmin
(
tkt
*
sso
.
Ticket
)
bool
{
func
(
s
*
AccountService
)
isAdmin
(
tkt
*
sso
.
Ticket
)
bool
{
...
@@ -145,6 +154,23 @@ func authUserFromContext(ctx context.Context) string {
...
@@ -145,6 +154,23 @@ func authUserFromContext(ctx context.Context) string {
return
""
return
""
}
}
func
(
s
*
AccountService
)
authorizeAdminGeneric
(
ctx
context
.
Context
,
tx
TX
,
ssoTicket
string
)
(
context
.
Context
,
error
)
{
// Validate the SSO ticket.
tkt
,
err
:=
s
.
validateSSO
(
ssoTicket
)
if
err
!=
nil
{
return
nil
,
newAuthError
(
err
)
}
// Requests are allowed if the SSO ticket corresponds to an admin, or if
// it identifies the same user that we're querying.
if
!
s
.
isAdmin
(
tkt
)
{
return
nil
,
newAuthError
(
ErrUnauthorized
)
}
ctx
=
context
.
WithValue
(
ctx
,
authUserCtxKey
,
tkt
.
User
)
return
ctx
,
nil
}
func
(
s
*
AccountService
)
authorizeAdmin
(
ctx
context
.
Context
,
tx
TX
,
req
RequestBase
)
(
context
.
Context
,
*
User
,
error
)
{
func
(
s
*
AccountService
)
authorizeAdmin
(
ctx
context
.
Context
,
tx
TX
,
req
RequestBase
)
(
context
.
Context
,
*
User
,
error
)
{
// Validate the SSO ticket.
// Validate the SSO ticket.
tkt
,
err
:=
s
.
validateSSO
(
req
.
SSO
)
tkt
,
err
:=
s
.
validateSSO
(
req
.
SSO
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment