mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-15 01:32:56 +02:00
Extends management user and group structure (#1268)
* extends user and group structure by introducing fields for issued and integration references * Add integration checks to group management to prevent groups added by integration. * Add integration checks to user management to prevent deleting user added by integration. * Fix broken user update tests * Initialize all user fields for testing * Change a serializer option to embedded for IntegrationReference in user and group models * Add issued field to user api response * Add IntegrationReference to Group in update groups handler * Set the default issued field for users in file store
This commit is contained in:
@ -22,6 +22,9 @@ const (
|
||||
UserStatusActive UserStatus = "active"
|
||||
UserStatusDisabled UserStatus = "disabled"
|
||||
UserStatusInvited UserStatus = "invited"
|
||||
|
||||
UserIssuedAPI = "api"
|
||||
UserIssuedIntegration = "integration"
|
||||
)
|
||||
|
||||
// StrRoleToUserRole returns UserRole for a given strRole or UserRoleUnknown if the specified role is unknown
|
||||
@ -42,6 +45,16 @@ type UserStatus string
|
||||
// UserRole is the role of a User
|
||||
type UserRole string
|
||||
|
||||
// IntegrationReference holds the reference to a particular integration
|
||||
type IntegrationReference struct {
|
||||
ID int
|
||||
IntegrationType string
|
||||
}
|
||||
|
||||
func (ir IntegrationReference) String() string {
|
||||
return fmt.Sprintf("%d:%s", ir.ID, ir.IntegrationType)
|
||||
}
|
||||
|
||||
// User represents a user of the system
|
||||
type User struct {
|
||||
Id string `gorm:"primaryKey"`
|
||||
@ -59,6 +72,11 @@ type User struct {
|
||||
Blocked bool
|
||||
// LastLogin is the last time the user logged in to IdP
|
||||
LastLogin time.Time
|
||||
|
||||
// Issued of the user
|
||||
Issued string `gorm:"default:api"`
|
||||
|
||||
IntegrationReference IntegrationReference `gorm:"embedded;embeddedPrefix:integration_ref_"`
|
||||
}
|
||||
|
||||
// IsBlocked returns true if the user is blocked, false otherwise
|
||||
@ -93,6 +111,7 @@ func (u *User) ToUserInfo(userData *idp.UserData) (*UserInfo, error) {
|
||||
IsServiceUser: u.IsServiceUser,
|
||||
IsBlocked: u.Blocked,
|
||||
LastLogin: u.LastLogin,
|
||||
Issued: u.Issued,
|
||||
}, nil
|
||||
}
|
||||
if userData.ID != u.Id {
|
||||
@ -114,6 +133,7 @@ func (u *User) ToUserInfo(userData *idp.UserData) (*UserInfo, error) {
|
||||
IsServiceUser: u.IsServiceUser,
|
||||
IsBlocked: u.Blocked,
|
||||
LastLogin: u.LastLogin,
|
||||
Issued: u.Issued,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -126,37 +146,40 @@ func (u *User) Copy() *User {
|
||||
pats[k] = v.Copy()
|
||||
}
|
||||
return &User{
|
||||
Id: u.Id,
|
||||
AccountID: u.AccountID,
|
||||
Role: u.Role,
|
||||
AutoGroups: autoGroups,
|
||||
IsServiceUser: u.IsServiceUser,
|
||||
ServiceUserName: u.ServiceUserName,
|
||||
PATs: pats,
|
||||
Blocked: u.Blocked,
|
||||
LastLogin: u.LastLogin,
|
||||
Id: u.Id,
|
||||
AccountID: u.AccountID,
|
||||
Role: u.Role,
|
||||
AutoGroups: autoGroups,
|
||||
IsServiceUser: u.IsServiceUser,
|
||||
ServiceUserName: u.ServiceUserName,
|
||||
PATs: pats,
|
||||
Blocked: u.Blocked,
|
||||
LastLogin: u.LastLogin,
|
||||
Issued: u.Issued,
|
||||
IntegrationReference: u.IntegrationReference,
|
||||
}
|
||||
}
|
||||
|
||||
// NewUser creates a new user
|
||||
func NewUser(id string, role UserRole, isServiceUser bool, serviceUserName string, autoGroups []string) *User {
|
||||
func NewUser(id string, role UserRole, isServiceUser bool, serviceUserName string, autoGroups []string, issued string) *User {
|
||||
return &User{
|
||||
Id: id,
|
||||
Role: role,
|
||||
IsServiceUser: isServiceUser,
|
||||
ServiceUserName: serviceUserName,
|
||||
AutoGroups: autoGroups,
|
||||
Issued: issued,
|
||||
}
|
||||
}
|
||||
|
||||
// NewRegularUser creates a new user with role UserRoleUser
|
||||
func NewRegularUser(id string) *User {
|
||||
return NewUser(id, UserRoleUser, false, "", []string{})
|
||||
return NewUser(id, UserRoleUser, false, "", []string{}, UserIssuedAPI)
|
||||
}
|
||||
|
||||
// NewAdminUser creates a new user with role UserRoleAdmin
|
||||
func NewAdminUser(id string) *User {
|
||||
return NewUser(id, UserRoleAdmin, false, "", []string{})
|
||||
return NewUser(id, UserRoleAdmin, false, "", []string{}, UserIssuedAPI)
|
||||
}
|
||||
|
||||
// createServiceUser creates a new service user under the given account.
|
||||
@ -178,7 +201,7 @@ func (am *DefaultAccountManager) createServiceUser(accountID string, initiatorUs
|
||||
}
|
||||
|
||||
newUserID := uuid.New().String()
|
||||
newUser := NewUser(newUserID, role, true, serviceUserName, autoGroups)
|
||||
newUser := NewUser(newUserID, role, true, serviceUserName, autoGroups, UserIssuedAPI)
|
||||
log.Debugf("New User: %v", newUser)
|
||||
account.Users[newUserID] = newUser
|
||||
|
||||
@ -199,6 +222,7 @@ func (am *DefaultAccountManager) createServiceUser(accountID string, initiatorUs
|
||||
Status: string(UserStatusActive),
|
||||
IsServiceUser: true,
|
||||
LastLogin: time.Time{},
|
||||
Issued: UserIssuedAPI,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -270,9 +294,11 @@ func (am *DefaultAccountManager) inviteNewUser(accountID, userID string, invite
|
||||
|
||||
role := StrRoleToUserRole(invite.Role)
|
||||
newUser := &User{
|
||||
Id: idpUser.ID,
|
||||
Role: role,
|
||||
AutoGroups: invite.AutoGroups,
|
||||
Id: idpUser.ID,
|
||||
Role: role,
|
||||
AutoGroups: invite.AutoGroups,
|
||||
Issued: invite.Issued,
|
||||
IntegrationReference: invite.IntegrationReference,
|
||||
}
|
||||
account.Users[idpUser.ID] = newUser
|
||||
|
||||
@ -361,6 +387,10 @@ func (am *DefaultAccountManager) DeleteUser(accountID, initiatorUserID string, t
|
||||
return status.Errorf(status.NotFound, "target user not found")
|
||||
}
|
||||
|
||||
if targetUser.Issued == UserIssuedIntegration {
|
||||
return status.Errorf(status.PermissionDenied, "only integration can delete this user")
|
||||
}
|
||||
|
||||
// handle service user first and exit, no need to fetch extra data from IDP, etc
|
||||
if targetUser.IsServiceUser {
|
||||
am.deleteServiceUser(account, initiatorUserID, targetUser)
|
||||
|
Reference in New Issue
Block a user