Skip to content

Commit

Permalink
Self delete API
Browse files Browse the repository at this point in the history
  • Loading branch information
harture committed Sep 9, 2019
1 parent 8ce645f commit e98cfd5
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 14 deletions.
26 changes: 13 additions & 13 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Gopkg.toml
Expand Up @@ -31,7 +31,8 @@

[[constraint]]
name = "github.com/cloudtrust/keycloak-client"
version = "v1.0-rc4"
#version = "v1.0-rc4"
branch = "CLOUDTRUST-1646_Self-deleteAPI"

[[constraint]]
name = "github.com/go-kit/kit"
Expand Down
7 changes: 7 additions & 0 deletions api/account/swagger-api_account.yaml
Expand Up @@ -50,6 +50,13 @@ paths:
responses:
200:
description: successful operation
delete:
tags:
- Account
summary: Delete account
responses:
200:
description: successful operation
components:
schemas:
UpdatePassword:
Expand Down
3 changes: 3 additions & 0 deletions cmd/keycloakb/keycloak_bridge.go
Expand Up @@ -452,6 +452,7 @@ func main() {
UpdatePassword: prepareEndpoint(account.MakeUpdatePasswordEndpoint(accountComponent), "update_password", influxMetrics, accountLogger, tracer, rateLimit["account"]),
GetAccount: prepareEndpoint(account.MakeGetAccountEndpoint(accountComponent), "get_account", influxMetrics, accountLogger, tracer, rateLimit["account"]),
UpdateAccount: prepareEndpoint(account.MakeUpdateAccountEndpoint(accountComponent), "update_account", influxMetrics, accountLogger, tracer, rateLimit["account"]),
DeleteAccount: prepareEndpoint(account.MakeDeleteAccountEndpoint(accountComponent), "delete_account", influxMetrics, accountLogger, tracer, rateLimit["account"]),
}
}

Expand Down Expand Up @@ -635,10 +636,12 @@ func main() {
var updatePasswordHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdatePassword)
var getAccountHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.GetAccount)
var updateAccountHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdateAccount)
var deleteAccountHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.DeleteAccount)

route.Path("/account/credentials/password").Methods("POST").Handler(updatePasswordHandler)
route.Path("/account").Methods("GET").Handler(getAccountHandler)
route.Path("/account").Methods("POST").Handler(updateAccountHandler)
route.Path("/account").Methods("DELETE").Handler(deleteAccountHandler)

c := cors.New(corsOptions)
errc <- http.ListenAndServe(httpAddrAccount, c.Handler(route))
Expand Down
16 changes: 16 additions & 0 deletions pkg/account/component.go
Expand Up @@ -19,13 +19,15 @@ type KeycloakClient interface {
UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword string) (string, error)
UpdateAccount(accessToken, realm string, user kc.UserRepresentation) error
GetAccount(accessToken, realm string) (kc.UserRepresentation, error)
DeleteAccount(accessToken, realm string) error
}

// Component interface exposes methods used by the bridge API
type Component interface {
UpdatePassword(ctx context.Context, currentPassword, newPassword, confirmPassword string) error
GetAccount(ctx context.Context) (api.AccountRepresentation, error)
UpdateAccount(context.Context, api.AccountRepresentation) error
DeleteAccount(context.Context) error
}

// Component is the management component.
Expand Down Expand Up @@ -182,3 +184,17 @@ func (c *component) UpdateAccount(ctx context.Context, user api.AccountRepresent

return nil
}

func (c *component) DeleteAccount(ctx context.Context) error {
var accessToken = ctx.Value(cs.CtContextAccessToken).(string)
var realm = ctx.Value(cs.CtContextRealm).(string)

err := c.keycloakClient.DeleteAccount(accessToken, realm)

if err != nil {
c.logger.Warn("err", err.Error())
return err
}

return nil
}
35 changes: 35 additions & 0 deletions pkg/account/component_test.go
Expand Up @@ -362,3 +362,38 @@ func TestGetUser(t *testing.T) {
assert.NotNil(t, err)
}
}

func TestDeleteUser(t *testing.T) {
var mockCtrl = gomock.NewController(t)
defer mockCtrl.Finish()
mockKeycloakClient := mock.NewAccKeycloakClient(mockCtrl)
mockEventDBModule := mock.NewEventsDBModule(mockCtrl)
var mockLogger = log.NewNopLogger()

var accountComponent = NewComponent(mockKeycloakClient, mockEventDBModule, mockLogger)

var accessToken = "TOKEN=="
var realmName = "master"
var username = "username"

var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken)
ctx = context.WithValue(ctx, cs.CtContextRealm, realmName)
ctx = context.WithValue(ctx, cs.CtContextUsername, username)

// Delete user with succces
{
mockKeycloakClient.EXPECT().DeleteAccount(accessToken, realmName).Return(nil).Times(1)

err := accountComponent.DeleteAccount(ctx)

assert.Nil(t, err)
}

//Error
{
mockKeycloakClient.EXPECT().DeleteAccount(accessToken, realmName).Return(fmt.Errorf("Unexpected error")).Times(1)
err := accountComponent.DeleteAccount(ctx)

assert.NotNil(t, err)
}
}
9 changes: 9 additions & 0 deletions pkg/account/endpoint.go
Expand Up @@ -15,6 +15,7 @@ type Endpoints struct {
UpdatePassword endpoint.Endpoint
GetAccount endpoint.Endpoint
UpdateAccount endpoint.Endpoint
DeleteAccount endpoint.Endpoint
}

// UpdatePasswordBody is the definition of the expected body content of UpdatePassword method
Expand All @@ -29,6 +30,7 @@ type AccountComponent interface {
UpdatePassword(ctx context.Context, currentPassword, newPassword, confirmPassword string) error
GetAccount(ctx context.Context) (api.AccountRepresentation, error)
UpdateAccount(ctx context.Context, account api.AccountRepresentation) error
DeleteAccount(ctx context.Context) error
}

// MakeUpdatePasswordEndpoint makes the UpdatePassword endpoint to update connected user's own password.
Expand Down Expand Up @@ -71,3 +73,10 @@ func MakeUpdateAccountEndpoint(component AccountComponent) cs.Endpoint {
return nil, component.UpdateAccount(ctx, body)
}
}

// MakeDeleteAccountEndpoint makes the DeleteAccount endpoint to delete connected user.
func MakeDeleteAccountEndpoint(component AccountComponent) cs.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
return nil, component.DeleteAccount(ctx)
}
}
13 changes: 13 additions & 0 deletions pkg/account/endpoint_test.go
Expand Up @@ -72,3 +72,16 @@ func TestMakeUpdateAccountEndpoint(t *testing.T) {
assert.NotNil(t, err)
}
}

func TestMakeDeleteAccountEndpoint(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

mockAccountComponent := mock.NewAccountComponent(mockCtrl)
mockAccountComponent.EXPECT().DeleteAccount(gomock.Any()).Return(nil).Times(1)

{
_, err := MakeDeleteAccountEndpoint(mockAccountComponent)(context.Background(), nil)
assert.Nil(t, err)
}
}

0 comments on commit e98cfd5

Please sign in to comment.