Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Commit

Permalink
Deactivate user in WIT and Tenant (#790)
Browse files Browse the repository at this point in the history
call WIT and Tenant during user deactivation

also:
- adding `TenantService` as a service (similar to WIT),
  in the ServiceFactory
- adding a function to the WIT service to delete the user
- testing calls to WIT and Tenant with Gock

fixes #777

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Feb 22, 2019
1 parent c02b299 commit 660a631
Show file tree
Hide file tree
Showing 16 changed files with 423 additions and 72 deletions.
251 changes: 226 additions & 25 deletions Gopkg.lock

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ required = [

[[constraint]]
name = "github.com/fabric8-services/fabric8-wit"
revision = "b59d0dc8ae9b2bfea1fb5dc6ff3552c42b735756"
revision = "f7b1641d891c194976363c4a74d1fe0b575491af"

[[constraint]]
name = "github.com/fabric8-services/fabric8-notification"
Expand All @@ -99,7 +99,7 @@ required = [

[[constraint]]
name = "github.com/fabric8-services/fabric8-common"
revision = "988ec38ba27dc10cc955f19cce227e7cd8d58528"
revision = "083c9c890cdf825027a0f009135af153d07d2926"

[[constraint]]
name = "github.com/jstemmer/go-junit-report"
Expand All @@ -120,7 +120,3 @@ required = [
[prune]
go-tests = true
unused-packages = true

[[constraint]]
name = "gopkg.in/h2non/gock.v1"
version = "1.0.12"
17 changes: 17 additions & 0 deletions application/service/factory/service_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func (s *serviceContextImpl) endTransaction() {
type ServiceFactory struct {
contextProducer servicecontext.ServiceContextProducer
config *configuration.ConfigurationData
tenantServiceFunc func() service.TenantService // the function to call when `TenantService()` is called on this factory
witServiceFunc func() service.WITService // the function to call when `WITService()` is called on this factory
notificationServiceFunc func() service.NotificationService // the function to call when `NotificationService()` is called on this factory
clusterServiceFunc func() service.ClusterService
Expand All @@ -152,6 +153,14 @@ func WithWITService(s service.WITService) Option {
}
}

func WithTenantService(s service.TenantService) Option {
return func(f *ServiceFactory) {
f.tenantServiceFunc = func() service.TenantService {
return s
}
}
}

func WithNotificationService(s service.NotificationService) Option {
return func(f *ServiceFactory) {
f.notificationServiceFunc = func() service.NotificationService {
Expand Down Expand Up @@ -184,6 +193,10 @@ func NewServiceFactory(producer servicecontext.ServiceContextProducer, config *c
f.witServiceFunc = func() service.WITService {
return witservice.NewWITService(f.getContext(), f.config)
}
// default function to return an instance of Tenant Service
f.tenantServiceFunc = func() service.TenantService {
return userservice.NewTenantService(f.config)
}
// default function to return an instance of Notification Service
f.notificationServiceFunc = func() service.NotificationService {
return notificationservice.NewNotificationService(f.getContext(), f.config)
Expand Down Expand Up @@ -276,6 +289,10 @@ func (f *ServiceFactory) WITService() service.WITService {
return f.witServiceFunc()
}

func (f *ServiceFactory) TenantService() service.TenantService {
return f.tenantServiceFunc()
}

func (f *ServiceFactory) ClusterService() service.ClusterService {
return f.clusterServiceFunc()
}
13 changes: 11 additions & 2 deletions application/service/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package service

import (
"context"
"github.com/dgrijalva/jwt-go"
"net/url"

jwt "github.com/dgrijalva/jwt-go"
"github.com/fabric8-services/fabric8-auth/app"
account "github.com/fabric8-services/fabric8-auth/authentication/account/repository"
"github.com/fabric8-services/fabric8-auth/authentication/provider"
Expand All @@ -22,7 +24,6 @@ import (
"github.com/goadesign/goa"
uuid "github.com/satori/go.uuid"
"golang.org/x/oauth2"
"net/url"
)

const (
Expand Down Expand Up @@ -165,9 +166,16 @@ type UserService interface {
HardDeleteUser(ctx context.Context, identity account.Identity) error
}

// TenantService represents the Tenant service
type TenantService interface {
Init(ctx context.Context) error
Delete(ctx context.Context, identityID uuid.UUID) error
}

type WITService interface {
UpdateUser(ctx context.Context, updatePayload *app.UpdateUsersPayload, identityID string) error
CreateUser(ctx context.Context, identity *account.Identity, identityID string) error
DeleteUser(ctx context.Context, identityID string) error
GetSpace(ctx context.Context, spaceID string) (space *wit.Space, e error)
}

Expand All @@ -190,6 +198,7 @@ type Services interface {
TokenService() TokenService
UserProfileService() UserProfileService
UserService() UserService
TenantService() TenantService
WITService() WITService
}

Expand Down
14 changes: 6 additions & 8 deletions authentication/account/service/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@ import (
"net/http"
"net/url"

"github.com/fabric8-services/fabric8-auth/application/service"
"github.com/fabric8-services/fabric8-auth/authentication/account/tenant"
"github.com/fabric8-services/fabric8-auth/authorization/token/manager"
"github.com/fabric8-services/fabric8-auth/goasupport"
"github.com/fabric8-services/fabric8-auth/log"
"github.com/fabric8-services/fabric8-auth/rest"
uuid "github.com/satori/go.uuid"

goauuid "github.com/goadesign/goa/uuid"
"github.com/satori/go.uuid"
)

// TenantService represents the Tenant service
type TenantService interface {
Init(ctx context.Context) error
Delete(ctx context.Context, identityID uuid.UUID) error
}

type tenantConfig interface {
GetTenantServiceURL() string
}
Expand All @@ -31,8 +26,10 @@ type tenantServiceImpl struct {
doer rest.HttpDoer
}

var _ service.TenantService = &tenantServiceImpl{}

// NewTenantService creates a new tenant service
func NewTenantService(config tenantConfig) TenantService {
func NewTenantService(config tenantConfig) service.TenantService {
return &tenantServiceImpl{config: config, doer: rest.DefaultHttpDoer()}
}

Expand All @@ -54,6 +51,7 @@ func (t *tenantServiceImpl) Init(ctx context.Context) error {

// Delete deletes tenants for the identity
func (t *tenantServiceImpl) Delete(ctx context.Context, identityID uuid.UUID) error {
log.Info(ctx, map[string]interface{}{"identity_id": identityID.String()}, "deleting user on Tenant service")
c, err := t.createClientWithServiceAccountSigner(ctx)
if err != nil {
return err
Expand Down
15 changes: 15 additions & 0 deletions authentication/account/service/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,21 @@ func (s *userServiceImpl) DeactivateUser(ctx context.Context, username string) (
// revoke all user's tokens
return s.Services().TokenService().SetStatusForAllIdentityTokens(ctx, identity.ID, token.TOKEN_STATUS_REVOKED)
})
if err != nil {
return nil, err
}

// call WIT and Tenant to deactivate the user there as well,
// using `auth` SA token here, not the request context's token
err = s.Services().WITService().DeleteUser(ctx, identity.ID.String())
if err != nil {
// just log the error but don't suspend the deactivation
log.Error(ctx, map[string]interface{}{"identity_id": identity.ID, "error": err}, "error occurred during user deactivation on WIT Service")
}
err = s.Services().TenantService().Delete(ctx, identity.ID)
if err != nil {
return nil, err
}

return identity, err
}
Expand Down
30 changes: 29 additions & 1 deletion authentication/account/service/user_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import (
"github.com/fabric8-services/fabric8-auth/errors"
"github.com/fabric8-services/fabric8-auth/gormtestsupport"
testsupport "github.com/fabric8-services/fabric8-auth/test"
testtoken "github.com/fabric8-services/fabric8-auth/test/token"
"github.com/fabric8-services/fabric8-common/gocksupport"

"github.com/jinzhu/gorm"
errs "github.com/pkg/errors"
uuid "github.com/satori/go.uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
gock "gopkg.in/h2non/gock.v1"
)

type userServiceBlackboxTestSuite struct {
Expand Down Expand Up @@ -67,6 +70,10 @@ func (s *userServiceBlackboxTestSuite) TestDeprovision() {

func (s *userServiceBlackboxTestSuite) TestDeactivate() {

// given
ctx, _, reqID := testtoken.ContextWithTokenAndRequestID(s.T())
saToken := testtoken.TokenManager.AuthServiceAccountToken()

s.T().Run("ok", func(t *testing.T) {
// given 2 users with tokens
userToDeactivate := s.Graph.CreateUser()
Expand All @@ -75,8 +82,26 @@ func (s *userServiceBlackboxTestSuite) TestDeactivate() {
userToStayIntact := s.Graph.CreateUser()
token3 := s.Graph.CreateToken(userToStayIntact)
token4 := s.Graph.CreateToken(userToStayIntact)

defer gock.OffAll()
// call to WIT Service
witCallsCounter := 0
gock.New("http://localhost:8080").
Delete(fmt.Sprintf("/api/users/username/%s", userToDeactivate.IdentityID().String())).
MatchHeader("Authorization", "Bearer "+saToken).
MatchHeader("X-Request-Id", reqID).
SetMatcher(gocksupport.SpyOnCalls(&witCallsCounter)).
Reply(200)
// call to Tenant Service
tenantCallsCounter := 0
gock.New("http://localhost:8090").
Delete(fmt.Sprintf("/api/tenants/%s", userToDeactivate.IdentityID().String())).
MatchHeader("Authorization", "Bearer "+saToken).
MatchHeader("X-Request-Id", reqID).
SetMatcher(gocksupport.SpyOnCalls(&tenantCallsCounter)).
Reply(204)
// when
identity, err := s.Application.UserService().DeactivateUser(s.Ctx, userToDeactivate.Identity().Username)
identity, err := s.Application.UserService().DeactivateUser(ctx, userToDeactivate.Identity().Username)
// then
require.NoError(t, err)
assert.False(t, identity.User.Active) // user is inactive...
Expand All @@ -93,6 +118,9 @@ func (s *userServiceBlackboxTestSuite) TestDeactivate() {
require.NotNil(t, tok)
assert.Equal(t, tok.Token().Status, token.TOKEN_STATUS_REVOKED)
}
// also, verify that WIT and tenant services were called
assert.Equal(t, 1, witCallsCounter)
assert.Equal(t, 1, tenantCallsCounter)
// lastly, verify that user to keep intact remainded intact
loadedUser = s.Graph.LoadUser(userToStayIntact.IdentityID())
assert.True(t, loadedUser.User().Active)
Expand Down
3 changes: 3 additions & 0 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,9 @@ func (c *ConfigurationData) GetWITURL() (string, error) {

// GetTenantServiceURL returns the URL for the Tenant service used by login to initialize OSO tenant space
func (c *ConfigurationData) GetTenantServiceURL() string {
if c.IsPostgresDeveloperModeEnabled() {
return devModeTenantServiceURL
}
return c.v.GetString(varTenantServiceURL)
}

Expand Down
1 change: 1 addition & 0 deletions configuration/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ vwIDAQAB
defaultPublicOAuthClientID = "740650a2-9c44-4db5-b067-a3d1b2cd2d01"
defaultWITDomainPrefix = "api"
devModeWITURL = "http://localhost:8080"
devModeTenantServiceURL = "http://localhost:8090"

// DefaultValidRedirectURLs is a regex to be used to whitelist redirect URL for auth
// If the AUTH_REDIRECT_VALID env var is not set then in Dev Mode all redirects allowed - *
Expand Down
6 changes: 3 additions & 3 deletions controller/namedusers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package controller
import (
"github.com/fabric8-services/fabric8-auth/app"
"github.com/fabric8-services/fabric8-auth/application"
accountservice "github.com/fabric8-services/fabric8-auth/authentication/account/service"
appservice "github.com/fabric8-services/fabric8-auth/application/service"
"github.com/fabric8-services/fabric8-auth/authorization/token"
"github.com/fabric8-services/fabric8-auth/errors"
"github.com/fabric8-services/fabric8-auth/jsonapi"
Expand All @@ -18,11 +18,11 @@ type NamedusersController struct {
*goa.Controller
app application.Application
config UsersControllerConfiguration
tenantService accountservice.TenantService
tenantService appservice.TenantService
}

// NewNamedusersController creates a namedusers controller.
func NewNamedusersController(service *goa.Service, app application.Application, config UsersControllerConfiguration, tenantService accountservice.TenantService) *NamedusersController {
func NewNamedusersController(service *goa.Service, app application.Application, config UsersControllerConfiguration, tenantService appservice.TenantService) *NamedusersController {
return &NamedusersController{
Controller: service.NewController("NamedusersController"),
app: app,
Expand Down
7 changes: 4 additions & 3 deletions controller/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package controller

import (
"context"

"github.com/fabric8-services/fabric8-auth/app"
"github.com/fabric8-services/fabric8-auth/application"
accountservice "github.com/fabric8-services/fabric8-auth/authentication/account/service"
appservice "github.com/fabric8-services/fabric8-auth/application/service"
"github.com/fabric8-services/fabric8-auth/authorization"
"github.com/fabric8-services/fabric8-auth/authorization/token/manager"
"github.com/fabric8-services/fabric8-auth/errors"
Expand All @@ -21,7 +22,7 @@ type UserController struct {
app application.Application
config UserControllerConfiguration
tokenManager manager.TokenManager
tenantService accountservice.TenantService
tenantService appservice.TenantService
}

// UserControllerConfiguration the Configuration for the UserController
Expand All @@ -31,7 +32,7 @@ type UserControllerConfiguration interface {

// NewUserController creates a user controller.
func NewUserController(service *goa.Service, app application.Application, config UserControllerConfiguration,
tokenManager manager.TokenManager, tenantService accountservice.TenantService) *UserController {
tokenManager manager.TokenManager, tenantService appservice.TenantService) *UserController {
return &UserController{
Controller: service.NewController("UserController"),
app: app,
Expand Down
4 changes: 4 additions & 0 deletions gormapplication/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ func (g *GormDB) NotificationService() service.NotificationService {
return g.serviceFactory.NotificationService()
}

func (g *GormDB) TenantService() service.TenantService {
return g.serviceFactory.TenantService()
}

func (g *GormDB) WITService() service.WITService {
return g.serviceFactory.WITService()
}
Expand Down
8 changes: 5 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package main
import (
"context"
"flag"
"github.com/fabric8-services/fabric8-auth/authorization/token/worker"
"net/http"
"os"
"os/user"
"runtime"
"time"

"github.com/fabric8-services/fabric8-auth/authorization/token/worker"

"github.com/fabric8-services/fabric8-auth/app"
factorymanager "github.com/fabric8-services/fabric8-auth/application/factory/manager"
appservice "github.com/fabric8-services/fabric8-auth/application/service"
"github.com/fabric8-services/fabric8-auth/application/transaction"
accountservice "github.com/fabric8-services/fabric8-auth/authentication/account/service"
"github.com/fabric8-services/fabric8-auth/authorization/token/manager"
Expand All @@ -25,7 +27,7 @@ import (
"github.com/fabric8-services/fabric8-auth/sentry"

"github.com/goadesign/goa"
"github.com/goadesign/goa/logging/logrus"
goalogrus "github.com/goadesign/goa/logging/logrus"
"github.com/goadesign/goa/middleware"
"github.com/goadesign/goa/middleware/gzip"
"github.com/goadesign/goa/middleware/security/jwt"
Expand Down Expand Up @@ -156,7 +158,7 @@ func main() {
service.Use(log.LogRequest(config.IsPostgresDeveloperModeEnabled()))
app.UseJWTMiddleware(service, jwt.New(tokenManager.PublicKeys(), nil, app.NewJWTSecurity()))

var tenantService accountservice.TenantService
var tenantService appservice.TenantService
if config.GetTenantServiceURL() != "" {
log.Logger().Infof("Enabling Tenant service %v", config.GetTenantServiceURL())
tenantService = accountservice.NewTenantService(config)
Expand Down
2 changes: 2 additions & 0 deletions test/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/url"
"testing"

"github.com/fabric8-services/fabric8-auth/log"
"github.com/fabric8-services/fabric8-auth/rest"

"github.com/stretchr/testify/assert"
Expand All @@ -23,6 +24,7 @@ type DummyHttpDoer struct {
}

func (c *DummyHttpClient) Do(req *http.Request) (*http.Response, error) {
log.Debug(nil, map[string]interface{}{"headers": req.Header}, "sending request with dummy HTTP client")
if c.AssertRequest != nil {
c.AssertRequest(req)
}
Expand Down
Loading

0 comments on commit 660a631

Please sign in to comment.