verify / verify (push) Successful in 4m17s
Signed-off-by: Cole Speelman <crspeelman@gmail.com>
39 lines
1.3 KiB
Go
39 lines
1.3 KiB
Go
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package organizations
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"slices"
|
|
"time"
|
|
)
|
|
|
|
var ErrRoleInvitationUnsupported = errors.New("organizations: atomic role-set invitations are unsupported")
|
|
|
|
// RoleInvitationRepository must preserve the entire role set and its required
|
|
// owner authority, then commit acceptance, membership, grants and audit together.
|
|
type RoleInvitationRepository interface {
|
|
CreateInvitationWithRoles(context.Context, Invitation, string, AuditEvent) error
|
|
AcceptInvitationWithRoles(context.Context, [32]byte, string, string, time.Time, AuditEvent) error
|
|
}
|
|
|
|
// RoleNames returns a validated copy of the invitation's direct roles. The older
|
|
// DirectRole remains supported; supplying both forms is an error, not a union.
|
|
func (invitation Invitation) RoleNames() ([]string, error) {
|
|
if invitation.DirectRole != "" && len(invitation.DirectRoles) > 0 || len(invitation.DirectRoles) > 16 {
|
|
return nil, errors.New("organizations: invalid invitation roles")
|
|
}
|
|
roles := append([]string(nil), invitation.DirectRoles...)
|
|
if invitation.DirectRole != "" {
|
|
roles = append(roles, invitation.DirectRole)
|
|
}
|
|
slices.Sort(roles)
|
|
for i, role := range roles {
|
|
if !safeNamePattern.MatchString(role) || i > 0 && role == roles[i-1] {
|
|
return nil, errors.New("organizations: invalid invitation role")
|
|
}
|
|
}
|
|
return roles, nil
|
|
}
|