Skip to content

Commit

Permalink
feat: add list roles and permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
ochom authored and Muchogoc committed Jul 30, 2021
1 parent 12712f7 commit 55d4716
Show file tree
Hide file tree
Showing 13 changed files with 951 additions and 308 deletions.
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -25,7 +25,7 @@ require (
github.com/savannahghi/feedlib v0.0.1
github.com/savannahghi/firebasetools v0.0.13
github.com/savannahghi/interserviceclient v0.0.13
github.com/savannahghi/profileutils v0.0.13
github.com/savannahghi/profileutils v0.0.15
github.com/savannahghi/pubsubtools v0.0.2
github.com/savannahghi/scalarutils v0.0.2
github.com/savannahghi/serverutils v0.0.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -388,8 +388,8 @@ github.com/savannahghi/interserviceclient v0.0.13 h1:hKUrWkUQW7mNZLp/wxJNnzORDpN
github.com/savannahghi/interserviceclient v0.0.13/go.mod h1:aGGEc+40bBVHVDs1k0CzK5uPb5080vv4fb25T/cuXQk=
github.com/savannahghi/profileutils v0.0.6/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/profileutils v0.0.7/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/profileutils v0.0.13 h1:qAGoINpVBVxH02Tbn22vQlo5nRpiYBBYeBor6vEdyEI=
github.com/savannahghi/profileutils v0.0.13/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/profileutils v0.0.15 h1:H05wdnrKzPm5RyaLvSMDI18JJU0hOF/QfNcCUBtsirc=
github.com/savannahghi/profileutils v0.0.15/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/pubsubtools v0.0.2 h1:5JqgynuuzduYu57y8TM0bU8unZD/7ob36sZ9BKPmt9o=
github.com/savannahghi/pubsubtools v0.0.2/go.mod h1:FQ+BxO4uA1ZkcziY4dR0uT9CKHVHb+4L1lUURBV2UD0=
github.com/savannahghi/scalarutils v0.0.0-20210622091443-bad5089abdad/go.mod h1:Z+Dl3wc3vy5zKvthctHAtYzol1p8w27zEVRfOYueoks=
Expand Down
61 changes: 59 additions & 2 deletions pkg/onboarding/infrastructure/database/fb/firebase.go
Expand Up @@ -3716,6 +3716,37 @@ func (fr *Repository) CreateRole(
return &role, nil
}

// GetAllRoles returns a list of all created roles
func (fr *Repository) GetAllRoles(ctx context.Context) (*[]profileutils.Role, error) {
ctx, span := tracer.Start(ctx, "GetAllRoles")
defer span.End()

query := &GetAllQuery{
CollectionName: fr.GetRolesCollectionName(),
}

docs, err := fr.FirestoreClient.GetAll(ctx, query)
if err != nil {
utils.RecordSpanError(span, err)
return nil, exceptions.InternalServerError(err)
}

roles := []profileutils.Role{}
for _, doc := range docs {
role := &profileutils.Role{}

err = doc.DataTo(role)
if err != nil {
utils.RecordSpanError(span, err)
err = fmt.Errorf("unable to read role")
return nil, exceptions.InternalServerError(err)
}
roles = append(roles, *role)
}

return &roles, nil
}

// UpdateRoleDetails updates the details of a role
func (fr *Repository) UpdateRoleDetails(
ctx context.Context,
Expand Down Expand Up @@ -3790,7 +3821,7 @@ func (fr *Repository) GetRoleByID(ctx context.Context, roleID string) (*profileu
return nil, err
}

role := &profileutils.Role{}
role := profileutils.Role{}

err = docs[0].DataTo(role)
if err != nil {
Expand All @@ -3799,7 +3830,7 @@ func (fr *Repository) GetRoleByID(ctx context.Context, roleID string) (*profileu
return nil, exceptions.InternalServerError(err)
}

return role, nil
return &role, nil
}

// GetRolesByIDs gets all roles matching provided roleIDs if specified otherwise all roles
Expand Down Expand Up @@ -3847,3 +3878,29 @@ func (fr *Repository) CheckIfRoleNameExists(ctx context.Context, name string) (b

return false, nil
}

//CheckIfUserHasPermission this method checks if a user has the required permission
func (fr *Repository) CheckIfUserHasPermission(ctx context.Context, UID string, requiredPermission profileutils.Permission) (bool, error) {
ctx, span := tracer.Start(ctx, "CheckIfUserHasPermission")
defer span.End()

userprofile, err := fr.GetUserProfileByUID(ctx, UID, false)
if err != nil {
utils.RecordSpanError(span, err)
return false, err
}

roles, err := fr.GetRolesByIDs(ctx, userprofile.Roles)
if err != nil {
utils.RecordSpanError(span, err)
return false, err
}

for _, role := range *roles {
if role.HasPermission(ctx, requiredPermission.Scope) {
return true, nil
}
}

return false, nil
}
26 changes: 21 additions & 5 deletions pkg/onboarding/infrastructure/database/fb/firebase_extension.go
Expand Up @@ -65,12 +65,28 @@ type DeleteCommand struct {
// GetAll retrieve a value from the store
func (f *FirestoreClientExtensionImpl) GetAll(ctx context.Context, getQuery *GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
collection := f.client.Collection(getQuery.CollectionName)
query := collection.Where(getQuery.FieldName, getQuery.Operator, getQuery.Value)
docs, err := query.Documents(ctx).GetAll()
if err != nil {
return nil, exceptions.InternalServerError(err)

var documents []*firestore.DocumentSnapshot

if getQuery.FieldName == "" && getQuery.Operator == "" && getQuery.Value == nil {
docs, err := collection.Documents(ctx).GetAll()
if err != nil {
return nil, exceptions.InternalServerError(err)
}

documents = docs

} else {
query := collection.Where(getQuery.FieldName, getQuery.Operator, getQuery.Value)
docs, err := query.Documents(ctx).GetAll()
if err != nil {
return nil, exceptions.InternalServerError(err)
}

documents = docs
}
return docs, nil

return documents, nil
}

// Create persists data to a firestore collection
Expand Down
168 changes: 167 additions & 1 deletion pkg/onboarding/infrastructure/database/fb/firebase_test.go
Expand Up @@ -25,7 +25,6 @@ import (

var fakeFireBaseClientExt extMock.FirebaseClientExtension
var fireBaseClientExt fb.FirebaseClientExtension = &fakeFireBaseClientExt

var fakeFireStoreClientExt extMock.FirestoreClientExtension

func TestRepository_UpdateUserName(t *testing.T) {
Expand Down Expand Up @@ -1775,3 +1774,170 @@ func TestRepository_GetRolesByIDs(t *testing.T) {
})
}
}

func TestRepository_GetAllRoles(t *testing.T) {
ctx := context.Background()
var fireStoreClientExt fb.FirestoreClientExtension = &fakeFireStoreClientExt
repo := fb.NewFirebaseRepository(fireStoreClientExt, fireBaseClientExt)

type args struct {
ctx context.Context
}
tests := []struct {
name string
args args
want *[]profileutils.Role
wantErr bool
}{
{
name: "fail: cannot retrieve firestore docs",
args: args{
ctx: ctx,
},
want: nil,
wantErr: true,
},
{
name: "success: retrieved roles",
args: args{
ctx: ctx,
},
want: &[]profileutils.Role{
{
ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f",
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.name == "fail: cannot retrieve firestore docs" {
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {

return nil, fmt.Errorf("cannot retrieve firestore docs")
}
}

if tt.name == "success: retrieved roles" {
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
docRef := &firestore.DocumentRef{ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f"}
docs := []*firestore.DocumentSnapshot{{Ref: docRef}}
return docs, nil
}
}

got, err := repo.GetAllRoles(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("Repository.GetAllRoles() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Repository.GetAllRoles() = %v, want %v", got, tt.want)
}
})
}
}

func TestRepository_CheckIfUserHasPermission(t *testing.T) {
ctx := context.Background()
var fireStoreClientExt fb.FirestoreClientExtension = &fakeFireStoreClientExt
repo := fb.NewFirebaseRepository(fireStoreClientExt, fireBaseClientExt)

type args struct {
ctx context.Context
UID string
requiredPermission profileutils.Permission
}
input := args{
ctx: ctx,
UID: uuid.NewString(),
requiredPermission: profileutils.CanAssignRole,
}
tests := []struct {
name string
args args
want bool
wantErr bool
}{
{
name: "sad unable to get user profile",
args: input,
want: false,
wantErr: true,
},
{
name: "sad unable to get roles by ids",
args: input,
want: false,
wantErr: true,
},
{
name: "sad required permission not among user roles",
args: input,
want: false,
wantErr: true,
},
{
name: "happy user has permission",
args: input,
want: true,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.name == "sad unable to get user profile" {
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
return nil, fmt.Errorf("unable to get userprofile by uid")
}
}
if tt.name == "sad unable to get roles by ids" {
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
docRef := &firestore.DocumentRef{ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f"}
docs := []*firestore.DocumentSnapshot{{Ref: docRef}}
return docs, nil
}
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
return nil, fmt.Errorf("unable to get userprofile by uid")
}
}
if tt.name == "sad required permission not among user roles" {
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
docRef := &firestore.DocumentRef{ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f"}
docs := []*firestore.DocumentSnapshot{{Ref: docRef}}
return docs, nil
}
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
docRef := &firestore.DocumentRef{
ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f",
}
docs := []*firestore.DocumentSnapshot{{Ref: docRef}}
return docs, nil
}
}
if tt.name == "happy user has permission" {
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
docRef := &firestore.DocumentRef{ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f"}
docs := []*firestore.DocumentSnapshot{{Ref: docRef}}
return docs, nil
}
fakeFireStoreClientExt.GetAllFn = func(ctx context.Context, query *fb.GetAllQuery) ([]*firestore.DocumentSnapshot, error) {
docRef := &firestore.DocumentRef{
ID: "c9d62c7e-93e5-44a6-b503-6fc159c1782f",
}
docs := []*firestore.DocumentSnapshot{{Ref: docRef}}
return docs, nil
}
}
got, err := repo.CheckIfUserHasPermission(tt.args.ctx, tt.args.UID, tt.args.requiredPermission)
if (err != nil) != tt.wantErr {
t.Errorf("Repository.CheckIfUserHasPermission() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("Repository.CheckIfUserHasPermission() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 55d4716

Please sign in to comment.