Skip to content

Commit

Permalink
feat: implement roles
Browse files Browse the repository at this point in the history
Signed-off-by: maxwellgithinji <maxwellgithinji@gmail.com>
  • Loading branch information
maxwellgithinji committed Oct 26, 2021
1 parent d4648c5 commit 7320fb5
Show file tree
Hide file tree
Showing 16 changed files with 383 additions and 12 deletions.
4 changes: 2 additions & 2 deletions pkg/onboarding/application/dto/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ type StaffProfileInput struct {
// TODO: the list of facilities to switch between is strictly those that the user is assigned to
DefaultFacilityID *string `json:"defaultFacilityID"`

// // there is nothing special about super-admin; just the set of roles they have
// Roles []domain.RoleType `json:"roles"` // TODO: roles are an enum (controlled list), known to both FE and BE
// there is nothing special about super-admin; just the set of roles they have
Roles []enums.RolesType `json:"roles"` // TODO: roles are an enum (controlled list), known to both FE and BE

Addresses []*AddressesInput `json:"addresses"`
}
Expand Down
82 changes: 82 additions & 0 deletions pkg/onboarding/application/enums/role_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package enums

import (
"fmt"
)

// RolesType is a list of all the role types.
type RolesType string

// contacts type constants
const (
RolesTypeCanRegisterStaff RolesType = "CAN_REGISTER_STAFF"
RolesTypeCanInviteStaff RolesType = "CAN_INVITE_STAFF"
RolesTypeCanSuspendStaff RolesType = "CAN_SUSPEND_STAFF"
RolesTypeCanActivateStaff RolesType = "CAN_ACTIVATE_STAFF"
RolesTypeCanDeleteStaff RolesType = "CAN_DELETE_STAFF"
RolesTypeCanInactivateStaff RolesType = "CAN_INACTIVATE_STAFF"

RolesTypeCanRegisterClient RolesType = "CAN_REGISTER_CLIENT"
RolesTypeCanInviteClient RolesType = "CAN_INVITE_CLIENT"
RolesTypeCanSuspendClient RolesType = "CAN_SUSPEND_CLIENT"
RolesTypeCanActivateClient RolesType = "CAN_ACTIVATE_CLIENT"
RolesTypeCanDeleteClient RolesType = "CAN_DELETE_CLIENT"
RolesTypeCanInactivateClient RolesType = "CAN_INACTIVATE_CLIENT"
)

// AllRoles is a set of a valid and known role types.
var AllRoles = []RolesType{
RolesTypeCanRegisterStaff,
RolesTypeCanInviteStaff,
RolesTypeCanSuspendStaff,
RolesTypeCanActivateStaff,
RolesTypeCanDeleteStaff,
RolesTypeCanInactivateStaff,

RolesTypeCanRegisterClient,
RolesTypeCanInviteClient,
RolesTypeCanSuspendClient,
RolesTypeCanActivateClient,
RolesTypeCanDeleteClient,
RolesTypeCanInactivateClient,
}

// IsValid returns true if a role is valid
func (m RolesType) IsValid() bool {
switch m {
case RolesTypeCanRegisterStaff,
RolesTypeCanInviteStaff,
RolesTypeCanSuspendStaff,
RolesTypeCanActivateStaff,
RolesTypeCanDeleteStaff,
RolesTypeCanInactivateStaff,

RolesTypeCanRegisterClient,
RolesTypeCanInviteClient,
RolesTypeCanSuspendClient,
RolesTypeCanActivateClient,
RolesTypeCanDeleteClient,
RolesTypeCanInactivateClient:
return true
}
return false
}

// String converts roles to string.
func (m RolesType) String() string {
return string(m)
}

// UnmarshalGQL converts the supplied value to a role type.
func (m *RolesType) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}

