/// <summary> /// Create a new <see cref="AccountRBACManager"/> from an existing database model. /// </summary> public AccountRBACManager(WorldSession session, AccountModel model) { this.session = session; foreach (AccountPermissionModel permissionModel in model.AccountPermission) { RBACPermission rbacPermission = RBACManager.Instance.GetPermission((Permission)permissionModel.PermissionId); if (rbacPermission == null) { throw new DatabaseDataException($"Account {model.Id} has invalid permission {permissionModel.PermissionId}!"); } permissions.Add(rbacPermission.Permission, new AccountPermission(permissionModel, rbacPermission)); } foreach (AccountRoleModel roleModel in model.AccountRole) { RBACRole rbacRole = RBACManager.Instance.GetRole((Role)roleModel.RoleId); if (rbacRole == null) { throw new DatabaseDataException($"Account {model.Id} has invalid role {roleModel.RoleId}!"); } roles.Add(rbacRole.Role, new AccountRole(roleModel, rbacRole)); } }
/// <summary> /// Grant <see cref="RBACRole"/> with supplied <see cref="Role"/> id to account. /// </summary> public void GrantRole(Role role) { RBACRole rbacRole = RBACManager.Instance.GetRole(role); if (rbacRole == null) { throw new ArgumentException($"Failed to grant role to account {session.Account.Id}, {role} isn't a valid role!"); } if (!roles.TryGetValue(role, out AccountRole accountRole)) { roles.Add(rbacRole.Role, new AccountRole(session.Account.Id, rbacRole)); } else { // we have this role but it's pending a delete from the database, reuse the model if (accountRole.PendingDelete) { accountRole.EnqueueDelete(false); } else { throw new ArgumentException($"Failed to grant role to account {session.Account.Id}, account already has role!"); } } }
public void Initialise() { log.Info("Initialising RBAC permissions..."); var permissionBuilder = ImmutableDictionary.CreateBuilder <Permission, RBACPermission>(); foreach (PermissionModel permissionModel in DatabaseManager.Instance.AuthDatabase.GetPermissions()) { var permission = new RBACPermission(permissionModel); permissionBuilder.Add(permission.Permission, permission); } permissions = permissionBuilder.ToImmutable(); var roleBuilder = ImmutableDictionary.CreateBuilder <Role, RBACRole>(); foreach (RoleModel roleModel in DatabaseManager.Instance.AuthDatabase.GetRoles()) { // check if permissions for role exist if (roleModel.RolePermission.Any(p => GetPermission((Permission)p.PermissionId) == null)) { throw new DatabaseDataException($"Role {roleModel.Flags}"); } // all permissions are included RoleFlags flags = (RoleFlags)roleModel.Flags; if ((flags & RoleFlags.Inclusive) != 0) { var role = new RBACRole(roleModel, roleModel.RolePermission .Select(p => GetPermission((Permission)p.PermissionId)) .ToImmutableDictionary(p => p.Permission, p => p)); roleBuilder.Add(role.Role, role); } // all permissions are excluded // this is used when a role will have all permission except a few else if ((flags & RoleFlags.Exclusive) != 0) { ImmutableDictionary <Permission, RBACPermission> except = roleModel.RolePermission .Select(p => GetPermission((Permission)p.PermissionId)) .ToImmutableDictionary(p => p.Permission, p => p); var role = new RBACRole(roleModel, permissions .Except(except) .ToImmutableDictionary(p => p.Key, p => p.Value)); roleBuilder.Add(role.Role, role); } } roles = roleBuilder.ToImmutable(); log.Info($"Loaded {permissions.Count} permission(s) in {roles.Count} role(s)."); }
/// <summary> /// Create a new <see cref="AccountRole"/> from a <see cref="RBACRole"/>. /// </summary> public AccountRole(uint id, RBACRole role) { Id = id; Role = role; saveMask = SaveMask.Create; }
/// <summary> /// Create a new <see cref="AccountRole"/> from an existing database model. /// </summary> public AccountRole(AccountRoleModel model, RBACRole role) { Id = model.Id; Role = role; saveMask = SaveMask.None; }