Add member routes to API
This commit is contained in:
		
							
								
								
									
										66
									
								
								PluralKit.API/Controllers/MemberController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								PluralKit.API/Controllers/MemberController.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| using System.Data; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using PluralKit.Core; | ||||
|  | ||||
| namespace PluralKit.API.Controllers | ||||
| { | ||||
|     [ApiController] | ||||
|     [Route("m")] | ||||
|     public class MemberController: ControllerBase | ||||
|     { | ||||
|         private MemberStore _members; | ||||
|         private IDbConnection _conn; | ||||
|         private TokenAuthService _auth; | ||||
|  | ||||
|         public MemberController(MemberStore members, IDbConnection conn, TokenAuthService auth) | ||||
|         { | ||||
|             _members = members; | ||||
|             _conn = conn; | ||||
|             _auth = auth; | ||||
|         } | ||||
|  | ||||
|         [HttpGet("{hid}")] | ||||
|         public async Task<ActionResult<PKMember>> GetMember(string hid) | ||||
|         { | ||||
|             var member = await _members.GetByHid(hid); | ||||
|             if (member == null) return NotFound("Member not found."); | ||||
|  | ||||
|             return Ok(member); | ||||
|         } | ||||
|  | ||||
|         [HttpPatch("{hid}")] | ||||
|         [RequiresSystem] | ||||
|         public async Task<ActionResult<PKMember>> PatchMember(string hid, [FromBody] PKMember newMember) | ||||
|         { | ||||
|             var member = await _members.GetByHid(hid); | ||||
|             if (member == null) return NotFound("Member not found."); | ||||
|  | ||||
|             if (member.System != _auth.CurrentSystem.Id) return Unauthorized($"Member '{hid}' is not part of your system."); | ||||
|  | ||||
|             // Explicit bounds checks | ||||
|             if (newMember.Name.Length > Limits.MaxMemberNameLength) | ||||
|                 return BadRequest($"Member name too long ({newMember.Name.Length} > {Limits.MaxMemberNameLength}."); | ||||
|             if (newMember.Pronouns.Length > Limits.MaxPronounsLength) | ||||
|                 return BadRequest($"Member pronouns too long ({newMember.Pronouns.Length} > {Limits.MaxPronounsLength}."); | ||||
|             if (newMember.Description.Length > Limits.MaxDescriptionLength) | ||||
|                 return BadRequest($"Member descriptions too long ({newMember.Description.Length} > {Limits.MaxDescriptionLength}."); | ||||
|  | ||||
|             // Sanity bounds checks | ||||
|             if (newMember.AvatarUrl.Length > 1000 || newMember.Prefix.Length > 1000 || newMember.Suffix.Length > 1000) | ||||
|                 return BadRequest(); | ||||
|  | ||||
|             member.Name = newMember.Name; | ||||
|             member.Color = newMember.Color; | ||||
|             member.AvatarUrl = newMember.AvatarUrl; | ||||
|             member.Birthday = newMember.Birthday; | ||||
|             member.Pronouns = newMember.Pronouns; | ||||
|             member.Description = newMember.Description; | ||||
|             member.Prefix = newMember.Prefix; | ||||
|             member.Suffix = newMember.Suffix; | ||||
|             await _members.Save(member); | ||||
|              | ||||
|             return Ok(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -99,9 +99,9 @@ namespace PluralKit.API.Controllers | ||||
|         } | ||||
|  | ||||
|         [HttpPatch] | ||||
|         [RequiresSystem] | ||||
|         public async Task<ActionResult<PKSystem>> EditSystem([FromBody] PKSystem newSystem) | ||||
|         { | ||||
|             if (_auth.CurrentSystem == null) return Unauthorized("No token specified in Authorization header."); | ||||
|             var system = _auth.CurrentSystem; | ||||
|              | ||||
|             system.Name = newSystem.Name; | ||||
| @@ -115,10 +115,9 @@ namespace PluralKit.API.Controllers | ||||
|         } | ||||
|  | ||||
|         [HttpPost("switches")] | ||||
|         [RequiresSystem] | ||||
|         public async Task<IActionResult> PostSwitch([FromBody] PostSwitchParams param) | ||||
|         { | ||||
|             if (_auth.CurrentSystem == null) return Unauthorized("No token specified in Authorization header."); | ||||
|  | ||||
|             if (param.Members.Distinct().Count() != param.Members.Count()) | ||||
|                 return BadRequest("Duplicate members in member list."); | ||||
|              | ||||
|   | ||||
							
								
								
									
										23
									
								
								PluralKit.API/RequiresSystemAttribute.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								PluralKit.API/RequiresSystemAttribute.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.Mvc.Filters; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
|  | ||||
| namespace PluralKit.API | ||||
| { | ||||
|     public class RequiresSystemAttribute: ActionFilterAttribute | ||||
|     { | ||||
|  | ||||
|         public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) | ||||
|         { | ||||
|             var auth = context.HttpContext.RequestServices.GetRequiredService<TokenAuthService>(); | ||||
|             if (auth.CurrentSystem == null) | ||||
|             { | ||||
|                 context.Result = new UnauthorizedObjectResult("Invalid or missing token in Authorization header."); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await base.OnActionExecutionAsync(context, next); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -6,6 +6,7 @@ using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NodaTime; | ||||
| using PluralKit.Core; | ||||
| using Image = SixLabors.ImageSharp.Image; | ||||
|  | ||||
| namespace PluralKit.Bot.Commands | ||||
|   | ||||
| @@ -9,6 +9,7 @@ using NodaTime; | ||||
| using NodaTime.Extensions; | ||||
| using NodaTime.Text; | ||||
| using NodaTime.TimeZones; | ||||
| using PluralKit.Core; | ||||
|  | ||||
| namespace PluralKit.Bot.Commands | ||||
| { | ||||
|   | ||||
| @@ -4,6 +4,7 @@ using System.Linq; | ||||
| using System.Net; | ||||
| using Humanizer; | ||||
| using NodaTime; | ||||
| using PluralKit.Core; | ||||
|  | ||||
| namespace PluralKit.Bot { | ||||
|     public static class Errors { | ||||
|   | ||||
| @@ -12,6 +12,7 @@ using Discord.Commands.Builders; | ||||
| using Discord.WebSocket; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using NodaTime; | ||||
| using PluralKit.Core; | ||||
| using Image = SixLabors.ImageSharp.Image; | ||||
|  | ||||
| namespace PluralKit.Bot | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| namespace PluralKit.Bot { | ||||
| namespace PluralKit.Core { | ||||
|     public static class Limits { | ||||
|         public static readonly int MaxSystemNameLength = 100; | ||||
|         public static readonly int MaxSystemTagLength = 31; | ||||
		Reference in New Issue
	
	Block a user