public async Task Default ( string permissionName, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <PermissionTarget>))] PermissionTarget revokedTarget = PermissionTarget.Self ) => await Default(this.Context.User, permissionName, revokedTarget);
public async Task <RuntimeResult> Default ( IRole discordRole, string permissionName, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <PermissionTarget>))] PermissionTarget revokedTarget = PermissionTarget.Self ) { var getPermissionResult = _permissionRegistry.GetPermission(permissionName); if (!getPermissionResult.IsSuccess) { return(getPermissionResult.ToRuntimeResult()); } var permission = getPermissionResult.Entity; var revokePermissionResult = await _permissions.RevokePermissionAsync ( discordRole, permission, revokedTarget ); if (!revokePermissionResult.IsSuccess) { return(revokePermissionResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess ( $"{permission.FriendlyName} revoked from {MentionUtils.MentionRole(discordRole.Id)}." )); }
public async Task <RuntimeResult> Default ( IUser discordUser, string permissionName, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <PermissionTarget>))] PermissionTarget grantedTarget = PermissionTarget.Self ) { var getPermissionResult = _permissionRegistry.GetPermission(permissionName); if (!getPermissionResult.IsSuccess) { return(getPermissionResult.ToRuntimeResult()); } var permission = getPermissionResult.Entity; var grantPermissionResult = await _permissions.GrantPermissionAsync ( this.Context.Guild, discordUser, permission, grantedTarget ); if (!grantPermissionResult.IsSuccess) { return(grantPermissionResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess ( $"{permission.FriendlyName} granted to {discordUser.Mention}." )); }
public async Task <ModifyEntityResult> RevokePermissionAsync ( [NotNull] IRole discordRole, [NotNull] IPermission revokedPermission, PermissionTarget target ) { // Special All target handling if (target == PermissionTarget.All) { var revokeSelfResult = await RevokePermissionAsync ( discordRole, revokedPermission, PermissionTarget.Self ); var revokeOtherResult = await RevokePermissionAsync ( discordRole, revokedPermission, PermissionTarget.Other ); if (revokeSelfResult.IsSuccess || revokeOtherResult.IsSuccess) { return(ModifyEntityResult.FromSuccess()); } // Both are false, so we'll just inherit the self result. return(ModifyEntityResult.FromError(revokeSelfResult)); } var getPermissionResult = await GetOrCreateRolePermissionAsync ( discordRole, revokedPermission, target ); if (!getPermissionResult.IsSuccess) { return(ModifyEntityResult.FromError(getPermissionResult)); } var permission = getPermissionResult.Entity; if (!permission.IsGranted) { return(ModifyEntityResult.FromError("The role is already prohibited from doing that.")); } permission.IsGranted = false; await _database.SaveChangesAsync(); return(ModifyEntityResult.FromSuccess()); }
public async Task <ModifyEntityResult> GrantPermissionAsync ( [NotNull] IRole discordRole, [NotNull] IPermission grantedPermission, PermissionTarget target ) { // Special All target handling if (target == PermissionTarget.All) { var grantSelfResult = await GrantPermissionAsync ( discordRole, grantedPermission, PermissionTarget.Self ); var grantOtherResult = await GrantPermissionAsync ( discordRole, grantedPermission, PermissionTarget.Other ); if (grantSelfResult.IsSuccess || grantOtherResult.IsSuccess) { return(ModifyEntityResult.FromSuccess()); } // Both are false, so we'll just inherit the self result. return(ModifyEntityResult.FromError(grantSelfResult)); } var getPermissionResult = await GetOrCreateRolePermissionAsync ( discordRole, grantedPermission, target ); if (!getPermissionResult.IsSuccess) { return(ModifyEntityResult.FromError(getPermissionResult)); } var permission = getPermissionResult.Entity; if (permission.IsGranted) { return(ModifyEntityResult.FromError("The user already has permission to do that.")); } permission.IsGranted = true; await _database.SaveChangesAsync(); return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Gets an existing user permission, or creates a default one if it does not exist. /// </summary> /// <param name="discordGuild">The guild the user is in.</param> /// <param name="discordUser">The user.</param> /// <param name="permission">The permission.</param> /// <param name="target">The target.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A retrieval result which may or may not have finished.</returns> private async Task <RetrieveEntityResult <UserPermission> > GetOrCreateUserPermissionAsync ( IGuild discordGuild, IUser discordUser, IPermission permission, PermissionTarget target, CancellationToken ct = default ) { if (target == PermissionTarget.All) { throw new ArgumentException("Invalid permission target.", nameof(target)); } var userPermissions = await _database.UserPermissions.ServersideQueryAsync ( q => q.Where ( p => p.ServerID == (long)discordGuild.Id && p.UserID == (long)discordUser.Id && p.Permission == permission.UniqueIdentifier && p.Target == target ), ct ); var userPermission = userPermissions.SingleOrDefault(); if (!(userPermission is null)) { return(userPermission); } var newPermission = _database.CreateProxy <UserPermission> ( (long)discordGuild.Id, (long)discordUser.Id, permission.UniqueIdentifier, target ); _database.UserPermissions.Update(newPermission); newPermission.IsGranted = permission.IsGrantedByDefaultTo(target); await _database.SaveChangesAsync(ct); return(newPermission); }
private async Task <RetrieveEntityResult <UserPermission> > GetOrCreateUserPermissionAsync ( [NotNull] IGuild discordGuild, [NotNull] IUser discordUser, [NotNull] IPermission permission, PermissionTarget target ) { if (target == PermissionTarget.All) { throw new ArgumentException("Invalid permission target.", nameof(target)); } var existingPermission = await _database.UserPermissions.FirstOrDefaultAsync ( p => p.ServerID == (long)discordGuild.Id && p.UserID == (long)discordUser.Id && p.Permission == permission.UniqueIdentifier && p.Target == target ); if (!(existingPermission is null)) { return(RetrieveEntityResult <UserPermission> .FromSuccess(existingPermission)); } var newPermission = new UserPermission ( (long)discordGuild.Id, (long)discordUser.Id, permission.UniqueIdentifier, target ) { IsGranted = permission.IsGrantedByDefaultTo(target) }; _database.UserPermissions.Update(newPermission); await _database.SaveChangesAsync(); // Requery the database return(await GetOrCreateUserPermissionAsync(discordGuild, discordUser, permission, target)); }
/// <summary> /// Gets an existing role permission, or creates a default one if it does not exist. /// </summary> /// <param name="discordRole">The role.</param> /// <param name="permission">The permission.</param> /// <param name="target">The target.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A retrieval result which may or may not have finished.</returns> private async Task <Result <RolePermission> > GetOrCreateRolePermissionAsync ( Snowflake discordRole, IPermission permission, PermissionTarget target, CancellationToken ct = default ) { if (target == PermissionTarget.All) { throw new ArgumentException("Invalid permission target.", nameof(target)); } var rolePermissions = await _database.RolePermissions.ServersideQueryAsync ( q => q .Where(p => p.RoleID == discordRole) .Where(p => p.Permission == permission.UniqueIdentifier) .Where(p => p.Target == target), ct ); var rolePermission = rolePermissions.SingleOrDefault(); if (rolePermission is not null) { return(rolePermission); } var newPermission = _database.CreateProxy <RolePermission> ( discordRole, permission.UniqueIdentifier, target ); _database.RolePermissions.Update(newPermission); newPermission.IsGranted = permission.IsGrantedByDefaultTo(target); await _database.SaveChangesAsync(ct); return(newPermission); }
public async Task Default ( [NotNull] IUser discordUser, string permissionName, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <PermissionTarget>))] PermissionTarget revokedTarget = PermissionTarget.Self ) { var getPermissionResult = _permissionRegistry.GetPermission(permissionName); if (!getPermissionResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, getPermissionResult.ErrorReason); return; } var permission = getPermissionResult.Entity; var revokePermissionResult = await _permissions.RevokePermissionAsync ( this.Context.Guild, discordUser, permission, revokedTarget ); if (!revokePermissionResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, revokePermissionResult.ErrorReason); return; } await _feedback.SendConfirmationAsync ( this.Context, $"{permission.FriendlyName} revoked from {discordUser.Mention}." ); }
public async Task Default ( [NotNull] IRole discordRole, [NotNull] string permissionName, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <PermissionTarget>))] PermissionTarget grantedTarget = PermissionTarget.Self ) { var getPermissionResult = _permissionRegistry.GetPermission(permissionName); if (!getPermissionResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, getPermissionResult.ErrorReason); return; } var permission = getPermissionResult.Entity; var grantPermissionResult = await _permissions.GrantPermissionAsync ( discordRole, permission, grantedTarget ); if (!grantPermissionResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, grantPermissionResult.ErrorReason); return; } await _feedback.SendConfirmationAsync ( this.Context, $"{permission.FriendlyName} granted to {MentionUtils.MentionRole(discordRole.Id)}." ); }
/// <summary> /// Gets an existing role permission, or creates a default one if it does not exist. /// </summary> /// <param name="discordRole">The role.</param> /// <param name="permission">The permission.</param> /// <param name="target">The target.</param> /// <returns>A retrieval result which may or may not have finished.</returns> private async Task <RetrieveEntityResult <RolePermission> > GetOrCreateRolePermissionAsync ( IRole discordRole, IPermission permission, PermissionTarget target ) { if (target == PermissionTarget.All) { throw new ArgumentException("Invalid permission target.", nameof(target)); } var existingPermission = await _database.RolePermissions.AsQueryable().FirstOrDefaultAsync ( p => p.RoleID == (long)discordRole.Id && p.Permission == permission.UniqueIdentifier && p.Target == target ); if (!(existingPermission is null)) { return(RetrieveEntityResult <RolePermission> .FromSuccess(existingPermission)); } var newPermission = new RolePermission((long)discordRole.Id, permission.UniqueIdentifier, target) { IsGranted = permission.IsGrantedByDefaultTo(target) }; _database.RolePermissions.Update(newPermission); await _database.SaveChangesAsync(); // Requery the database return(await GetOrCreateRolePermissionAsync(discordRole, permission, target)); }
public async Task <DetermineConditionResult> HasPermissionAsync ( [NotNull] IGuild discordServer, [NotNull] IGuildUser discordUser, IPermission requiredPermission, PermissionTarget target ) { // The server owner always has all permissions by default if (discordServer.OwnerId == discordUser.Id) { return(DetermineConditionResult.FromSuccess()); } // Special handling for the All target if (target == PermissionTarget.All) { var hasSelf = await HasPermissionAsync ( discordServer, discordUser, requiredPermission, PermissionTarget.Self ); var hasOther = await HasPermissionAsync ( discordServer, discordUser, requiredPermission, PermissionTarget.Other ); if (hasSelf.IsSuccess && hasOther.IsSuccess) { return(DetermineConditionResult.FromSuccess()); } return(DetermineConditionResult.FromError("Permission denied.")); } var hasPermission = false; // Check if the user is part of any roles which this permission applies to var rolePermission = await GetApplicableRolePermissions(discordUser) .FirstOrDefaultAsync ( p => p.Permission == requiredPermission.UniqueIdentifier && p.Target == target ); if (!(rolePermission is null)) { hasPermission = rolePermission.IsGranted; } // Check if the user has the permission applied to themselves var userPermission = await GetApplicableUserPermissions(discordServer, discordUser) .FirstOrDefaultAsync ( p => p.Permission == requiredPermission.UniqueIdentifier && p.Target == target ); if (!(userPermission is null)) { hasPermission = userPermission.IsGranted; } if (rolePermission is null && userPermission is null) { // Use the permission's default value hasPermission = requiredPermission.IsGrantedByDefaultTo(target); } if (hasPermission) { return(DetermineConditionResult.FromSuccess()); } return(DetermineConditionResult.FromError("Permission denied.")); }
/// <summary> /// Grants the specified user the given permission. /// </summary> /// <param name="discordServer">The Discord server the permission was granted on.</param> /// <param name="discordUser">The Discord user.</param> /// <param name="grantedPermission">The granted permission.</param> /// <param name="target">The granted target.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> GrantPermissionAsync ( IGuild discordServer, IUser discordUser, IPermission grantedPermission, PermissionTarget target, CancellationToken ct = default ) { // Special All target handling if (target == PermissionTarget.All) { var grantSelfResult = await GrantPermissionAsync ( discordServer, discordUser, grantedPermission, PermissionTarget.Self, ct ); var grantOtherResult = await GrantPermissionAsync ( discordServer, discordUser, grantedPermission, PermissionTarget.Other, ct ); if (grantSelfResult.IsSuccess || grantOtherResult.IsSuccess) { return(ModifyEntityResult.FromSuccess()); } // Both are false, so we'll just inherit the error from the self grant. return(ModifyEntityResult.FromError(grantSelfResult)); } var getPermissionResult = await GetOrCreateUserPermissionAsync ( discordServer, discordUser, grantedPermission, target, ct ); if (!getPermissionResult.IsSuccess) { return(ModifyEntityResult.FromError(getPermissionResult)); } var permission = getPermissionResult.Entity; if (permission.IsGranted) { return(ModifyEntityResult.FromError("The user already has permission to do that.")); } permission.IsGranted = true; await _database.SaveChangesAsync(ct); return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Revokes the given permission from the given Discord user. If the user does not have the permission, no /// changes are made. /// </summary> /// <param name="discordServer">The Discord server the permission was revoked on.</param> /// <param name="discordUser">The Discord user.</param> /// <param name="revokedPermission">The revoked permission.</param> /// <param name="target">The revoked target.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> RevokePermissionAsync ( IGuild discordServer, IUser discordUser, IPermission revokedPermission, PermissionTarget target, CancellationToken ct = default ) { // Special All target handling if (target == PermissionTarget.All) { var revokeSelfResult = await RevokePermissionAsync ( discordServer, discordUser, revokedPermission, PermissionTarget.Self, ct ); var revokeOtherResult = await RevokePermissionAsync ( discordServer, discordUser, revokedPermission, PermissionTarget.Other, ct ); if (revokeSelfResult.IsSuccess || revokeOtherResult.IsSuccess) { return(ModifyEntityResult.FromSuccess()); } // Both are false, so we'll just inherit the self result. return(ModifyEntityResult.FromError(revokeSelfResult)); } var getPermissionResult = await GetOrCreateUserPermissionAsync ( discordServer, discordUser, revokedPermission, target, ct ); if (!getPermissionResult.IsSuccess) { return(ModifyEntityResult.FromError(getPermissionResult)); } var permission = getPermissionResult.Entity; if (!permission.IsGranted) { return(ModifyEntityResult.FromError("The user is already prohibited from doing that.")); } permission.IsGranted = false; await _database.SaveChangesAsync(ct); return(ModifyEntityResult.FromSuccess()); }
public async Task <Result> HasPermissionAsync ( Snowflake discordServer, Snowflake discordUser, IPermission requiredPermission, PermissionTarget target, CancellationToken ct = default ) { var getDiscordServer = await _guildAPI.GetGuildAsync(discordServer, ct : ct); if (!getDiscordServer.IsSuccess) { return(Result.FromError(getDiscordServer)); } var guild = getDiscordServer.Entity; // The server owner always has all permissions by default if (guild.OwnerID == discordUser) { return(Result.FromSuccess()); } // Special handling for the All target if (target == PermissionTarget.All) { var hasSelf = await HasPermissionAsync ( discordServer, discordUser, requiredPermission, PermissionTarget.Self, ct ); var hasOther = await HasPermissionAsync ( discordServer, discordUser, requiredPermission, PermissionTarget.Other, ct ); if (hasSelf.IsSuccess && hasOther.IsSuccess) { return(Result.FromSuccess()); } return(new UserError("Permission denied.")); } var hasPermission = false; var getGuildMember = await _guildAPI.GetGuildMemberAsync(discordServer, discordUser, ct); if (!getGuildMember.IsSuccess) { return(Result.FromError(getGuildMember)); } var member = getGuildMember.Entity; // Check if the user is part of any roles which this permission applies to var rolePermissions = await GetApplicableRolePermissionsAsync(member.Roles, ct); var rolePermission = rolePermissions.FirstOrDefault ( p => p.Permission == requiredPermission.UniqueIdentifier && p.Target == target ); if (rolePermission is not null) { hasPermission = rolePermission.IsGranted; } // Check if the user has the permission applied to themselves var userPermission = await _database.UserPermissions.ServersideQueryAsync ( q => q .Where(p => p.ServerID == discordServer) .Where(p => p.UserID == discordUser) .Where(p => p.Permission == requiredPermission.UniqueIdentifier) .Where(p => p.Target == target) .SingleOrDefaultAsync(ct) ); if (userPermission is not null) { hasPermission = userPermission.IsGranted; } if (rolePermission is null && userPermission is null) { // Use the permission's default value hasPermission = requiredPermission.IsGrantedByDefaultTo(target); } return(hasPermission ? Result.FromSuccess() : new UserError("Permission denied.")); }