migrate auto groups to different table

This commit is contained in:
pascal
2026-01-08 15:45:48 +01:00
parent fb71b0d04b
commit f7ee019f26
7 changed files with 387 additions and 56 deletions

View File

@@ -28,6 +28,8 @@ type Group struct {
// Peers list of the group
Peers []string `gorm:"-"` // Peers and GroupPeers list will be ignored when writing to the DB. Use AddPeerToGroup and RemovePeerFromGroup methods to modify group membership
GroupPeers []GroupPeer `gorm:"foreignKey:GroupID;references:id;constraint:OnDelete:CASCADE;"`
Users []string `gorm:"-"`
GroupUsers []GroupUser `gorm:"foreignKey:GroupID;references:id;constraint:OnDelete:CASCADE;"`
// Resources contains a list of resources in that group
Resources []Resource `gorm:"serializer:json"`
@@ -41,6 +43,12 @@ type GroupPeer struct {
PeerID string `gorm:"primaryKey"`
}
type GroupUser struct {
AccountID string `gorm:"index"`
GroupID string `gorm:"primaryKey"`
UserID string `gorm:"primaryKey"`
}
func (g *Group) LoadGroupPeers() {
g.Peers = make([]string, len(g.GroupPeers))
for i, peer := range g.GroupPeers {
@@ -61,6 +69,26 @@ func (g *Group) StoreGroupPeers() {
g.Peers = []string{}
}
func (g *Group) LoadGroupUsers() {
g.Users = make([]string, len(g.GroupUsers))
for i, user := range g.GroupUsers {
g.Users[i] = user.UserID
}
g.GroupUsers = []GroupUser{}
}
func (g *Group) StoreGroupUsers() {
g.GroupUsers = make([]GroupUser, len(g.Users))
for i, user := range g.Users {
g.GroupUsers[i] = GroupUser{
AccountID: g.AccountID,
GroupID: g.ID,
UserID: user,
}
}
g.Users = []string{}
}
// EventMeta returns activity event meta related to the group
func (g *Group) EventMeta() map[string]any {
return map[string]any{"name": g.Name}
@@ -78,11 +106,13 @@ func (g *Group) Copy() *Group {
Issued: g.Issued,
Peers: make([]string, len(g.Peers)),
GroupPeers: make([]GroupPeer, len(g.GroupPeers)),
GroupUsers: make([]GroupUser, len(g.GroupUsers)),
Resources: make([]Resource, len(g.Resources)),
IntegrationReference: g.IntegrationReference,
}
copy(group.Peers, g.Peers)
copy(group.GroupPeers, g.GroupPeers)
copy(group.GroupUsers, g.GroupUsers)
copy(group.Resources, g.Resources)
return group
}

View File

@@ -85,9 +85,11 @@ type User struct {
// ServiceUserName is only set if IsServiceUser is true
ServiceUserName string
// AutoGroups is a list of Group IDs to auto-assign to peers registered by this user
AutoGroups []string `gorm:"serializer:json"`
PATs map[string]*PersonalAccessToken `gorm:"-"`
PATsG []PersonalAccessToken `json:"-" gorm:"foreignKey:UserID;references:id;constraint:OnDelete:CASCADE;"`
AutoGroups []string `gorm:"-"`
// GroupUsers replaces old AutoGroups
Groups []*GroupUser `gorm:"foreignKey:UserID;references:id;constraint:OnDelete:CASCADE;"`
PATs map[string]*PersonalAccessToken `gorm:"-"`
PATsG []PersonalAccessToken `json:"-" gorm:"foreignKey:UserID;references:id;constraint:OnDelete:CASCADE;"`
// Blocked indicates whether the user is blocked. Blocked users can't use the system.
Blocked bool
// PendingApproval indicates whether the user requires approval before being activated
@@ -106,6 +108,24 @@ type User struct {
Email string `gorm:"default:''"`
}
func (u *User) LoadAutoGroups() {
u.AutoGroups = make([]string, 0, len(u.Groups))
for _, group := range u.Groups {
u.AutoGroups = append(u.AutoGroups, group.GroupID)
}
}
func (u *User) StoreAutoGroups() {
u.Groups = make([]*GroupUser, 0, len(u.Groups))
for _, groupID := range u.AutoGroups {
u.Groups = append(u.Groups, &GroupUser{
AccountID: u.AccountID,
GroupID: groupID,
UserID: u.Id,
})
}
}
// IsBlocked returns true if the user is blocked, false otherwise
func (u *User) IsBlocked() bool {
return u.Blocked
@@ -198,8 +218,11 @@ func (u *User) ToUserInfo(userData *idp.UserData) (*UserInfo, error) {
// Copy the user
func (u *User) Copy() *User {
groupUsers := make([]*GroupUser, len(u.Groups))
copy(groupUsers, u.Groups)
autoGroups := make([]string, len(u.AutoGroups))
copy(autoGroups, u.AutoGroups)
pats := make(map[string]*PersonalAccessToken, len(u.PATs))
for k, v := range u.PATs {
pats[k] = v.Copy()
@@ -221,6 +244,7 @@ func (u *User) Copy() *User {
IntegrationReference: u.IntegrationReference,
Email: u.Email,
Name: u.Name,
Groups: groupUsers,
}
}