1+ use std:: sync:: Arc ;
2+ use axum:: extract:: { Path , State } ;
13use crate :: AppState ;
2- use axum:: Json ;
3- use axum:: routing:: get;
4+ use axum:: { Extension , Json } ;
5+ use axum:: routing:: { post, put} ;
6+ use http:: StatusCode ;
7+ use lambda_http:: tracing:: info;
8+ use serde:: { Deserialize , Serialize } ;
49use serde_json:: { Value , json} ;
510use tower_http:: cors:: CorsLayer ;
11+ use twilight_model:: id:: Id ;
12+ use twilight_model:: id:: marker:: { GuildMarker , RoleMarker } ;
13+ use twilight_model:: user:: CurrentUser ;
14+ use crate :: discord:: { add_guild_member_role, remove_guild_member_role} ;
15+ use crate :: guilds:: models:: Guild ;
16+ use crate :: guilds:: verify:: models:: { Verify , VerifyRole } ;
17+ use crate :: users:: utils:: link_arr_match;
18+ use crate :: utils:: is_client_admin_guild;
619
720pub fn router ( ) -> axum:: Router < AppState > {
8- axum:: Router :: new ( ) . route ( "/" , get ( get_verify) )
21+ axum:: Router :: new ( )
22+ . route ( "/recon" , post ( post_recon) )
23+ . route ( "/roles/{role_id}" , put ( put_roles_id) . delete ( delete_roles_id) )
924 . layer ( CorsLayer :: permissive ( ) )
1025}
1126
12- async fn get_verify ( ) -> Json < Value > {
13- Json ( json ! ( { "msg" : "I am GET /verify" } ) )
27+ #[ derive( Serialize , Deserialize ) ]
28+ struct PutRoleRequest {
29+ pub pattern : String ,
1430}
31+
32+ async fn put_roles_id (
33+ Path ( ( guild_id, role_id) ) : Path < ( Id < GuildMarker > , Id < RoleMarker > ) > ,
34+ Extension ( current_user) : Extension < CurrentUser > ,
35+ State ( app_state) : State < AppState > ,
36+ Json ( put_role_request) : Json < PutRoleRequest >
37+ ) -> Result < Json < Value > , StatusCode > {
38+ if !is_client_admin_guild ( guild_id, & current_user, & app_state. discord_bot ) . await ? {
39+ return Err ( StatusCode :: FORBIDDEN ) ;
40+ }
41+
42+ let mut guild = Guild :: from_db ( guild_id, & app_state. dynamo ) . await . unwrap ( ) ;
43+
44+ if guild. verify . roles . iter ( ) . any ( |r| r. role_id == role_id) {
45+ remove_existing_role ( & mut guild, role_id, & app_state) . await ?;
46+ }
47+
48+ let mut new_role = VerifyRole {
49+ role_id,
50+ pattern : put_role_request. pattern ,
51+ ..Default :: default ( )
52+ } ;
53+
54+ for ( user_id, user_links) in & guild. verify . user_links {
55+ if link_arr_match ( user_links, & new_role. pattern ) {
56+ add_guild_member_role ( guild. guild_id , * user_id, role_id, & app_state. discord_bot ) . await ?;
57+ new_role. members += 1 ;
58+ }
59+ }
60+ guild. verify . roles . push ( new_role) ;
61+ guild. save ( & app_state. dynamo ) . await ;
62+
63+ Ok ( Json ( json ! ( guild. verify. roles. iter( ) . find( |r| r. role_id == role_id) . unwrap( ) ) ) )
64+ }
65+
66+
67+ async fn delete_roles_id (
68+ Path ( ( guild_id, role_id) ) : Path < ( Id < GuildMarker > , Id < RoleMarker > ) > ,
69+ Extension ( current_user) : Extension < CurrentUser > ,
70+ State ( app_state) : State < AppState > ,
71+ ) -> Result < StatusCode , StatusCode > {
72+ if !is_client_admin_guild ( guild_id, & current_user, & app_state. discord_bot ) . await ? {
73+ return Err ( StatusCode :: FORBIDDEN ) ;
74+ }
75+
76+ let mut guild = Guild :: from_db ( guild_id, & app_state. dynamo ) . await . unwrap ( ) ;
77+
78+ remove_existing_role ( & mut guild, role_id, & app_state) . await ?;
79+
80+ guild. save ( & app_state. dynamo ) . await ;
81+
82+ Ok ( StatusCode :: NO_CONTENT )
83+ }
84+
85+ async fn remove_existing_role (
86+ guild : & mut Guild ,
87+ role_id : Id < RoleMarker > ,
88+ app_state : & AppState
89+ ) -> Result < ( ) , StatusCode > {
90+ let existing_role_opt = guild. verify . roles . iter ( ) . find ( |r| r. role_id == role_id) ;
91+
92+ if existing_role_opt. is_none ( ) {
93+ // No role found
94+ return Ok ( ( ) )
95+ }
96+ let existing_role = existing_role_opt. unwrap ( ) ;
97+
98+ for ( user_id, user_links) in & guild. verify . user_links {
99+ if link_arr_match ( user_links, & existing_role. pattern ) {
100+ remove_guild_member_role ( guild. guild_id , * user_id, role_id, & app_state. discord_bot ) . await ?
101+ }
102+ }
103+
104+ guild. verify . roles . retain ( |r| r. role_id != role_id) ;
105+ Ok ( ( ) )
106+ }
107+
108+ async fn post_recon (
109+ Path ( guild_id) : Path < Id < GuildMarker > > ,
110+ Extension ( discord_user) : Extension < Arc < twilight_http:: Client > > ,
111+ State ( app_state) : State < AppState > ,
112+ ) -> Result < StatusCode , StatusCode > {
113+ if discord_user. token ( ) != app_state. discord_bot . token ( ) {
114+ return Err ( StatusCode :: FORBIDDEN ) ;
115+ }
116+
117+ let mut guild = Guild :: from_db ( guild_id, & app_state. dynamo ) . await . unwrap ( ) ;
118+ let Verify { roles, user_links} = & mut guild. verify ;
119+
120+ for role in roles {
121+ role. members = 0 ;
122+ for ( user_id, links) in & * user_links {
123+ if link_arr_match ( links, & role. pattern ) {
124+ add_guild_member_role ( guild. guild_id , * user_id, role. role_id , & app_state. discord_bot ) . await ?;
125+ role. members += 1 ;
126+ } else {
127+ remove_guild_member_role ( guild. guild_id , * user_id, role. role_id , & app_state. discord_bot ) . await ?;
128+ }
129+ }
130+ }
131+ guild. save ( & app_state. dynamo ) . await ;
132+
133+ Ok ( StatusCode :: NO_CONTENT )
134+ }
0 commit comments