Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dex
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
dex
Commits
a4269430
Commit
a4269430
authored
Sep 29, 2015
by
Joe Bowers
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #140 from joeatwork/disable-users-api
Expose API to enable and disable users
parents
05adce3e
2ed28598
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
443 additions
and
12 deletions
+443
-12
user.go
db/user.go
+19
-0
user_repo_test.go
functional/repo/user_repo_test.go
+56
-0
user_api_test.go
integration/user_api_test.go
+43
-0
v1-gen.go
schema/adminschema/v1-gen.go
+1
-1
v1-gen.go
schema/workerschema/v1-gen.go
+96
-2
v1-json.go
schema/workerschema/v1-json.go
+47
-3
v1.json
schema/workerschema/v1.json
+45
-1
server.go
server/server.go
+5
-1
user.go
server/user.go
+35
-4
api.go
user/api/api.go
+17
-0
api_test.go
user/api/api_test.go
+48
-0
manager.go
user/manager.go
+16
-0
user.go
user/user.go
+15
-0
No files found.
db/user.go
View file @
a4269430
...
@@ -97,10 +97,29 @@ func (r *userRepo) Create(tx repo.Transaction, usr user.User) (err error) {
...
@@ -97,10 +97,29 @@ func (r *userRepo) Create(tx repo.Transaction, usr user.User) (err error) {
}
}
err
=
r
.
insert
(
tx
,
usr
)
err
=
r
.
insert
(
tx
,
usr
)
return
err
}
func
(
r
*
userRepo
)
Disable
(
tx
repo
.
Transaction
,
userID
string
,
disable
bool
)
error
{
if
userID
==
""
{
return
user
.
ErrorInvalidID
}
qt
:=
pq
.
QuoteIdentifier
(
userTableName
)
ex
:=
r
.
executor
(
tx
)
result
,
err
:=
ex
.
Exec
(
fmt
.
Sprintf
(
"UPDATE %s SET disabled = $2 WHERE id = $1"
,
qt
),
userID
,
disable
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
ct
,
err
:=
result
.
RowsAffected
()
switch
{
case
err
!=
nil
:
return
err
case
ct
==
0
:
return
user
.
ErrorNotFound
}
return
nil
return
nil
}
}
...
...
functional/repo/user_repo_test.go
View file @
a4269430
...
@@ -35,6 +35,7 @@ var (
...
@@ -35,6 +35,7 @@ var (
ID
:
"ID-2"
,
ID
:
"ID-2"
,
Email
:
"Email-2@example.com"
,
Email
:
"Email-2@example.com"
,
CreatedAt
:
time
.
Now
(),
CreatedAt
:
time
.
Now
(),
Disabled
:
true
,
},
},
RemoteIdentities
:
[]
user
.
RemoteIdentity
{
RemoteIdentities
:
[]
user
.
RemoteIdentity
{
{
{
...
@@ -232,6 +233,61 @@ func TestUpdateUser(t *testing.T) {
...
@@ -232,6 +233,61 @@ func TestUpdateUser(t *testing.T) {
}
}
}
}
func
TestDisableUser
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
id
string
disable
bool
err
error
}{
{
id
:
"ID-1"
,
},
{
id
:
"ID-1"
,
disable
:
true
,
},
{
id
:
"ID-2"
,
},
{
id
:
"ID-2"
,
disable
:
true
,
},
{
id
:
"NO SUCH ID"
,
err
:
user
.
ErrorNotFound
,
},
{
id
:
"NO SUCH ID"
,
err
:
user
.
ErrorNotFound
,
disable
:
true
,
},
{
id
:
""
,
err
:
user
.
ErrorInvalidID
,
},
}
for
i
,
tt
:=
range
tests
{
repo
:=
makeTestUserRepo
()
err
:=
repo
.
Disable
(
nil
,
tt
.
id
,
tt
.
disable
)
switch
{
case
err
!=
tt
.
err
:
t
.
Errorf
(
"case %d: want=%q, got=%q"
,
i
,
tt
.
err
,
err
)
case
tt
.
err
==
nil
:
gotUser
,
err
:=
repo
.
Get
(
nil
,
tt
.
id
)
if
err
!=
nil
{
t
.
Fatalf
(
"case %d: want nil err, got %q"
,
i
,
err
)
}
if
gotUser
.
Disabled
!=
tt
.
disable
{
t
.
Errorf
(
"case %d: disabled status want=%v got=%v"
,
i
,
tt
.
disable
,
gotUser
.
Disabled
)
}
}
}
}
func
TestAttachRemoteIdentity
(
t
*
testing
.
T
)
{
func
TestAttachRemoteIdentity
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
tests
:=
[]
struct
{
id
string
id
string
...
...
integration/user_api_test.go
View file @
a4269430
...
@@ -141,6 +141,7 @@ func makeUserAPITestFixtures() *userAPITestFixtures {
...
@@ -141,6 +141,7 @@ func makeUserAPITestFixtures() *userAPITestFixtures {
f
.
trans
=
&
tokenHandlerTransport
{
f
.
trans
=
&
tokenHandlerTransport
{
Handler
:
usrSrv
.
HTTPHandler
(),
Handler
:
usrSrv
.
HTTPHandler
(),
Token
:
userGoodToken
,
}
}
hc
:=
&
http
.
Client
{
hc
:=
&
http
.
Client
{
Transport
:
f
.
trans
,
Transport
:
f
.
trans
,
...
@@ -530,6 +531,48 @@ func TestCreateUser(t *testing.T) {
...
@@ -530,6 +531,48 @@ func TestCreateUser(t *testing.T) {
}
}
}
}
func
TestDisableUser
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
id
string
disable
bool
}{
{
id
:
"ID-2"
,
disable
:
true
,
},
{
id
:
"ID-4"
,
disable
:
false
,
},
}
for
i
,
tt
:=
range
tests
{
f
:=
makeUserAPITestFixtures
()
usr
,
err
:=
f
.
client
.
Users
.
Get
(
tt
.
id
)
.
Do
()
if
err
!=
nil
{
t
.
Fatalf
(
"case %v: unexpected error: %v"
,
i
,
err
)
}
if
usr
.
User
.
Disabled
==
tt
.
disable
{
t
.
Fatalf
(
"case %v: misconfigured test, initial disabled state should be %v but was %v"
,
i
,
!
tt
.
disable
,
usr
.
User
.
Disabled
)
}
_
,
err
=
f
.
client
.
Users
.
Disable
(
tt
.
id
,
&
schema
.
UserDisableRequest
{
Disable
:
tt
.
disable
,
})
.
Do
()
if
err
!=
nil
{
t
.
Fatalf
(
"case %v: unexpected error: %v"
,
i
,
err
)
}
usr
,
err
=
f
.
client
.
Users
.
Get
(
tt
.
id
)
.
Do
()
if
err
!=
nil
{
t
.
Fatalf
(
"case %v: unexpected error: %v"
,
i
,
err
)
}
if
usr
.
User
.
Disabled
!=
tt
.
disable
{
t
.
Errorf
(
"case %v: user disabled state incorrect. wanted: %v found: %v"
,
i
,
tt
.
disable
,
usr
.
User
.
Disabled
)
}
}
}
type
testEmailer
struct
{
type
testEmailer
struct
{
cantEmail
bool
cantEmail
bool
lastEmail
string
lastEmail
string
...
...
schema/adminschema/v1-gen.go
View file @
a4269430
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
//
//
// Usage example:
// Usage example:
//
//
// import "g
ithub.com/coreos/dex/Godeps/_workspace/src/g
oogle.golang.org/api/adminschema/v1"
// import "google.golang.org/api/adminschema/v1"
// ...
// ...
// adminschemaService, err := adminschema.New(oauthHttpClient)
// adminschemaService, err := adminschema.New(oauthHttpClient)
package
adminschema
package
adminschema
...
...
schema/workerschema/v1-gen.go
View file @
a4269430
...
@@ -108,6 +108,8 @@ type User struct {
...
@@ -108,6 +108,8 @@ type User struct {
CreatedAt
string
`json:"createdAt,omitempty"`
CreatedAt
string
`json:"createdAt,omitempty"`
Disabled
bool
`json:"disabled,omitempty"`
DisplayName
string
`json:"displayName,omitempty"`
DisplayName
string
`json:"displayName,omitempty"`
Email
string
`json:"email,omitempty"`
Email
string
`json:"email,omitempty"`
...
@@ -134,6 +136,15 @@ type UserCreateResponse struct {
...
@@ -134,6 +136,15 @@ type UserCreateResponse struct {
type
UserCreateResponseUser
struct
{
type
UserCreateResponseUser
struct
{
}
}
type
UserDisableRequest
struct
{
// Disable: If true, disable this user, if false, enable them
Disable
bool
`json:"disable,omitempty"`
}
type
UserDisableResponse
struct
{
Ok
bool
`json:"ok,omitempty"`
}
type
UserResponse
struct
{
type
UserResponse
struct
{
User
*
User
`json:"user,omitempty"`
User
*
User
`json:"user,omitempty"`
}
}
...
@@ -355,6 +366,89 @@ func (c *UsersCreateCall) Do() (*UserCreateResponse, error) {
...
@@ -355,6 +366,89 @@ func (c *UsersCreateCall) Do() (*UserCreateResponse, error) {
}
}
// method id "dex.User.Disable":
type
UsersDisableCall
struct
{
s
*
Service
id
string
userdisablerequest
*
UserDisableRequest
opt_
map
[
string
]
interface
{}
}
// Disable: Enable or disable a user.
func
(
r
*
UsersService
)
Disable
(
id
string
,
userdisablerequest
*
UserDisableRequest
)
*
UsersDisableCall
{
c
:=
&
UsersDisableCall
{
s
:
r
.
s
,
opt_
:
make
(
map
[
string
]
interface
{})}
c
.
id
=
id
c
.
userdisablerequest
=
userdisablerequest
return
c
}
// Fields allows partial responses to be retrieved.
// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func
(
c
*
UsersDisableCall
)
Fields
(
s
...
googleapi
.
Field
)
*
UsersDisableCall
{
c
.
opt_
[
"fields"
]
=
googleapi
.
CombineFields
(
s
)
return
c
}
func
(
c
*
UsersDisableCall
)
Do
()
(
*
UserDisableResponse
,
error
)
{
var
body
io
.
Reader
=
nil
body
,
err
:=
googleapi
.
WithoutDataWrapper
.
JSONReader
(
c
.
userdisablerequest
)
if
err
!=
nil
{
return
nil
,
err
}
ctype
:=
"application/json"
params
:=
make
(
url
.
Values
)
params
.
Set
(
"alt"
,
"json"
)
if
v
,
ok
:=
c
.
opt_
[
"fields"
];
ok
{
params
.
Set
(
"fields"
,
fmt
.
Sprintf
(
"%v"
,
v
))
}
urls
:=
googleapi
.
ResolveRelative
(
c
.
s
.
BasePath
,
"users/{id}/disable"
)
urls
+=
"?"
+
params
.
Encode
()
req
,
_
:=
http
.
NewRequest
(
"POST"
,
urls
,
body
)
googleapi
.
Expand
(
req
.
URL
,
map
[
string
]
string
{
"id"
:
c
.
id
,
})
req
.
Header
.
Set
(
"Content-Type"
,
ctype
)
req
.
Header
.
Set
(
"User-Agent"
,
"google-api-go-client/0.5"
)
res
,
err
:=
c
.
s
.
client
.
Do
(
req
)
if
err
!=
nil
{
return
nil
,
err
}
defer
googleapi
.
CloseBody
(
res
)
if
err
:=
googleapi
.
CheckResponse
(
res
);
err
!=
nil
{
return
nil
,
err
}
var
ret
*
UserDisableResponse
if
err
:=
json
.
NewDecoder
(
res
.
Body
)
.
Decode
(
&
ret
);
err
!=
nil
{
return
nil
,
err
}
return
ret
,
nil
// {
// "description": "Enable or disable a user.",
// "httpMethod": "POST",
// "id": "dex.User.Disable",
// "parameterOrder": [
// "id"
// ],
// "parameters": {
// "id": {
// "location": "path",
// "required": true,
// "type": "string"
// }
// },
// "path": "users/{id}/disable",
// "request": {
// "$ref": "UserDisableRequest"
// },
// "response": {
// "$ref": "UserDisableResponse"
// }
// }
}
// method id "dex.User.Get":
// method id "dex.User.Get":
type
UsersGetCall
struct
{
type
UsersGetCall
struct
{
...
@@ -363,7 +457,7 @@ type UsersGetCall struct {
...
@@ -363,7 +457,7 @@ type UsersGetCall struct {
opt_
map
[
string
]
interface
{}
opt_
map
[
string
]
interface
{}
}
}
// Get: Get a single
use object
.
// Get: Get a single
User object by id
.
func
(
r
*
UsersService
)
Get
(
id
string
)
*
UsersGetCall
{
func
(
r
*
UsersService
)
Get
(
id
string
)
*
UsersGetCall
{
c
:=
&
UsersGetCall
{
s
:
r
.
s
,
opt_
:
make
(
map
[
string
]
interface
{})}
c
:=
&
UsersGetCall
{
s
:
r
.
s
,
opt_
:
make
(
map
[
string
]
interface
{})}
c
.
id
=
id
c
.
id
=
id
...
@@ -406,7 +500,7 @@ func (c *UsersGetCall) Do() (*UserResponse, error) {
...
@@ -406,7 +500,7 @@ func (c *UsersGetCall) Do() (*UserResponse, error) {
}
}
return
ret
,
nil
return
ret
,
nil
// {
// {
// "description": "Get a single
use object
.",
// "description": "Get a single
User object by id
.",
// "httpMethod": "GET",
// "httpMethod": "GET",
// "id": "dex.User.Get",
// "id": "dex.User.Get",
// "parameterOrder": [
// "parameterOrder": [
...
...
schema/workerschema/v1-json.go
View file @
a4269430
package
workerschema
package
workerschema
//
//
// This file is automatically generated by schema/generator
// This file is automatically generated by schema/generator
//
//
...
@@ -109,6 +108,9 @@ const DiscoveryJSON = `{
...
@@ -109,6 +108,9 @@ const DiscoveryJSON = `{
"admin": {
"admin": {
"type": "boolean"
"type": "boolean"
},
},
"disabled": {
"type": "boolean"
},
"createdAt": {
"createdAt": {
"type": "string",
"type": "string",
"format": "date-time"
"format": "date-time"
...
@@ -167,6 +169,25 @@ const DiscoveryJSON = `{
...
@@ -167,6 +169,25 @@ const DiscoveryJSON = `{
"type": "boolean"
"type": "boolean"
}
}
}
}
},
"UserDisableRequest": {
"id": "UserDisableRequest",
"type": "object",
"properties": {
"disable": {
"type": "boolean",
"description": "If true, disable this user, if false, enable them"
}
}
},
"UserDisableResponse": {
"id": "UserDisableResponse",
"type": "object",
"properties": {
"ok": {
"type": "boolean"
}
}
}
}
},
},
"resources": {
"resources": {
...
@@ -224,7 +245,7 @@ const DiscoveryJSON = `{
...
@@ -224,7 +245,7 @@ const DiscoveryJSON = `{
},
},
"Get": {
"Get": {
"id": "dex.User.Get",
"id": "dex.User.Get",
"description": "Get a single
use object
.",
"description": "Get a single
User object by id
.",
"httpMethod": "GET",
"httpMethod": "GET",
"path": "users/{id}",
"path": "users/{id}",
"parameters": {
"parameters": {
...
@@ -252,9 +273,31 @@ const DiscoveryJSON = `{
...
@@ -252,9 +273,31 @@ const DiscoveryJSON = `{
"response": {
"response": {
"$ref": "UserCreateResponse"
"$ref": "UserCreateResponse"
}
}
},
"Disable": {
"id": "dex.User.Disable",
"description": "Enable or disable a user.",
"httpMethod": "POST",
"path": "users/{id}/disable",
"parameters": {
"id": {
"type": "string",
"required": true,
"location": "path"
}
},
"parameterOrder": [
"id"
],
"request": {
"$ref": "UserDisableRequest"
},
"response": {
"$ref": "UserDisableResponse"
}
}
}
}
}
}
}
}
}
}
}
`
`
\ No newline at end of file
schema/workerschema/v1.json
View file @
a4269430
...
@@ -102,6 +102,9 @@
...
@@ -102,6 +102,9 @@
"admin"
:
{
"admin"
:
{
"type"
:
"boolean"
"type"
:
"boolean"
},
},
"disabled"
:
{
"type"
:
"boolean"
},
"createdAt"
:
{
"createdAt"
:
{
"type"
:
"string"
,
"type"
:
"string"
,
"format"
:
"date-time"
"format"
:
"date-time"
...
@@ -160,6 +163,25 @@
...
@@ -160,6 +163,25 @@
"type"
:
"boolean"
"type"
:
"boolean"
}
}
}
}
},
"UserDisableRequest"
:
{
"id"
:
"UserDisableRequest"
,
"type"
:
"object"
,
"properties"
:
{
"disable"
:
{
"type"
:
"boolean"
,
"description"
:
"If true, disable this user, if false, enable them. No error is signaled if the user state doesn't change."
}
}
},
"UserDisableResponse"
:
{
"id"
:
"UserDisableResponse"
,
"type"
:
"object"
,
"properties"
:
{
"ok"
:
{
"type"
:
"boolean"
}
}
}
}
},
},
"resources"
:
{
"resources"
:
{
...
@@ -217,7 +239,7 @@
...
@@ -217,7 +239,7 @@
},
},
"Get"
:
{
"Get"
:
{
"id"
:
"dex.User.Get"
,
"id"
:
"dex.User.Get"
,
"description"
:
"Get a single
use object
."
,
"description"
:
"Get a single
User object by id
."
,
"httpMethod"
:
"GET"
,
"httpMethod"
:
"GET"
,
"path"
:
"users/{id}"
,
"path"
:
"users/{id}"
,
"parameters"
:
{
"parameters"
:
{
...
@@ -245,6 +267,28 @@
...
@@ -245,6 +267,28 @@
"response"
:
{
"response"
:
{
"$ref"
:
"UserCreateResponse"
"$ref"
:
"UserCreateResponse"
}
}
},
"Disable"
:
{
"id"
:
"dex.User.Disable"
,
"description"
:
"Enable or disable a user."
,
"httpMethod"
:
"POST"
,
"path"
:
"users/{id}/disable"
,
"parameters"
:
{
"id"
:
{
"type"
:
"string"
,
"required"
:
true
,
"location"
:
"path"
}
},
"parameterOrder"
:
[
"id"
],
"request"
:
{
"$ref"
:
"UserDisableRequest"
},
"response"
:
{
"$ref"
:
"UserDisableResponse"
}
}
}
}
}
}
}
...
...
server/server.go
View file @
a4269430
...
@@ -244,7 +244,11 @@ func (s *Server) HTTPHandler() http.Handler {
...
@@ -244,7 +244,11 @@ func (s *Server) HTTPHandler() http.Handler {
mux
.
Handle
(
path
.
Join
(
apiBasePath
,
clientPath
),
s
.
NewClientTokenAuthHandler
(
clientHandler
))
mux
.
Handle
(
path
.
Join
(
apiBasePath
,
clientPath
),
s
.
NewClientTokenAuthHandler
(
clientHandler
))
usersAPI
:=
usersapi
.
NewUsersAPI
(
s
.
UserManager
,
s
.
ClientIdentityRepo
,
s
.
UserEmailer
,
s
.
localConnectorID
)
usersAPI
:=
usersapi
.
NewUsersAPI
(
s
.
UserManager
,
s
.
ClientIdentityRepo
,
s
.
UserEmailer
,
s
.
localConnectorID
)
mux
.
Handle
(
path
.
Join
(
apiBasePath
,
UsersSubTree
),
NewUserMgmtServer
(
usersAPI
,
s
.
JWTVerifierFactory
(),
s
.
UserManager
,
s
.
ClientIdentityRepo
)
.
HTTPHandler
())
handler
:=
NewUserMgmtServer
(
usersAPI
,
s
.
JWTVerifierFactory
(),
s
.
UserManager
,
s
.
ClientIdentityRepo
)
.
HTTPHandler
()
path
:=
path
.
Join
(
apiBasePath
,
UsersSubTree
)
mux
.
Handle
(
path
,
handler
)
mux
.
Handle
(
path
+
"/"
,
handler
)
return
http
.
Handler
(
mux
)
return
http
.
Handler
(
mux
)
}
}
...
...
server/user.go
View file @
a4269430
...
@@ -23,10 +23,11 @@ const (
...
@@ -23,10 +23,11 @@ const (
)
)
var
(
var
(
UsersSubTree
=
"/users"
UsersSubTree
=
"/users"
UsersListEndpoint
=
addBasePath
(
UsersSubTree
)
UsersListEndpoint
=
addBasePath
(
UsersSubTree
)
UsersCreateEndpoint
=
addBasePath
(
UsersSubTree
)
UsersCreateEndpoint
=
addBasePath
(
UsersSubTree
)
UsersGetEndpoint
=
addBasePath
(
UsersSubTree
+
"/:id"
)
UsersGetEndpoint
=
addBasePath
(
UsersSubTree
+
"/:id"
)
UsersDisableEndpoint
=
addBasePath
(
UsersSubTree
+
"/:id/disable"
)
)
)
type
UserMgmtServer
struct
{
type
UserMgmtServer
struct
{
...
@@ -51,6 +52,7 @@ func (s *UserMgmtServer) HTTPHandler() http.Handler {
...
@@ -51,6 +52,7 @@ func (s *UserMgmtServer) HTTPHandler() http.Handler {
r
.
RedirectFixedPath
=
false
r
.
RedirectFixedPath
=
false
r
.
GET
(
UsersListEndpoint
,
s
.
listUsers
)
r
.
GET
(
UsersListEndpoint
,
s
.
listUsers
)
r
.
POST
(
UsersCreateEndpoint
,
s
.
createUser
)
r
.
POST
(
UsersCreateEndpoint
,
s
.
createUser
)
r
.
POST
(
UsersDisableEndpoint
,
s
.
disableUser
)
r
.
GET
(
UsersGetEndpoint
,
s
.
getUser
)
r
.
GET
(
UsersGetEndpoint
,
s
.
getUser
)
return
r
return
r
}
}
...
@@ -140,6 +142,35 @@ func (s *UserMgmtServer) createUser(w http.ResponseWriter, r *http.Request, ps h
...
@@ -140,6 +142,35 @@ func (s *UserMgmtServer) createUser(w http.ResponseWriter, r *http.Request, ps h
writeResponseWithBody
(
w
,
http
.
StatusOK
,
createdResponse
)
writeResponseWithBody
(
w
,
http
.
StatusOK
,
createdResponse
)
}
}
func
(
s
*
UserMgmtServer
)
disableUser
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
ps
httprouter
.
Params
)
{
creds
,
err
:=
s
.
getCreds
(
r
)
if
err
!=
nil
{
s
.
writeError
(
w
,
err
)
return
}
id
:=
ps
.
ByName
(
"id"
)
if
id
==
""
{
writeAPIError
(
w
,
http
.
StatusBadRequest
,
newAPIError
(
errorInvalidRequest
,
"id is required"
))
return
}
disableReq
:=
schema
.
UserDisableRequest
{}
err
=
json
.
NewDecoder
(
r
.
Body
)
.
Decode
(
&
disableReq
)
if
err
!=
nil
{
writeInvalidRequest
(
w
,
"cannot parse JSON body"
)
}
resp
,
err
:=
s
.
api
.
DisableUser
(
creds
,
id
,
disableReq
.
Disable
)
if
err
!=
nil
{
s
.
writeError
(
w
,
err
)
return
}
writeResponseWithBody
(
w
,
http
.
StatusOK
,
resp
)
}
func
(
s
*
UserMgmtServer
)
writeError
(
w
http
.
ResponseWriter
,
err
error
)
{
func
(
s
*
UserMgmtServer
)
writeError
(
w
http
.
ResponseWriter
,
err
error
)
{
log
.
Errorf
(
"Error calling user management API: %v: "
,
err
)
log
.
Errorf
(
"Error calling user management API: %v: "
,
err
)
if
apiErr
,
ok
:=
err
.
(
api
.
Error
);
ok
{
if
apiErr
,
ok
:=
err
.
(
api
.
Error
);
ok
{
...
...
user/api/api.go
View file @
a4269430
...
@@ -121,6 +121,21 @@ func (u *UsersAPI) GetUser(creds Creds, id string) (schema.User, error) {
...
@@ -121,6 +121,21 @@ func (u *UsersAPI) GetUser(creds Creds, id string) (schema.User, error) {
return
userToSchemaUser
(
usr
),
nil
return
userToSchemaUser
(
usr
),
nil
}
}
func
(
u
*
UsersAPI
)
DisableUser
(
creds
Creds
,
userID
string
,
disable
bool
)
(
schema
.
UserDisableResponse
,
error
)
{
log
.
Infof
(
"userAPI: DisableUser"
)
if
!
u
.
Authorize
(
creds
)
{
return
schema
.
UserDisableResponse
{},
ErrorUnauthorized
}
if
err
:=
u
.
manager
.
Disable
(
userID
,
disable
);
err
!=
nil
{
return
schema
.
UserDisableResponse
{},
mapError
(
err
)
}
return
schema
.
UserDisableResponse
{
Ok
:
true
,
},
nil
}
func
(
u
*
UsersAPI
)
CreateUser
(
creds
Creds
,
usr
schema
.
User
,
redirURL
url
.
URL
)
(
schema
.
UserCreateResponse
,
error
)
{
func
(
u
*
UsersAPI
)
CreateUser
(
creds
Creds
,
usr
schema
.
User
,
redirURL
url
.
URL
)
(
schema
.
UserCreateResponse
,
error
)
{
log
.
Infof
(
"userAPI: CreateUser"
)
log
.
Infof
(
"userAPI: CreateUser"
)
if
!
u
.
Authorize
(
creds
)
{
if
!
u
.
Authorize
(
creds
)
{
...
@@ -207,6 +222,7 @@ func userToSchemaUser(usr user.User) schema.User {
...
@@ -207,6 +222,7 @@ func userToSchemaUser(usr user.User) schema.User {
EmailVerified
:
usr
.
EmailVerified
,
EmailVerified
:
usr
.
EmailVerified
,
DisplayName
:
usr
.
DisplayName
,
DisplayName
:
usr
.
DisplayName
,
Admin
:
usr
.
Admin
,
Admin
:
usr
.
Admin
,
Disabled
:
usr
.
Disabled
,
CreatedAt
:
usr
.
CreatedAt
.
UTC
()
.
Format
(
time
.
RFC3339
),
CreatedAt
:
usr
.
CreatedAt
.
UTC
()
.
Format
(
time
.
RFC3339
),
}
}
}
}
...
@@ -218,6 +234,7 @@ func schemaUserToUser(usr schema.User) user.User {
...
@@ -218,6 +234,7 @@ func schemaUserToUser(usr schema.User) user.User {
EmailVerified
:
usr
.
EmailVerified
,
EmailVerified
:
usr
.
EmailVerified
,
DisplayName
:
usr
.
DisplayName
,
DisplayName
:
usr
.
DisplayName
,
Admin
:
usr
.
Admin
,
Admin
:
usr
.
Admin
,
Disabled
:
usr
.
Disabled
,
}
}
}
}
...
...
user/api/api_test.go
View file @
a4269430
...
@@ -94,6 +94,13 @@ func makeTestFixtures() (*UsersAPI, *testEmailer) {
...
@@ -94,6 +94,13 @@ func makeTestFixtures() (*UsersAPI, *testEmailer) {
Email
:
"id3@example.com"
,
Email
:
"id3@example.com"
,
CreatedAt
:
clock
.
Now
(),
CreatedAt
:
clock
.
Now
(),
},
},
},
{
User
:
user
.
User
{
ID
:
"ID-4"
,
Email
:
"id4@example.com"
,
CreatedAt
:
clock
.
Now
(),
Disabled
:
true
,
},
},
},
})
})
pwr
:=
user
.
NewPasswordInfoRepoFromPasswordInfos
([]
user
.
PasswordInfo
{
pwr
:=
user
.
NewPasswordInfoRepoFromPasswordInfos
([]
user
.
PasswordInfo
{
...
@@ -369,3 +376,44 @@ func TestCreateUser(t *testing.T) {
...
@@ -369,3 +376,44 @@ func TestCreateUser(t *testing.T) {
}
}
}
}
}
}
func
TestDisableUsers
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
id
string
disable
bool
}{
{
id
:
"ID-1"
,
disable
:
true
,
},
{
id
:
"ID-1"
,
disable
:
false
,
},
{
id
:
"ID-4"
,
disable
:
true
,
},
{
id
:
"ID-4"
,
disable
:
false
,
},
}
for
i
,
tt
:=
range
tests
{
api
,
_
:=
makeTestFixtures
()
_
,
err
:=
api
.
DisableUser
(
goodCreds
,
tt
.
id
,
tt
.
disable
)
if
err
!=
nil
{
t
.
Fatalf
(
"case %d: unexpected error: %v"
,
i
,
err
)
}
usr
,
err
:=
api
.
GetUser
(
goodCreds
,
tt
.
id
)
if
err
!=
nil
{
t
.
Fatalf
(
"case %d: unexpected error: %v"
,
i
,
err
)
}
if
usr
.
Disabled
!=
tt
.
disable
{
t
.
Errorf
(
"case %d: user disable state wrong. wanted: %v got: %v"
,
i
,
tt
.
disable
,
usr
.
Disabled
)
}
}
}
user/manager.go
View file @
a4269430
...
@@ -102,6 +102,22 @@ func (m *Manager) CreateUser(user User, hashedPassword Password, connID string)
...
@@ -102,6 +102,22 @@ func (m *Manager) CreateUser(user User, hashedPassword Password, connID string)
return
user
.
ID
,
nil
return
user
.
ID
,
nil
}
}
func
(
m
*
Manager
)
Disable
(
userID
string
,
disabled
bool
)
error
{
tx
,
err
:=
m
.
begin
()
if
err
=
m
.
userRepo
.
Disable
(
tx
,
userID
,
disabled
);
err
!=
nil
{
rollback
(
tx
)
return
err
}
if
err
=
tx
.
Commit
();
err
!=
nil
{
rollback
(
tx
)
return
err
}
return
nil
}
// RegisterWithRemoteIdentity creates new user and attaches the given remote identity.
// RegisterWithRemoteIdentity creates new user and attaches the given remote identity.
func
(
m
*
Manager
)
RegisterWithRemoteIdentity
(
email
string
,
emailVerified
bool
,
rid
RemoteIdentity
)
(
string
,
error
)
{
func
(
m
*
Manager
)
RegisterWithRemoteIdentity
(
email
string
,
emailVerified
bool
,
rid
RemoteIdentity
)
(
string
,
error
)
{
tx
,
err
:=
m
.
begin
()
tx
,
err
:=
m
.
begin
()
...
...
user/user.go
View file @
a4269430
...
@@ -80,6 +80,8 @@ type UserRepo interface {
...
@@ -80,6 +80,8 @@ type UserRepo interface {
GetByEmail
(
tx
repo
.
Transaction
,
email
string
)
(
User
,
error
)
GetByEmail
(
tx
repo
.
Transaction
,
email
string
)
(
User
,
error
)
Disable
(
tx
repo
.
Transaction
,
id
string
,
disabled
bool
)
error
Update
(
repo
.
Transaction
,
User
)
error
Update
(
repo
.
Transaction
,
User
)
error
GetByRemoteIdentity
(
repo
.
Transaction
,
RemoteIdentity
)
(
User
,
error
)
GetByRemoteIdentity
(
repo
.
Transaction
,
RemoteIdentity
)
(
User
,
error
)
...
@@ -254,6 +256,19 @@ func (r *memUserRepo) Update(_ repo.Transaction, user User) error {
...
@@ -254,6 +256,19 @@ func (r *memUserRepo) Update(_ repo.Transaction, user User) error {
return
nil
return
nil
}
}
func
(
r
*
memUserRepo
)
Disable
(
_
repo
.
Transaction
,
id
string
,
disable
bool
)
error
{
if
id
==
""
{
return
ErrorInvalidID
}
user
,
ok
:=
r
.
usersByID
[
id
]
if
!
ok
{
return
ErrorNotFound
}
user
.
Disabled
=
disable
r
.
set
(
user
)
return
nil
}
func
(
r
*
memUserRepo
)
AddRemoteIdentity
(
_
repo
.
Transaction
,
userID
string
,
ri
RemoteIdentity
)
error
{
func
(
r
*
memUserRepo
)
AddRemoteIdentity
(
_
repo
.
Transaction
,
userID
string
,
ri
RemoteIdentity
)
error
{
_
,
ok
:=
r
.
usersByID
[
userID
]
_
,
ok
:=
r
.
usersByID
[
userID
]
if
!
ok
{
if
!
ok
{
...
...
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