@@ -216,8 +216,6 @@ struct PasswordUserInput {
216
216
username : String ,
217
217
#[ graphql( secret) ]
218
218
password : String ,
219
- /// If provided, that means an admin tried to create an account.
220
- creator_user_id : Option < String > ,
221
219
}
222
220
223
221
#[ derive( Debug , InputObject , Serialize , Deserialize , Clone ) ]
@@ -233,13 +231,11 @@ enum AuthUserInput {
233
231
Oidc ( OidcUserInput ) ,
234
232
}
235
233
236
- impl AuthUserInput {
237
- fn creator_user_id ( & self ) -> Option < String > {
238
- match self {
239
- Self :: Password ( p) => p. creator_user_id . clone ( ) ,
240
- _ => None ,
241
- }
242
- }
234
+ #[ derive( Debug , InputObject ) ]
235
+ struct RegisterUserInput {
236
+ data : AuthUserInput ,
237
+ /// If registration is disabled, this can be used to override it.
238
+ admin_access_token : Option < String > ,
243
239
}
244
240
245
241
#[ derive( Enum , Clone , Debug , Copy , PartialEq , Eq ) ]
@@ -261,6 +257,7 @@ enum RegisterResult {
261
257
262
258
#[ derive( Enum , Clone , Debug , Copy , PartialEq , Eq ) ]
263
259
enum LoginErrorVariant {
260
+ AccountDisabled ,
264
261
UsernameDoesNotExist ,
265
262
CredentialsMismatch ,
266
263
IncorrectProviderChosen ,
@@ -284,10 +281,14 @@ enum LoginResult {
284
281
285
282
#[ derive( Debug , InputObject ) ]
286
283
struct UpdateUserInput {
287
- username : Option < String > ,
284
+ user_id : String ,
285
+ is_disabled : Option < bool > ,
286
+ lot : Option < UserLot > ,
288
287
#[ graphql( secret) ]
289
288
password : Option < String > ,
289
+ username : Option < String > ,
290
290
extra_information : Option < serde_json:: Value > ,
291
+ admin_access_token : Option < String > ,
291
292
}
292
293
293
294
#[ derive( Debug , InputObject ) ]
@@ -1252,7 +1253,7 @@ impl MiscellaneousMutation {
1252
1253
async fn register_user (
1253
1254
& self ,
1254
1255
gql_ctx : & Context < ' _ > ,
1255
- input : AuthUserInput ,
1256
+ input : RegisterUserInput ,
1256
1257
) -> Result < RegisterResult > {
1257
1258
let service = gql_ctx. data_unchecked :: < Arc < MiscellaneousService > > ( ) ;
1258
1259
service. register_user ( input) . await
@@ -1271,7 +1272,7 @@ impl MiscellaneousMutation {
1271
1272
input : UpdateUserInput ,
1272
1273
) -> Result < StringIdObject > {
1273
1274
let service = gql_ctx. data_unchecked :: < Arc < MiscellaneousService > > ( ) ;
1274
- let user_id = self . user_id_from_ctx ( gql_ctx) . await ? ;
1275
+ let user_id = self . user_id_from_ctx ( gql_ctx) . await . ok ( ) ;
1275
1276
service. update_user ( user_id, input) . await
1276
1277
}
1277
1278
@@ -3715,9 +3716,13 @@ impl MiscellaneousService {
3715
3716
. await ,
3716
3717
) ,
3717
3718
MediaSource :: Tmdb => Box :: new ( self . get_tmdb_non_media_service ( ) . await ?) ,
3718
- MediaSource :: Anilist => {
3719
- Box :: new ( NonMediaAnilistService :: new ( self . config . frontend . page_size ) . await )
3720
- }
3719
+ MediaSource :: Anilist => Box :: new (
3720
+ NonMediaAnilistService :: new (
3721
+ & self . config . anime_and_manga . anilist ,
3722
+ self . config . frontend . page_size ,
3723
+ )
3724
+ . await ,
3725
+ ) ,
3721
3726
MediaSource :: Mal => Box :: new ( NonMediaMalService :: new ( ) . await ) ,
3722
3727
MediaSource :: Custom => return err ( ) ,
3723
3728
} ;
@@ -4854,33 +4859,33 @@ impl MiscellaneousService {
4854
4859
Ok ( ( ) )
4855
4860
}
4856
4861
4857
- async fn register_user ( & self , input : AuthUserInput ) -> Result < RegisterResult > {
4858
- if let Some ( user_id ) = input . creator_user_id ( ) {
4859
- self . admin_account_guard ( & user_id ) . await ? ;
4860
- } else if ! self . config . users . allow_registration {
4862
+ async fn register_user ( & self , input : RegisterUserInput ) -> Result < RegisterResult > {
4863
+ if ! self . config . users . allow_registration
4864
+ && input . admin_access_token . unwrap_or_default ( ) != self . config . server . admin_access_token
4865
+ {
4861
4866
return Ok ( RegisterResult :: Error ( RegisterError {
4862
4867
error : RegisterErrorVariant :: Disabled ,
4863
4868
} ) ) ;
4864
4869
}
4865
- let ( filter, username, password) = match input. clone ( ) {
4866
- AuthUserInput :: Oidc ( input ) => (
4867
- user:: Column :: OidcIssuerId . eq ( & input . issuer_id ) ,
4868
- input . email ,
4870
+ let ( filter, username, password) = match input. data . clone ( ) {
4871
+ AuthUserInput :: Oidc ( data ) => (
4872
+ user:: Column :: OidcIssuerId . eq ( & data . issuer_id ) ,
4873
+ data . email ,
4869
4874
None ,
4870
4875
) ,
4871
- AuthUserInput :: Password ( input ) => (
4872
- user:: Column :: Name . eq ( & input . username ) ,
4873
- input . username ,
4874
- Some ( input . password ) ,
4876
+ AuthUserInput :: Password ( data ) => (
4877
+ user:: Column :: Name . eq ( & data . username ) ,
4878
+ data . username ,
4879
+ Some ( data . password ) ,
4875
4880
) ,
4876
4881
} ;
4877
4882
if User :: find ( ) . filter ( filter) . count ( & self . db ) . await . unwrap ( ) != 0 {
4878
4883
return Ok ( RegisterResult :: Error ( RegisterError {
4879
4884
error : RegisterErrorVariant :: IdentifierAlreadyExists ,
4880
4885
} ) ) ;
4881
4886
} ;
4882
- let oidc_issuer_id = match input {
4883
- AuthUserInput :: Oidc ( input ) => Some ( input . issuer_id ) ,
4887
+ let oidc_issuer_id = match input. data {
4888
+ AuthUserInput :: Oidc ( data ) => Some ( data . issuer_id ) ,
4884
4889
AuthUserInput :: Password ( _) => None ,
4885
4890
} ;
4886
4891
let lot = if User :: find ( ) . count ( & self . db ) . await . unwrap ( ) == 0 {
@@ -4914,6 +4919,11 @@ impl MiscellaneousService {
4914
4919
error : LoginErrorVariant :: UsernameDoesNotExist ,
4915
4920
} ) ) ,
4916
4921
Some ( user) => {
4922
+ if user. is_disabled . unwrap_or_default ( ) {
4923
+ return Ok ( LoginResult :: Error ( LoginError {
4924
+ error : LoginErrorVariant :: AccountDisabled ,
4925
+ } ) ) ;
4926
+ }
4917
4927
if self . config . users . validate_password {
4918
4928
if let AuthUserInput :: Password ( PasswordUserInput { password, .. } ) = input {
4919
4929
if let Some ( hashed_password) = user. password {
@@ -4958,8 +4968,17 @@ impl MiscellaneousService {
4958
4968
Ok ( ( ) )
4959
4969
}
4960
4970
4961
- async fn update_user ( & self , user_id : String , input : UpdateUserInput ) -> Result < StringIdObject > {
4962
- let mut user_obj: user:: ActiveModel = User :: find_by_id ( user_id. to_owned ( ) )
4971
+ async fn update_user (
4972
+ & self ,
4973
+ user_id : Option < String > ,
4974
+ input : UpdateUserInput ,
4975
+ ) -> Result < StringIdObject > {
4976
+ if user_id. unwrap_or_default ( ) != input. user_id
4977
+ && input. admin_access_token . unwrap_or_default ( ) != self . config . server . admin_access_token
4978
+ {
4979
+ return Err ( Error :: new ( "Admin access token mismatch" . to_owned ( ) ) ) ;
4980
+ }
4981
+ let mut user_obj: user:: ActiveModel = User :: find_by_id ( input. user_id )
4963
4982
. one ( & self . db )
4964
4983
. await
4965
4984
. unwrap ( )
@@ -4974,6 +4993,12 @@ impl MiscellaneousService {
4974
4993
if let Some ( i) = input. extra_information {
4975
4994
user_obj. extra_information = ActiveValue :: Set ( Some ( i) ) ;
4976
4995
}
4996
+ if let Some ( l) = input. lot {
4997
+ user_obj. lot = ActiveValue :: Set ( l) ;
4998
+ }
4999
+ if let Some ( d) = input. is_disabled {
5000
+ user_obj. is_disabled = ActiveValue :: Set ( Some ( d) ) ;
5001
+ }
4977
5002
let user_obj = user_obj. update ( & self . db ) . await . unwrap ( ) ;
4978
5003
Ok ( StringIdObject { id : user_obj. id } )
4979
5004
}
@@ -5791,19 +5816,20 @@ impl MiscellaneousService {
5791
5816
async fn admin_account_guard ( & self , user_id : & String ) -> Result < ( ) > {
5792
5817
let main_user = user_by_id ( & self . db , user_id) . await ?;
5793
5818
if main_user. lot != UserLot :: Admin {
5794
- return Err ( Error :: new ( "Only admins can perform this operation." ) ) ;
5819
+ return Err ( Error :: new ( BackendError :: AdminOnlyAction . to_string ( ) ) ) ;
5795
5820
}
5796
5821
Ok ( ( ) )
5797
5822
}
5798
5823
5799
5824
async fn users_list ( & self , query : Option < String > ) -> Result < Vec < user:: Model > > {
5800
- Ok ( User :: find ( )
5825
+ let users = User :: find ( )
5801
5826
. apply_if ( query, |query, value| {
5802
5827
query. filter ( Expr :: col ( user:: Column :: Name ) . ilike ( ilike_sql ( & value) ) )
5803
5828
} )
5804
5829
. order_by_asc ( user:: Column :: Name )
5805
5830
. all ( & self . db )
5806
- . await ?)
5831
+ . await ?;
5832
+ Ok ( users)
5807
5833
}
5808
5834
5809
5835
async fn delete_user ( & self , to_delete_user_id : String ) -> Result < bool > {
0 commit comments