private static async Task RemoveRoleMembership(HttpContext ctx, ValourDB db, ulong member_id, ulong role_member_id, [FromHeader] string authorization) { AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db); if (auth is null) { await TokenInvalid(ctx); return; } ServerPlanetMember target_member = await db.PlanetMembers .Include(x => x.Planet) .Include(x => x.RoleMembership.OrderBy(x => x.Role.Position)) .ThenInclude(x => x.Role) .FirstOrDefaultAsync(x => x.Id == member_id); if (target_member is null) { ctx.Response.StatusCode = 404; await ctx.Response.WriteAsync("Target member not found"); return; } // Ensure auth user is member of planet ServerPlanetMember member = await db.PlanetMembers.FirstOrDefaultAsync(x => x.Planet_Id == target_member.Planet_Id && x.User_Id == auth.User_Id); if (member is null) { ctx.Response.StatusCode = 403; await ctx.Response.WriteAsync("Auth member not found"); return; } if (!auth.HasScope(UserPermissions.PlanetManagement)) { ctx.Response.StatusCode = 403; await ctx.Response.WriteAsync("Token lacks UserPermissions.PlanetManagement"); return; } var roleMember = await db.PlanetRoleMembers.Include(x => x.Role).FirstOrDefaultAsync(x => x.Id == role_member_id); if (roleMember is null) { ctx.Response.StatusCode = 200; await ctx.Response.WriteAsync("Member already lacks role"); return; } if (roleMember.Id != target_member.Id) { ctx.Response.StatusCode = 400; await ctx.Response.WriteAsync("Target id mismatch"); return; } if (roleMember.Planet_Id != member.Planet_Id || roleMember.Planet_Id != target_member.Planet_Id) { ctx.Response.StatusCode = 400; await ctx.Response.WriteAsync("Planet id mismatch"); return; } var callerAuth = await member.GetAuthorityAsync(); // Ensure role has less authority than user adding it if (roleMember.Role.GetAuthority() >= callerAuth) { ctx.Response.StatusCode = 400; await ctx.Response.WriteAsync("Can only add remove with lower authority than your own"); return; } // Ensure target member has less authority than caller if (await target_member.GetAuthorityAsync() >= callerAuth) { ctx.Response.StatusCode = 403; await ctx.Response.WriteAsync("Target has higher or equal authority"); return; } db.Remove(roleMember); await db.SaveChangesAsync(); ctx.Response.StatusCode = 200; await ctx.Response.WriteAsync("Success"); return; }