*m = RolesType(str)
if !m.IsValid() {
return fmt.Errorf("%s is not a valid RolesType", str)
}
return nil
}
2 changes: 1 addition & 1 deletion pkg/onboarding/domain/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ type StaffProfile struct {
DefaultFacilityID *string

// there is nothing special about super-admin; just the set of roles they have
Roles []string // TODO: roles are an enum (controlled list), known to both FE and BE
Roles []enums.RolesType // TODO: roles are an enum (controlled list), known to both FE and BE

Addresses []*Addresses
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ func NewGormMock() *GormMock {
RegisterStaffUserFn: func(ctx context.Context, user *gorm.User, staff *gorm.StaffProfile) (*gorm.StaffUserProfile, error) {
ID := uuid.New().String()
testTime := time.Now()
roles := []string{enums.RolesTypeCanInviteClient.String()}
languages := []string{string(enumutils.LanguageEn)}
return &gorm.StaffUserProfile{
User: &gorm.User{
UserID: &ID,
Expand All @@ -239,6 +241,7 @@ func NewGormMock() *GormMock {
FailedLoginCount: "0",
TermsAccepted: true,
AcceptedTermsID: ID,
Languages: languages,
},
Staff: &gorm.StaffProfile{
StaffProfileID: &ID,
Expand All @@ -256,6 +259,7 @@ func NewGormMock() *GormMock {
Active: true,
},
},
Roles: roles,
},
}, nil
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ type StaffProfile struct {
DefaultFacilityID *string `gorm:"column:default_facility_id"` // TODO: required, FK to facility
Facility Facility `gorm:"foreignKey:default_facility_id;references:facility_id;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`

// // there is nothing special about super-admin; just the set of roles they have
// Roles []string `gorm:"type:text[];column:roles"` // TODO: roles are an enum (controlled list), known to both FE and BE
// there is nothing special about super-admin; just the set of roles they have
Roles pq.StringArray `gorm:"type:text[];column:roles"` // TODO: roles are an enum (controlled list), known to both FE and BE

Addresses []*Addresses `gorm:"ForeignKey:StaffProfileID"`
}
Expand Down
11 changes: 9 additions & 2 deletions pkg/onboarding/infrastructure/database/postgres/mappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"strconv"

"github.com/savannahghi/enumutils"
"github.com/savannahghi/onboarding-service/pkg/onboarding/application/enums"
"github.com/savannahghi/onboarding-service/pkg/onboarding/domain"
"github.com/savannahghi/onboarding-service/pkg/onboarding/infrastructure/database/postgres/gorm"
)
Expand Down Expand Up @@ -115,14 +116,20 @@ func (d *OnboardingDb) mapRegisterStaffObjectToDomain(userStaffObject *gorm.Staf
addresses = append(addresses, address)
}

roles := []enums.RolesType{}
for _, r := range staffObject.Roles {
roles = append(roles, enums.RolesType(r))

}

staffProfile := &domain.StaffProfile{
ID: staffObject.StaffProfileID,
UserID: userObject.UserID,
StaffNumber: staffObject.StaffNumber,
// Facilities: staffObject.Facilities,
DefaultFacilityID: staffObject.DefaultFacilityID,
// Roles: staffObject.Roles,
Addresses: addresses,
Addresses: addresses,
Roles: roles,
}
return &domain.StaffUserProfile{
User: user,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ func NewPostgresMock() *PostgresMock {
RegisterStaffUserFn: func(ctx context.Context, user *dto.UserInput, staff *dto.StaffProfileInput) (*domain.StaffUserProfile, error) {
ID := uuid.New().String()
testTime := time.Now()
roles := []enums.RolesType{enums.RolesTypeCanInviteClient}
languages := []enumutils.Language{enumutils.LanguageEn}
return &domain.StaffUserProfile{
User: &domain.User{
ID: &ID,
Expand All @@ -162,6 +164,7 @@ func NewPostgresMock() *PostgresMock {
FailedLoginCount: "0",
TermsAccepted: true,
AcceptedTermsID: ID,
Languages: languages,
},
Staff: &domain.StaffProfile{
ID: &ID,
Expand All @@ -179,6 +182,7 @@ func NewPostgresMock() *PostgresMock {
Active: true,
},
},
Roles: roles,
},
}, nil
},
Expand Down
10 changes: 10 additions & 0 deletions pkg/onboarding/infrastructure/database/postgres/pg_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,20 @@ func (d *OnboardingDb) RegisterStaffUser(ctx context.Context, user *dto.UserInpu
}
}

roles := []string{}
for _, r := range staff.Roles {
if !r.IsValid() {
return nil, fmt.Errorf("role %s is not valid", r)
}

roles = append(roles, r.String())
}

staffObject := &gorm.StaffProfile{
StaffNumber: staff.StaffNumber,
DefaultFacilityID: staff.DefaultFacilityID,
Addresses: addresses,
Roles: roles,
}

userStaffProfile, err := d.create.RegisterStaffUser(ctx, userObject, staffObject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ func TestOnboardingDb_RegisterStaffUser(t *testing.T) {
testUserID := uuid.New().String()
testTime := time.Now()
testID := uuid.New().String()
rolesInput := []enums.RolesType{enums.RolesTypeCanInviteClient}

type args struct {
ctx context.Context
Expand Down Expand Up @@ -283,6 +284,7 @@ func TestOnboardingDb_RegisterStaffUser(t *testing.T) {
Active: true,
},
},
Roles: rolesInput,
}
staffNoFacilityIDInput := &dto.StaffProfileInput{
StaffNumber: "s123",
Expand Down Expand Up @@ -375,6 +377,7 @@ func TestOnboardingDb_RegisterStaffUser(t *testing.T) {
Active: true,
},
},
Roles: []string{enums.RolesTypeCanInviteClient.String()},
},
}, nil
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/onboarding/presentation/graph/enums.graphql
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
enum RolesType {
CAN_REGISTER_STAFF
CAN_INVITE_STAFF
CAN_SUSPEND_STAFF
CAN_ACTIVATE_STAFF
CAN_DELETE_STAFF
CAN_INACTIVATE_STAFF

CAN_REGISTER_CLIENT
CAN_INVITE_CLIENT
CAN_SUSPEND_CLIENT
CAN_ACTIVATE_CLIENT
CAN_DELETE_CLIENT
CAN_INACTIVATE_CLIENT
}

enum ClientType {
PMTCT
OVC
Expand Down

0 comments on commit 7320fb5

Please sign in to comment.