Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
accountserver
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2
Issues
2
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai3
accountserver
Commits
5f6e6818
Commit
5f6e6818
authored
Jun 23, 2018
by
ale
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add API to manage email aliases
parent
da51a6a2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
124 additions
and
25 deletions
+124
-25
actions.go
actions.go
+68
-6
actions_test.go
actions_test.go
+54
-13
service.go
service.go
+2
-6
No files found.
actions.go
View file @
5f6e6818
...
...
@@ -109,7 +109,7 @@ type DisableResourceRequest struct {
// DisableResource disables a resource belonging to the user.
func
(
s
*
AccountService
)
DisableResource
(
ctx
context
.
Context
,
tx
TX
,
req
*
DisableResourceRequest
)
error
{
ctx
,
r
,
err
:=
s
.
authorizeResource
(
req
.
NewContext
(
ctx
)
,
tx
,
req
.
ResourceRequestBase
)
ctx
,
r
,
err
:=
s
.
authorizeResource
(
ctx
,
tx
,
req
.
ResourceRequestBase
)
if
err
!=
nil
{
return
err
}
...
...
@@ -125,7 +125,7 @@ type EnableResourceRequest struct {
// EnableResource enables a resource belonging to the user.
func
(
s
*
AccountService
)
EnableResource
(
ctx
context
.
Context
,
tx
TX
,
req
*
EnableResourceRequest
)
error
{
ctx
,
r
,
err
:=
s
.
authorizeResource
(
req
.
NewContext
(
ctx
)
,
tx
,
req
.
ResourceRequestBase
)
ctx
,
r
,
err
:=
s
.
authorizeResource
(
ctx
,
tx
,
req
.
ResourceRequestBase
)
if
err
!=
nil
{
return
err
}
...
...
@@ -332,7 +332,7 @@ type DeleteApplicationSpecificPasswordRequest struct {
// DeleteApplicationSpecificPassword destroys an application-specific
// password, identified by its unique ID.
func
(
s
*
AccountService
)
DeleteApplicationSpecificPassword
(
ctx
context
.
Context
,
tx
TX
,
req
*
DeleteApplicationSpecificPasswordRequest
)
error
{
ctx
,
user
,
err
:=
s
.
authorizeUser
(
req
.
NewContext
(
ctx
)
,
tx
,
req
.
RequestBase
)
ctx
,
user
,
err
:=
s
.
authorizeUser
(
ctx
,
tx
,
req
.
RequestBase
)
if
err
!=
nil
{
return
err
}
...
...
@@ -379,7 +379,7 @@ type MoveResourceResponse struct {
// once regardless of which individual ResourceID is provided as long
// as it belongs to the group.
func
(
s
*
AccountService
)
MoveResource
(
ctx
context
.
Context
,
tx
TX
,
req
*
MoveResourceRequest
)
(
*
MoveResourceResponse
,
error
)
{
ctx
,
user
,
err
:=
s
.
authorizeAdmin
(
req
.
NewContext
(
ctx
)
,
tx
,
req
.
RequestBase
)
ctx
,
user
,
err
:=
s
.
authorizeAdmin
(
ctx
,
tx
,
req
.
RequestBase
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -437,7 +437,7 @@ type EnableOTPResponse struct {
// or it can let the server generate a new secret by passing an empty
// totp_secret.
func
(
s
*
AccountService
)
EnableOTP
(
ctx
context
.
Context
,
tx
TX
,
req
*
EnableOTPRequest
)
(
*
EnableOTPResponse
,
error
)
{
ctx
,
user
,
err
:=
s
.
authorizeUser
(
req
.
NewContext
(
ctx
)
,
tx
,
req
.
RequestBase
)
ctx
,
user
,
err
:=
s
.
authorizeUser
(
ctx
,
tx
,
req
.
RequestBase
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -469,7 +469,7 @@ type DisableOTPRequest struct {
// DisableOTP disables two-factor authentication for a user.
func
(
s
*
AccountService
)
DisableOTP
(
ctx
context
.
Context
,
tx
TX
,
req
*
DisableOTPRequest
)
error
{
ctx
,
user
,
err
:=
s
.
authorizeUser
(
req
.
NewContext
(
ctx
)
,
tx
,
req
.
RequestBase
)
ctx
,
user
,
err
:=
s
.
authorizeUser
(
ctx
,
tx
,
req
.
RequestBase
)
if
err
!=
nil
{
return
err
}
...
...
@@ -483,6 +483,68 @@ func (s *AccountService) DisableOTP(ctx context.Context, tx TX, req *DisableOTPR
})
}
// AddEmailAliasRequest is the request type for AccountService.AddEmailAlias().
type
AddEmailAliasRequest
struct
{
ResourceRequestBase
Addr
string
`json:"addr"`
}
// Validate the request.
func
(
r
*
AddEmailAliasRequest
)
Validate
(
ctx
context
.
Context
,
s
*
AccountService
)
error
{
return
s
.
emailValidator
(
ctx
,
r
.
Addr
)
}
const
maxEmailAliases
=
5
// AddEmailAlias adds an alias (additional address) to an email resource.
func
(
s
*
AccountService
)
AddEmailAlias
(
ctx
context
.
Context
,
tx
TX
,
req
*
AddEmailAliasRequest
)
error
{
ctx
,
r
,
err
:=
s
.
authorizeResource
(
ctx
,
tx
,
req
.
ResourceRequestBase
)
if
err
!=
nil
{
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
{
// Allow at most 5 aliases.
if
len
(
r
.
Email
.
Aliases
)
>=
maxEmailAliases
{
return
errors
.
New
(
"too many aliases"
)
}
r
.
Email
.
Aliases
=
append
(
r
.
Email
.
Aliases
,
req
.
Addr
)
return
tx
.
UpdateResource
(
ctx
,
r
)
})
}
// DeleteEmailAliasRequest is the request type for AccountService.DeleteEmailAlias().
type
DeleteEmailAliasRequest
struct
{
ResourceRequestBase
Addr
string
`json:"addr"`
}
// DeleteEmailAlias removes an alias from an email resource.
func
(
s
*
AccountService
)
DeleteEmailAlias
(
ctx
context
.
Context
,
tx
TX
,
req
*
DeleteEmailAliasRequest
)
error
{
ctx
,
r
,
err
:=
s
.
authorizeResource
(
ctx
,
tx
,
req
.
ResourceRequestBase
)
if
err
!=
nil
{
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
{
var
aliases
[]
string
for
_
,
a
:=
range
r
.
Email
.
Aliases
{
if
a
!=
req
.
Addr
{
aliases
=
append
(
aliases
,
a
)
}
}
r
.
Email
.
Aliases
=
aliases
return
tx
.
UpdateResource
(
ctx
,
r
)
})
}
const
appSpecificPasswordLen
=
64
func
randomBase64
(
n
int
)
string
{
...
...
actions_test.go
View file @
5f6e6818
...
...
@@ -99,31 +99,42 @@ func (v *fakeValidator) Validate(tkt, nonce, service string, _ []string) (*sso.T
},
nil
}
func
(
b
*
fakeBackend
)
addUser
(
user
*
User
)
{
b
.
users
[
user
.
Name
]
=
user
b
.
resources
[
user
.
Name
]
=
make
(
map
[
string
]
*
Resource
)
for
_
,
r
:=
range
user
.
Resources
{
b
.
resources
[
user
.
Name
][
r
.
ID
.
String
()]
=
r
}
}
func
createFakeBackend
()
*
fakeBackend
{
fb
:=
&
fakeBackend
{
users
:
map
[
string
]
*
User
{
"testuser"
:
&
User
{
Name
:
"testuser"
,
Resources
:
[]
*
Resource
{
{
ID
:
NewResourceID
(
"email"
,
"testuser@example.com"
,
"testuser@example.com"
),
Name
:
"testuser@example.com"
,
Status
:
ResourceStatusActive
,
Email
:
&
Email
{},
},
},
},
},
users
:
make
(
map
[
string
]
*
User
),
resources
:
make
(
map
[
string
]
map
[
string
]
*
Resource
),
passwords
:
make
(
map
[
string
]
string
),
appSpecificPasswords
:
make
(
map
[
string
][]
*
AppSpecificPasswordInfo
),
encryptionKeys
:
make
(
map
[
string
][]
*
UserEncryptionKey
),
}
fb
.
addUser
(
&
User
{
Name
:
"testuser"
,
Resources
:
[]
*
Resource
{
{
ID
:
NewResourceID
(
ResourceTypeEmail
,
"testuser"
,
"testuser@example.com"
),
Name
:
"testuser@example.com"
,
Status
:
ResourceStatusActive
,
Email
:
&
Email
{},
},
},
})
return
fb
}
func
testConfig
()
*
Config
{
var
c
Config
c
.
ForbiddenUsernames
=
[]
string
{
"root"
}
c
.
AvailableDomains
=
map
[
string
][]
string
{
ResourceTypeEmail
:
[]
string
{
"example.com"
},
}
c
.
SSO
.
Domain
=
"mydomain"
c
.
SSO
.
Service
=
"service/"
c
.
SSO
.
AdminGroup
=
testAdminGroupName
...
...
@@ -255,3 +266,33 @@ func TestService_EncryptionKeys(t *testing.T) {
t
.
Fatalf
(
"found %d encryption keys, expected 1"
,
n
)
}
}
// Try adding aliases to the email resource.
func
TestService_AddEmailAlias
(
t
*
testing
.
T
)
{
svc
,
tx
:=
testService
(
""
)
testdata
:=
[]
struct
{
addr
string
expectedOk
bool
}{
{
"alias@example.com"
,
true
},
{
"another-example-address@example.com"
,
true
},
{
"root@example.com"
,
false
},
{
"alias@other-domain.com"
,
false
},
}
for
_
,
td
:=
range
testdata
{
req
:=
&
AddEmailAliasRequest
{
ResourceRequestBase
:
ResourceRequestBase
{
SSO
:
"testuser"
,
ResourceID
:
NewResourceID
(
ResourceTypeEmail
,
"testuser"
,
"testuser@example.com"
),
},
Addr
:
td
.
addr
,
}
err
:=
svc
.
AddEmailAlias
(
context
.
TODO
(),
tx
,
req
)
if
err
!=
nil
&&
td
.
expectedOk
{
t
.
Errorf
(
"AddEmailAlias(%s) failed: %v"
,
td
.
addr
,
err
)
}
else
if
err
==
nil
&&
!
td
.
expectedOk
{
t
.
Errorf
(
"AddEmailAlias(%s) did not fail but should have"
,
td
.
addr
)
}
}
}
service.go
View file @
5f6e6818
...
...
@@ -68,8 +68,7 @@ type AccountService struct {
ssoAdminGroup
string
passwordValidator
ValidatorFunc
dataValidators
map
[
string
]
ValidatorFunc
//adminDataValidators map[string]ValidatorFunc
emailValidator
ValidatorFunc
}
// NewAccountService builds a new AccountService with the specified configuration.
...
...
@@ -92,11 +91,8 @@ func newAccountServiceWithSSO(backend Backend, config *Config, ssoValidator sso.
validationConfig
:=
config
.
validationConfig
()
domainBackend
:=
config
.
domainBackend
()
s
.
dataValidators
=
map
[
string
]
ValidatorFunc
{
ResourceTypeEmail
:
validHostedEmail
(
validationConfig
,
domainBackend
,
backend
),
ResourceTypeMailingList
:
validHostedMailingList
(
validationConfig
,
domainBackend
,
backend
),
}
s
.
passwordValidator
=
validPassword
(
validationConfig
)
s
.
emailValidator
=
validHostedEmail
(
validationConfig
,
domainBackend
,
backend
)
return
s
}
...
...
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