add SetPrincipalRoles and principalsToSet

pull/165/head
Jim Lambert 6 years ago
parent a4580fda15
commit 457ad3cb08

@ -110,14 +110,12 @@ func (r *Repository) AddPrincipalRoles(ctx context.Context, roleId string, roleV
return principalRoles, nil
}
// SetPrincipalRoles will set the role's principals
// SetPrincipalRoles will set the role's principals. If both userIds and
// groupIds are empty, the principal roles will be cleared.
func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleVersion int, userIds, groupIds []string, opt ...Option) ([]PrincipalRole, int, error) {
if roleId == "" {
return nil, db.NoRowsAffected, fmt.Errorf("set principal roles: missing role id: %w", db.ErrInvalidParameter)
}
if len(userIds) == 0 && len(groupIds) == 0 {
return nil, db.NoRowsAffected, fmt.Errorf("set principal roles: missing either user or groups to delete %w", db.ErrInvalidParameter)
}
role := allocRole()
role.PublicId = roleId
scope, err := role.GetScope(ctx, r.reader)
@ -159,7 +157,7 @@ func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleV
// we need a roleTicket, which won't be redeemed until all the other
// writes are successful. We can't just use a single ticket because
// we need to write oplog entries for deletes and adds
roleTicket, err := w.GetTicket(role)
roleTicket, err := w.GetTicket(&role)
if err != nil {
return fmt.Errorf("set principal roles: unable to get ticket for role: %w", err)
}
@ -231,6 +229,7 @@ func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleV
if err := w.CreateItems(ctx, toSet.addUserRoles, db.NewOplogMsgs(&userOplogMsgs)); err != nil {
return fmt.Errorf("set principal roles: unable to add users: %w", err)
}
totalRowsAffected += len(toSet.addUserRoles)
msgs = append(msgs, userOplogMsgs...)
}
if len(toSet.addGroupRoles) > 0 {
@ -238,6 +237,7 @@ func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleV
if err := w.CreateItems(ctx, toSet.addGroupRoles, db.NewOplogMsgs(&grpOplogMsgs)); err != nil {
return fmt.Errorf("set principal roles: unable to add groups: %w", err)
}
totalRowsAffected += len(toSet.addGroupRoles)
msgs = append(msgs, grpOplogMsgs...)
}
metadata := oplog.Metadata{
@ -275,85 +275,6 @@ func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleV
return currentPrincipals, totalRowsAffected, nil
}
type principalSet struct {
addUserRoles []interface{}
addGroupRoles []interface{}
deleteUserRoles []interface{}
deleteGroupRoles []interface{}
}
func (r *Repository) principalsToSet(ctx context.Context, role *Role, userIds, groupIds []string) (*principalSet, error) {
if role == nil {
return nil, fmt.Errorf("missing role %w", db.ErrNilParameter)
}
existing, err := r.ListPrincipalRoles(ctx, role.PublicId)
if err != nil {
return nil, fmt.Errorf("unable to list existing principal role %s: %w", role.PublicId, err)
}
existingUsers := map[string]PrincipalRole{}
existingGroups := map[string]PrincipalRole{}
for _, p := range existing {
switch p.GetType() {
case UserRoleType.String():
existingUsers[p.GetPrincipalId()] = p
case GroupRoleType.String():
existingGroups[p.GetPrincipalId()] = p
default:
return nil, fmt.Errorf("%s is unknown principal type %s", p.GetPrincipalId(), p.GetType())
}
}
var newUserRoles []interface{}
userIdsMap := map[string]struct{}{}
for _, id := range userIds {
userIdsMap[id] = struct{}{}
if _, ok := existingUsers[id]; !ok {
usrRole, err := NewUserRole(role.ScopeId, role.PublicId, id)
if err != nil {
return nil, fmt.Errorf("unable to create in memory user role for add: %w", err)
}
newUserRoles = append(newUserRoles, usrRole)
}
}
var newGrpRoles []interface{}
groupIdsMap := map[string]struct{}{}
for _, id := range groupIds {
groupIdsMap[id] = struct{}{}
if _, ok := existingGroups[id]; !ok {
grpRole, err := NewGroupRole(role.ScopeId, role.PublicId, id)
if err != nil {
return nil, fmt.Errorf("unable to create in memory group role for add: %w", err)
}
newGrpRoles = append(newGrpRoles, grpRole)
}
}
var deleteUserRoles []interface{}
for _, p := range existingUsers {
if _, ok := userIdsMap[p.GetPrincipalId()]; !ok {
usrRole, err := NewUserRole(p.GetScopeId(), p.GetRoleId(), p.GetPrincipalId())
if err != nil {
return nil, fmt.Errorf("unable to create in memory user role for delete: %w", err)
}
deleteUserRoles = append(deleteUserRoles, usrRole)
}
}
var deleteGrpRoles []interface{}
for _, p := range existingGroups {
if _, ok := groupIdsMap[p.GetPrincipalId()]; !ok {
grpRole, err := NewGroupRole(p.GetScopeId(), p.GetRoleId(), p.GetPrincipalId())
if err != nil {
return nil, fmt.Errorf("unable to create in memory group role for delete: %w", err)
}
deleteGrpRoles = append(deleteGrpRoles, grpRole)
}
}
return &principalSet{
addUserRoles: newUserRoles,
addGroupRoles: newGrpRoles,
deleteUserRoles: deleteUserRoles,
deleteGroupRoles: deleteGrpRoles,
}, nil
}
// DeletePrincipalRoles principals (userIds and/or groupIds) from a role
// (roleId). The role's current db version must match the roleVersion or an
// error will be returned.
@ -467,3 +388,82 @@ func (r *Repository) ListPrincipalRoles(ctx context.Context, roleId string, opt
}
return principals, nil
}
type principalSet struct {
addUserRoles []interface{}
addGroupRoles []interface{}
deleteUserRoles []interface{}
deleteGroupRoles []interface{}
}
func (r *Repository) principalsToSet(ctx context.Context, role *Role, userIds, groupIds []string) (*principalSet, error) {
if role == nil {
return nil, fmt.Errorf("missing role %w", db.ErrNilParameter)
}
existing, err := r.ListPrincipalRoles(ctx, role.PublicId)
if err != nil {
return nil, fmt.Errorf("unable to list existing principal role %s: %w", role.PublicId, err)
}
existingUsers := map[string]PrincipalRole{}
existingGroups := map[string]PrincipalRole{}
for _, p := range existing {
switch p.GetType() {
case UserRoleType.String():
existingUsers[p.GetPrincipalId()] = p
case GroupRoleType.String():
existingGroups[p.GetPrincipalId()] = p
default:
return nil, fmt.Errorf("%s is unknown principal type %s", p.GetPrincipalId(), p.GetType())
}
}
var newUserRoles []interface{}
userIdsMap := map[string]struct{}{}
for _, id := range userIds {
userIdsMap[id] = struct{}{}
if _, ok := existingUsers[id]; !ok {
usrRole, err := NewUserRole(role.ScopeId, role.PublicId, id)
if err != nil {
return nil, fmt.Errorf("unable to create in memory user role for add: %w", err)
}
newUserRoles = append(newUserRoles, usrRole)
}
}
var newGrpRoles []interface{}
groupIdsMap := map[string]struct{}{}
for _, id := range groupIds {
groupIdsMap[id] = struct{}{}
if _, ok := existingGroups[id]; !ok {
grpRole, err := NewGroupRole(role.ScopeId, role.PublicId, id)
if err != nil {
return nil, fmt.Errorf("unable to create in memory group role for add: %w", err)
}
newGrpRoles = append(newGrpRoles, grpRole)
}
}
var deleteUserRoles []interface{}
for _, p := range existingUsers {
if _, ok := userIdsMap[p.GetPrincipalId()]; !ok {
usrRole, err := NewUserRole(p.GetScopeId(), p.GetRoleId(), p.GetPrincipalId())
if err != nil {
return nil, fmt.Errorf("unable to create in memory user role for delete: %w", err)
}
deleteUserRoles = append(deleteUserRoles, usrRole)
}
}
var deleteGrpRoles []interface{}
for _, p := range existingGroups {
if _, ok := groupIdsMap[p.GetPrincipalId()]; !ok {
grpRole, err := NewGroupRole(p.GetScopeId(), p.GetRoleId(), p.GetPrincipalId())
if err != nil {
return nil, fmt.Errorf("unable to create in memory group role for delete: %w", err)
}
deleteGrpRoles = append(deleteGrpRoles, grpRole)
}
}
return &principalSet{
addUserRoles: newUserRoles,
addGroupRoles: newGrpRoles,
deleteUserRoles: deleteUserRoles,
deleteGroupRoles: deleteGrpRoles,
}, nil
}

Loading…
Cancel
Save