From a0043c6cc7101a913bfbfdacef198e0415d09f10 Mon Sep 17 00:00:00 2001 From: nathanmartinszup <63246935+nathanmartinszup@users.noreply.github.com> Date: Thu, 15 Jul 2021 16:19:02 -0300 Subject: [PATCH] hotifx/get-workspace-repository-ldap (#127) * Fixing error in get repository and workspace when ldap auth type Signed-off-by: nathanmartinszup * Adding unity tests Signed-off-by: nathanmartinszup --- .../controllers/repository/repository.go | 4 +++ .../controllers/repository/repository_test.go | 36 +++++++++++++++++-- .../controllers/workspace/workspace.go | 4 +++ .../controllers/workspace/workspace_test.go | 31 +++++++++++++--- .../repositories/repository/repository.go | 24 +++++++++++++ .../repository/repository_mock.go | 5 +++ .../repository/repository_test.go | 16 +++++++++ .../repositories/workspace/workspace.go | 23 ++++++++++++ .../repositories/workspace/workspace_mock.go | 5 +++ .../repositories/workspace/workspace_test.go | 14 ++++++++ 10 files changed, 155 insertions(+), 7 deletions(-) diff --git a/core/internal/controllers/repository/repository.go b/core/internal/controllers/repository/repository.go index a98fce1f9..ee7168629 100644 --- a/core/internal/controllers/repository/repository.go +++ b/core/internal/controllers/repository/repository.go @@ -114,6 +114,10 @@ func (c *Controller) Get(data *repositoryEntities.Data) (*repositoryEntities.Res return c.getRepositoryWhenAdmin(data, accountEnums.ApplicationAdmin) } + if c.appConfig.GetAuthenticationType() == auth.Ldap { + return c.repository.GetRepositoryLdap(data.RepositoryID, data.Permissions) + } + if c.workspaceRepository.IsWorkspaceAdmin(data.AccountID, data.WorkspaceID) { return c.getRepositoryWhenAdmin(data, accountEnums.Admin) } diff --git a/core/internal/controllers/repository/repository_test.go b/core/internal/controllers/repository/repository_test.go index d8fe60e67..6778914cf 100644 --- a/core/internal/controllers/repository/repository_test.go +++ b/core/internal/controllers/repository/repository_test.go @@ -224,6 +224,8 @@ func TestGet(t *testing.T) { } t.Run("should success get a repository", func(t *testing.T) { + databaseMock := &database.Mock{} + workspaceRepositoryMock := &workspaceRepository.Mock{} workspaceRepositoryMock.On("IsWorkspaceAdmin").Return(false) @@ -231,8 +233,30 @@ func TestGet(t *testing.T) { repositoryMock.On("GetRepository").Return(&repositoryEntities.Repository{}, nil) repositoryMock.On("GetAccountRepository").Return(&repositoryEntities.AccountRepository{}, nil) + appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) + + databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} + controller := NewRepositoryController(&broker.Mock{}, databaseConnection, appConfig, + repositoryUseCases.NewRepositoryUseCases(), repositoryMock, &tokenUseCases.UseCases{}, + workspaceRepositoryMock) + + result, err := controller.Get(data) + assert.NoError(t, err) + assert.NotNil(t, result) + }) + + t.Run("should success get a repository auth type ldap", func(t *testing.T) { databaseMock := &database.Mock{} + + workspaceRepositoryMock := &workspaceRepository.Mock{} + workspaceRepositoryMock.On("IsWorkspaceAdmin").Return(false) + + repositoryMock := &repositoryRepository.Mock{} + repositoryMock.On("GetRepositoryLdap").Return(&repositoryEntities.Response{}, nil) + appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Ldap) databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} controller := NewRepositoryController(&broker.Mock{}, databaseConnection, appConfig, @@ -245,6 +269,8 @@ func TestGet(t *testing.T) { }) t.Run("should return error when failed to get repository", func(t *testing.T) { + databaseMock := &database.Mock{} + workspaceRepositoryMock := &workspaceRepository.Mock{} workspaceRepositoryMock.On("IsWorkspaceAdmin").Return(false) @@ -252,8 +278,8 @@ func TestGet(t *testing.T) { repositoryMock.On("GetRepository").Return(&repositoryEntities.Repository{}, errors.New("test")) repositoryMock.On("GetAccountRepository").Return(&repositoryEntities.AccountRepository{}, nil) - databaseMock := &database.Mock{} appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} controller := NewRepositoryController(&broker.Mock{}, databaseConnection, appConfig, @@ -265,6 +291,8 @@ func TestGet(t *testing.T) { }) t.Run("should return error when failed to get account repository", func(t *testing.T) { + databaseMock := &database.Mock{} + workspaceRepositoryMock := &workspaceRepository.Mock{} workspaceRepositoryMock.On("IsWorkspaceAdmin").Return(false) @@ -272,8 +300,8 @@ func TestGet(t *testing.T) { repositoryMock.On("GetAccountRepository").Return( &repositoryEntities.AccountRepository{}, errors.New("test")) - databaseMock := &database.Mock{} appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} controller := NewRepositoryController(&broker.Mock{}, databaseConnection, appConfig, @@ -324,7 +352,9 @@ func TestGet(t *testing.T) { t.Run("should success get a repository when workspace admin", func(t *testing.T) { databaseMock := &database.Mock{} + appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) workspaceRepositoryMock := &workspaceRepository.Mock{} workspaceRepositoryMock.On("IsWorkspaceAdmin").Return(true) @@ -345,7 +375,9 @@ func TestGet(t *testing.T) { t.Run("should return error when failed to get repository and user is workspace admin", func(t *testing.T) { databaseMock := &database.Mock{} + appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) workspaceRepositoryMock := &workspaceRepository.Mock{} workspaceRepositoryMock.On("IsWorkspaceAdmin").Return(true) diff --git a/core/internal/controllers/workspace/workspace.go b/core/internal/controllers/workspace/workspace.go index f9acbfae5..25080b954 100644 --- a/core/internal/controllers/workspace/workspace.go +++ b/core/internal/controllers/workspace/workspace.go @@ -98,6 +98,10 @@ func (c *Controller) Get(data *workspaceEntities.Data) (*workspaceEntities.Respo return c.getWorkspaceWhenAppAdmin(data) } + if c.appConfig.GetAuthenticationType() == auth.Ldap { + return c.repository.GetWorkspaceLdap(data.WorkspaceID, data.Permissions) + } + return c.getWorkspace(data) } diff --git a/core/internal/controllers/workspace/workspace_test.go b/core/internal/controllers/workspace/workspace_test.go index b8525a48e..b867ac1be 100644 --- a/core/internal/controllers/workspace/workspace_test.go +++ b/core/internal/controllers/workspace/workspace_test.go @@ -146,13 +146,32 @@ func TestGet(t *testing.T) { } t.Run("should success get workspace with role", func(t *testing.T) { - repositoryMock := &workspaceRepository.Mock{} + databaseMock := &database.Mock{} + repositoryMock := &workspaceRepository.Mock{} repositoryMock.On("GetAccountWorkspace").Return(accountWorkspace, nil) repositoryMock.On("GetWorkspace").Return(workspace, nil) + appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) + + databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} + controller := NewWorkspaceController(&broker.Broker{}, databaseConnection, appConfig, + workspaceUseCases.NewWorkspaceUseCases(), repositoryMock, tokenUseCases.NewTokenUseCases()) + + result, err := controller.Get(workspaceData) + assert.NoError(t, err) + assert.NotNil(t, result) + }) + + t.Run("should success get workspace with auth type ldap", func(t *testing.T) { databaseMock := &database.Mock{} + + repositoryMock := &workspaceRepository.Mock{} + repositoryMock.On("GetWorkspaceLdap").Return(&workspaceEntities.Response{}, nil) + appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Ldap) databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} controller := NewWorkspaceController(&broker.Broker{}, databaseConnection, appConfig, @@ -164,13 +183,14 @@ func TestGet(t *testing.T) { }) t.Run("should return error when failed to get workspace", func(t *testing.T) { - repositoryMock := &workspaceRepository.Mock{} + databaseMock := &database.Mock{} + repositoryMock := &workspaceRepository.Mock{} repositoryMock.On("GetAccountWorkspace").Return(accountWorkspace, nil) repositoryMock.On("GetWorkspace").Return(workspace, errors.New("test")) - databaseMock := &database.Mock{} appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} controller := NewWorkspaceController(&broker.Broker{}, databaseConnection, appConfig, @@ -182,12 +202,13 @@ func TestGet(t *testing.T) { }) t.Run("should return error when failed to get workspace", func(t *testing.T) { - repositoryMock := &workspaceRepository.Mock{} + databaseMock := &database.Mock{} + repositoryMock := &workspaceRepository.Mock{} repositoryMock.On("GetAccountWorkspace").Return(accountWorkspace, errors.New("test")) - databaseMock := &database.Mock{} appConfig := &app.Mock{} + appConfig.On("GetAuthenticationType").Return(auth.Horusec) databaseConnection := &database.Connection{Read: databaseMock, Write: databaseMock} controller := NewWorkspaceController(&broker.Broker{}, databaseConnection, appConfig, diff --git a/core/internal/repositories/repository/repository.go b/core/internal/repositories/repository/repository.go index 620572670..d4f241e60 100644 --- a/core/internal/repositories/repository/repository.go +++ b/core/internal/repositories/repository/repository.go @@ -41,6 +41,7 @@ type IRepository interface { ListAllRepositoryUsers(repositoryID uuid.UUID) (*[]roleEntities.Response, error) GetWorkspace(workspaceID uuid.UUID) (*workspaceEntities.Workspace, error) ListRepositoriesWhenApplicationAdmin() (*[]repositoryEntities.Response, error) + GetRepositoryLdap(repositoryID uuid.UUID, permissions []string) (*repositoryEntities.Response, error) } type Repository struct { @@ -217,3 +218,26 @@ func (r *Repository) queryListRepositoriesWhenApplicationAdmin() string { FROM repositories AS repo ` } + +func (r *Repository) GetRepositoryLdap( + repositoryID uuid.UUID, permissions []string) (*repositoryEntities.Response, error) { + repository := &repositoryEntities.Response{} + + return repository, r.databaseRead.Raw(r.queryGetRepositoryLdap(), repository, + sql.Named("permissions", pq.StringArray(permissions)), + sql.Named("repositoryID", repositoryID)).GetErrorExceptNotFound() +} + +func (r *Repository) queryGetRepositoryLdap() string { + return ` + SELECT repo.repository_id, repo.workspace_id, repo.description, repo.name, repo.created_at, repo.updated_at, + repo.authz_admin, repo.authz_supervisor, repo.authz_member, + CASE + WHEN @permissions @> repo.authz_admin THEN 'admin' + WHEN @permissions @> repo.authz_supervisor THEN 'supervisor' + ELSE 'member' + END AS role + FROM repositories AS repo + WHERE repository_id = @repositoryID + ` +} diff --git a/core/internal/repositories/repository/repository_mock.go b/core/internal/repositories/repository/repository_mock.go index ba4326c56..de507df73 100644 --- a/core/internal/repositories/repository/repository_mock.go +++ b/core/internal/repositories/repository/repository_mock.go @@ -73,3 +73,8 @@ func (m *Mock) ListRepositoriesWhenApplicationAdmin() (*[]repositoryEntities.Res args := m.MethodCalled("ListRepositoriesWhenApplicationAdmin") return args.Get(0).(*[]repositoryEntities.Response), mockUtils.ReturnNilOrError(args, 1) } + +func (m *Mock) GetRepositoryLdap(_ uuid.UUID, _ []string) (*repositoryEntities.Response, error) { + args := m.MethodCalled("GetRepositoryLdap") + return args.Get(0).(*repositoryEntities.Response), mockUtils.ReturnNilOrError(args, 1) +} diff --git a/core/internal/repositories/repository/repository_test.go b/core/internal/repositories/repository/repository_test.go index 5fd5b0d88..6dcdbb9f8 100644 --- a/core/internal/repositories/repository/repository_test.go +++ b/core/internal/repositories/repository/repository_test.go @@ -220,3 +220,19 @@ func TestListRepositoriesWhenApplicationAdmin(t *testing.T) { assert.NotNil(t, result) }) } + +func TestGetRepositoryLdap(t *testing.T) { + t.Run("should success get repository", func(t *testing.T) { + workspaceRepositoryMock := &workspaceRepository.Mock{} + + databaseMock := &database.Mock{} + databaseMock.On("Raw").Return(&response.Response{}) + + repository := NewRepositoryRepository(&database.Connection{Read: databaseMock, Write: databaseMock}, + repositoryUseCases.NewRepositoryUseCases(), workspaceRepositoryMock) + + result, err := repository.GetRepositoryLdap(uuid.New(), []string{""}) + assert.NoError(t, err) + assert.NotNil(t, result) + }) +} diff --git a/core/internal/repositories/workspace/workspace.go b/core/internal/repositories/workspace/workspace.go index fff75e2d7..560b46935 100644 --- a/core/internal/repositories/workspace/workspace.go +++ b/core/internal/repositories/workspace/workspace.go @@ -37,6 +37,7 @@ type IRepository interface { ListAllWorkspaceUsers(workspaceID uuid.UUID) (*[]roleEntities.Response, error) ListWorkspacesApplicationAdmin() (*[]workspaceEntities.Response, error) IsWorkspaceAdmin(accountID, workspaceID uuid.UUID) bool + GetWorkspaceLdap(workspaceID uuid.UUID, permissions []string) (*workspaceEntities.Response, error) } type Repository struct { @@ -155,3 +156,25 @@ func (r *Repository) IsWorkspaceAdmin(accountID, workspaceID uuid.UUID) bool { return response.GetError() == nil && accountWorkspace.Role == accountEnums.Admin } + +func (r *Repository) GetWorkspaceLdap( + workspaceID uuid.UUID, permissions []string) (*workspaceEntities.Response, error) { + workspace := &workspaceEntities.Response{} + + return workspace, r.databaseRead.Raw(r.queryGetWorkspaceLdap(), workspace, + sql.Named("permissions", pq.StringArray(permissions)), + sql.Named("workspaceID", workspaceID)).GetErrorExceptNotFound() +} + +func (r *Repository) queryGetWorkspaceLdap() string { + return ` + SELECT ws.workspace_id, ws.name, ws.description, ws.created_at, ws.updated_at, + ws.authz_admin, ws.authz_member, + CASE + WHEN @permissions @> ws.authz_admin THEN 'admin' + ELSE 'member' + END AS role + FROM workspaces as ws + WHERE workspace_id = @workspaceID + ` +} diff --git a/core/internal/repositories/workspace/workspace_mock.go b/core/internal/repositories/workspace/workspace_mock.go index 2e8e80a20..bb0d61d69 100644 --- a/core/internal/repositories/workspace/workspace_mock.go +++ b/core/internal/repositories/workspace/workspace_mock.go @@ -62,3 +62,8 @@ func (m *Mock) IsWorkspaceAdmin(_, _ uuid.UUID) bool { args := m.MethodCalled("IsWorkspaceAdmin") return args.Get(0).(bool) } + +func (m *Mock) GetWorkspaceLdap(_ uuid.UUID, _ []string) (*workspaceEntities.Response, error) { + args := m.MethodCalled("GetWorkspaceLdap") + return args.Get(0).(*workspaceEntities.Response), mockUtils.ReturnNilOrError(args, 1) +} diff --git a/core/internal/repositories/workspace/workspace_test.go b/core/internal/repositories/workspace/workspace_test.go index 4f5063a43..627dde821 100644 --- a/core/internal/repositories/workspace/workspace_test.go +++ b/core/internal/repositories/workspace/workspace_test.go @@ -138,3 +138,17 @@ func TestIsWorkspaceAdmin(t *testing.T) { assert.False(t, repository.IsWorkspaceAdmin(uuid.New(), uuid.New())) }) } + +func TestGetWorkspaceLdap(t *testing.T) { + t.Run("should success get workspace", func(t *testing.T) { + databaseMock := &database.Mock{} + databaseMock.On("Raw").Return(&response.Response{}) + + repository := NewWorkspaceRepository(&database.Connection{Read: databaseMock, Write: databaseMock}, + workspaceUseCases.NewWorkspaceUseCases()) + + result, err := repository.GetWorkspaceLdap(uuid.New(), []string{}) + assert.NoError(t, err) + assert.NotNil(t, result) + }) +}