Add per-server access control (User.ServerIDs)
Non-admin users are now restricted to servers explicitly listed in their new ServerIDs field; empty means no access (secure by default). Admins always have full access. Migration backfills existing users' ServerIDs with the migrated legacy server so nobody is locked out on upgrade. New RequireServerAccess middleware enforces this on /servers/:id/... routes (applied to GET /servers/:id/clients so far); GET /servers also filters its list for non-admins.
This commit is contained in:
@@ -303,6 +303,27 @@ func (o *JsonDB) migrateLegacyServer() error {
|
||||
}
|
||||
}
|
||||
|
||||
// backfill ServerIDs on every existing user so nobody is locked out of
|
||||
// the migrated server by the new per-server access control (users
|
||||
// created after migration default to no access, per model.User).
|
||||
userRecords, err := o.conn.ReadAll("users")
|
||||
if err != nil && err != scribble.ErrMissingCollection {
|
||||
return fmt.Errorf("migration: cannot read users: %v", err)
|
||||
}
|
||||
for _, rec := range userRecords {
|
||||
var user model.User
|
||||
if err := json.Unmarshal(rec, &user); err != nil {
|
||||
return fmt.Errorf("migration: cannot decode user json: %v", err)
|
||||
}
|
||||
if len(user.ServerIDs) > 0 {
|
||||
continue
|
||||
}
|
||||
user.ServerIDs = []string{serverID}
|
||||
if err := o.conn.Write("users", user.Username, user); err != nil {
|
||||
return fmt.Errorf("migration: cannot backfill server_ids on user %s: %v", user.Username, err)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: the legacy "server" directory is intentionally left in place
|
||||
// (not renamed/removed) at this stage. Existing store methods (GetServer,
|
||||
// GetGlobalSettings, SaveServerInterface, ...) still read/write it
|
||||
|
||||
Reference in New Issue
Block a user