Skip to content

Commit 9633e70

Browse files
Update permissions and get state apis added
1 parent 8e9acc3 commit 9633e70

File tree

1 file changed

+73
-10
lines changed

1 file changed

+73
-10
lines changed

UserManagementApi/Controllers/UsersController.cs

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.EntityFrameworkCore;
44
using Microsoft.Extensions.Options;
55
using Microsoft.IdentityModel.Tokens;
6+
using SharedLibrary.Cache;
67
using System.IdentityModel.Tokens.Jwt;
78
using System.Security.Claims;
89
using System.Text;
@@ -11,6 +12,7 @@
1112
using UserManagementApi.Contracts.Models;
1213
using UserManagementApi.Data;
1314
using UserManagementApi.DTO.Auth;
15+
using static System.Net.WebRequestMethods;
1416

1517

1618
namespace UserManagementApi.Controllers
@@ -20,14 +22,12 @@ namespace UserManagementApi.Controllers
2022
[Route("api/users")]
2123
public class UsersController : ControllerBase
2224
{
25+
private readonly ICacheAccessProvider _cache;
2326
private readonly AppDbContext _db;
2427
private readonly JwtOptions _jwt;
2528

26-
public UsersController(AppDbContext db, IOptions<JwtOptions> jwtOptions)
27-
{
28-
_db = db;
29-
_jwt = jwtOptions.Value;
30-
}
29+
public UsersController(ICacheAccessProvider cache, AppDbContext db, IOptions<JwtOptions> jwtOptions) => (_cache, _db, _jwt) = (cache, db, jwtOptions.Value);
30+
3131
// --------- NEW: POST /api/users/authenticate ----------
3232
[HttpPost("authenticate")]
3333
[ProducesResponseType(typeof(AuthResponse), StatusCodes.Status200OK)]
@@ -70,15 +70,58 @@ public async Task<ActionResult<AuthResponse>> Authenticate([FromBody] LoginReque
7070
var dto = await BuildPermissionsForUser(user.Id);
7171

7272
var token = GenerateJwt(user, out var expiresAtUtc);
73-
74-
return Ok(new AuthResponse(user.Id, user.UserName, token, expiresAtUtc, dto.Categories));
73+
74+
var role = user?.UserRoles.Select(ur => ur.Role.Name).FirstOrDefault();
75+
76+
return Ok(new AuthResponse(user.Id, user.UserName, token, role, expiresAtUtc, dto.Categories));
77+
}
78+
79+
[HttpPost("updatepermissions")]
80+
[ProducesResponseType(typeof(AuthResponse), StatusCodes.Status200OK)]
81+
public async Task<ActionResult<AuthResponse>> UpdatePermissions([FromBody] UpdatePermissionsRequest operation)
82+
{
83+
var admin = await _db.Roles.Where(r => r.Name == "Admin").FirstOrDefaultAsync();
84+
var webfunction = await _db.Functions.Where(r => r.Code == "Logs.View").FirstOrDefaultAsync();
85+
var apifunction = await _db.Functions.Where(r => r.Code == "Api.Logs.View").FirstOrDefaultAsync();
86+
87+
bool hasWebAccess = _db.RoleFunctions.Any(rf => rf.FunctionId == webfunction.Id && rf.RoleId == admin.Id);
88+
bool hasApiAccess = _db.RoleFunctions.Any(rf => rf.FunctionId == apifunction.Id && rf.RoleId == admin.Id);
89+
90+
if (operation.Op == "grant-webapp" && !hasWebAccess)
91+
{
92+
await _db.RoleFunctions.AddAsync(new RoleFunction() { RoleId = admin.Id, FunctionId = webfunction.Id});
93+
}
94+
if (operation.Op == "grant-api" && !hasApiAccess)
95+
{
96+
await _db.RoleFunctions.AddAsync(new RoleFunction() { RoleId = admin.Id, FunctionId = apifunction.Id });
97+
}
98+
if (operation.Op == "revoke-api" && hasApiAccess)
99+
{
100+
_db.RoleFunctions.Remove(new RoleFunction() { RoleId = admin.Id, FunctionId = apifunction.Id });
101+
}
102+
if (operation.Op == "revoke-both")
103+
{
104+
if (hasWebAccess)
105+
_db.RoleFunctions.Remove(new RoleFunction() { RoleId = admin.Id, FunctionId = webfunction.Id });
106+
if (hasApiAccess)
107+
_db.RoleFunctions.Remove(new RoleFunction() { RoleId = admin.Id, FunctionId = apifunction.Id });
108+
}
109+
// save once (only if something changed)
110+
if (_db.ChangeTracker.HasChanges())
111+
{
112+
var affected = await _db.SaveChangesAsync();
113+
}
114+
115+
long cacheresult = await _cache.InvalidatePermissionsForRoleAsync("Admin");
116+
117+
return Ok(new { Message = $"Permissions updated with operation: {operation.Op}" });
75118
}
76119

77120
// --------- (Existing) GET /api/users/{userId}/permissions ----------
78121
// Now protected by JWT; call with Bearer token returned by /authenticate
79122
[Authorize]
80123
[HttpGet("{userId:int}/permissions")]
81-
public async Task<ActionResult<UserPermissionsDto>> GetPermissions(int userId)
124+
public async Task<ActionResult> GetPermissions(int userId)
82125
{
83126
// Optional: you can enforce that a user can only view their own permissions
84127
// by comparing userId with the token's sub, if desired.
@@ -90,6 +133,24 @@ public async Task<ActionResult<UserPermissionsDto>> GetPermissions(int userId)
90133
return Ok(dto);
91134
}
92135

136+
[Authorize]
137+
[HttpGet("{userId:int}/getstate")]
138+
public async Task<object> GetStateAsync(int userId)
139+
{
140+
var admin = await _db.Roles.Where(r => r.Name == "Admin").FirstOrDefaultAsync();
141+
var webfunction = await _db.Functions.Where(r => r.Code == "Logs.View").FirstOrDefaultAsync();
142+
var apifunction = await _db.Functions.Where(r => r.Code == "Api.Logs.View").FirstOrDefaultAsync();
143+
144+
bool hasWebAccess = _db.RoleFunctions.Any(rf => rf.FunctionId == webfunction.Id && rf.RoleId == admin.Id);
145+
bool hasApiAccess = _db.RoleFunctions.Any(rf => rf.FunctionId == apifunction.Id && rf.RoleId == admin.Id);
146+
147+
return new
148+
{
149+
webapp = hasWebAccess,
150+
api = hasApiAccess
151+
};
152+
}
153+
93154
// ----- helpers -----
94155

95156
protected virtual async Task<UserPermissionsDto> BuildPermissionsForUser(int userId)
@@ -159,11 +220,11 @@ protected virtual string GenerateJwt(AppUser user, out DateTime expiresAtUtc)
159220

160221
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keyPlain));
161222
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
162-
223+
163224
var claims = new List<Claim>
164225
{
165226
new(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
166-
new(JwtRegisteredClaimNames.UniqueName, user.UserName)
227+
new(JwtRegisteredClaimNames.UniqueName, user.UserName)
167228
};
168229

169230
var now = DateTime.UtcNow;
@@ -179,5 +240,7 @@ protected virtual string GenerateJwt(AppUser user, out DateTime expiresAtUtc)
179240

180241
return new JwtSecurityTokenHandler().WriteToken(token);
181242
}
243+
244+
182245
}
183246
}

0 commit comments

Comments
 (0)