feat(backend): limit total members per user
This commit is contained in:
		
							parent
							
								
									80ac16694c
								
							
						
					
					
						commit
						4002893323
					
				
					 3 changed files with 21 additions and 4 deletions
				
			
		|  | @ -41,6 +41,8 @@ public class MembersController( | ||||||
|         return Ok(memberRenderer.RenderMember(member, CurrentToken)); |         return Ok(memberRenderer.RenderMember(member, CurrentToken)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public const int MaxMemberCount = 500; | ||||||
|  | 
 | ||||||
|     [HttpPost("/api/v2/users/@me/members")] |     [HttpPost("/api/v2/users/@me/members")] | ||||||
|     [ProducesResponseType<MemberRendererService.MemberResponse>(StatusCodes.Status200OK)] |     [ProducesResponseType<MemberRendererService.MemberResponse>(StatusCodes.Status200OK)] | ||||||
|     [Authorize("member.create")] |     [Authorize("member.create")] | ||||||
|  | @ -58,6 +60,10 @@ public class MembersController( | ||||||
|             .. ValidationUtils.ValidateLinks(req.Links) |             .. ValidationUtils.ValidateLinks(req.Links) | ||||||
|         ]); |         ]); | ||||||
| 
 | 
 | ||||||
|  |         var memberCount = await db.Members.CountAsync(m => m.UserId == CurrentUser.Id, ct); | ||||||
|  |         if (memberCount >= MaxMemberCount) | ||||||
|  |             throw new ApiError.BadRequest("Maximum number of members reached"); | ||||||
|  | 
 | ||||||
|         var member = new Member |         var member = new Member | ||||||
|         { |         { | ||||||
|             Id = snowflakeGenerator.GenerateSnowflake(), |             Id = snowflakeGenerator.GenerateSnowflake(), | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | using Foxnouns.Backend.Utils; | ||||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||||
| 
 | 
 | ||||||
| namespace Foxnouns.Backend.Controllers; | namespace Foxnouns.Backend.Controllers; | ||||||
|  | @ -18,14 +19,22 @@ public class MetaController : ApiControllerBase | ||||||
|                 (int)FoxnounsMetrics.UsersActiveMonthCount.Value, |                 (int)FoxnounsMetrics.UsersActiveMonthCount.Value, | ||||||
|                 (int)FoxnounsMetrics.UsersActiveWeekCount.Value, |                 (int)FoxnounsMetrics.UsersActiveWeekCount.Value, | ||||||
|                 (int)FoxnounsMetrics.UsersActiveDayCount.Value |                 (int)FoxnounsMetrics.UsersActiveDayCount.Value | ||||||
|             )) |             ), | ||||||
|  |             new Limits( | ||||||
|  |                 MemberCount: MembersController.MaxMemberCount, | ||||||
|  |                 BioLength: ValidationUtils.MaxBioLength)) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     [HttpGet("/api/v2/coffee")] |     [HttpGet("/api/v2/coffee")] | ||||||
|     public IActionResult BrewCoffee() => Problem("Sorry, I'm a teapot!", statusCode: StatusCodes.Status418ImATeapot); |     public IActionResult BrewCoffee() => Problem("Sorry, I'm a teapot!", statusCode: StatusCodes.Status418ImATeapot); | ||||||
| 
 | 
 | ||||||
|     private record MetaResponse(string Repository, string Version, string Hash, int Members, UserInfo Users); |     private record MetaResponse(string Repository, string Version, string Hash, int Members, UserInfo Users, Limits Limits); | ||||||
| 
 | 
 | ||||||
|     private record UserInfo(int Total, int ActiveMonth, int ActiveWeek, int ActiveDay); |     private record UserInfo(int Total, int ActiveMonth, int ActiveWeek, int ActiveDay); | ||||||
|  | 
 | ||||||
|  |     // All limits that the frontend should know about (for UI purposes) | ||||||
|  |     private record Limits( | ||||||
|  |         int MemberCount, | ||||||
|  |         int BioLength); | ||||||
| } | } | ||||||
|  | @ -127,12 +127,14 @@ public static class ValidationUtils | ||||||
|         return errors; |         return errors; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public const int MaxBioLength = 1024; | ||||||
|  |      | ||||||
|     public static ValidationError? ValidateBio(string? bio) |     public static ValidationError? ValidateBio(string? bio) | ||||||
|     { |     { | ||||||
|         return bio?.Length switch |         return bio?.Length switch | ||||||
|         { |         { | ||||||
|             0 => ValidationError.LengthError("Bio is too short", 1, 1024, bio.Length), |             0 => ValidationError.LengthError("Bio is too short", 1, MaxBioLength, bio.Length), | ||||||
|             > 1024 => ValidationError.LengthError("Bio is too long", 1, 1024, bio.Length), |             > MaxBioLength => ValidationError.LengthError("Bio is too long", 1, MaxBioLength, bio.Length), | ||||||
|             _ => null |             _ => null | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue