1515OAuth2 Provider settings, checking for user settings first, then falling
1616back to the defaults.
1717"""
18- import importlib
1918
2019from django .conf import settings
2120from django .core .exceptions import ImproperlyConfigured
21+ from django .test .signals import setting_changed
22+ from django .utils .module_loading import import_string
2223
2324
2425USER_SETTINGS = getattr (settings , "OAUTH2_PROVIDER" , None )
5354 "ACCESS_TOKEN_MODEL" : ACCESS_TOKEN_MODEL ,
5455 "GRANT_MODEL" : GRANT_MODEL ,
5556 "REFRESH_TOKEN_MODEL" : REFRESH_TOKEN_MODEL ,
57+ "APPLICATION_ADMIN_CLASS" : "oauth2_provider.admin.ApplicationAdmin" ,
58+ "ACCESS_TOKEN_ADMIN_CLASS" : "oauth2_provider.admin.AccessTokenAdmin" ,
59+ "GRANT_ADMIN_CLASS" : "oauth2_provider.admin.GrantAdmin" ,
60+ "REFRESH_TOKEN_ADMIN_CLASS" : "oauth2_provider.admin.RefreshTokenAdmin" ,
5661 "REQUEST_APPROVAL_PROMPT" : "force" ,
5762 "ALLOWED_REDIRECT_URI_SCHEMES" : ["http" , "https" ],
5863 # Special settings that will be evaluated at runtime
8893 "OAUTH2_VALIDATOR_CLASS" ,
8994 "OAUTH2_BACKEND_CLASS" ,
9095 "SCOPES_BACKEND_CLASS" ,
96+ "APPLICATION_ADMIN_CLASS" ,
97+ "ACCESS_TOKEN_ADMIN_CLASS" ,
98+ "GRANT_ADMIN_CLASS" ,
99+ "REFRESH_TOKEN_ADMIN_CLASS" ,
91100)
92101
93102
@@ -96,23 +105,21 @@ def perform_import(val, setting_name):
96105 If the given setting is a string import notation,
97106 then perform the necessary import or imports.
98107 """
99- if isinstance ( val , ( list , tuple )) :
100- return [ import_from_string ( item , setting_name ) for item in val ]
101- elif "." in val :
108+ if val is None :
109+ return None
110+ elif isinstance ( val , str ) :
102111 return import_from_string (val , setting_name )
103- else :
104- raise ImproperlyConfigured ("Bad value for %r: %r" % (setting_name , val ))
112+ elif isinstance (val , (list , tuple )):
113+ return [import_from_string (item , setting_name ) for item in val ]
114+ return val
105115
106116
107117def import_from_string (val , setting_name ):
108118 """
109119 Attempt to import a class from a string representation.
110120 """
111121 try :
112- parts = val .split ("." )
113- module_path , class_name = "." .join (parts [:- 1 ]), parts [- 1 ]
114- module = importlib .import_module (module_path )
115- return getattr (module , class_name )
122+ return import_string (val )
116123 except ImportError as e :
117124 msg = "Could not import %r for setting %r. %s: %s." % (val , setting_name , e .__class__ .__name__ , e )
118125 raise ImportError (msg )
@@ -127,14 +134,21 @@ class OAuth2ProviderSettings:
127134 """
128135
129136 def __init__ (self , user_settings = None , defaults = None , import_strings = None , mandatory = None ):
130- self .user_settings = user_settings or {}
131- self .defaults = defaults or {}
132- self .import_strings = import_strings or ()
137+ self ._user_settings = user_settings or {}
138+ self .defaults = defaults or DEFAULTS
139+ self .import_strings = import_strings or IMPORT_STRINGS
133140 self .mandatory = mandatory or ()
141+ self ._cached_attrs = set ()
142+
143+ @property
144+ def user_settings (self ):
145+ if not hasattr (self , "_user_settings" ):
146+ self ._user_settings = getattr (settings , "OAUTH2_PROVIDER" , {})
147+ return self ._user_settings
134148
135149 def __getattr__ (self , attr ):
136- if attr not in self .defaults . keys () :
137- raise AttributeError ("Invalid OAuth2Provider setting: %r " % ( attr ) )
150+ if attr not in self .defaults :
151+ raise AttributeError ("Invalid OAuth2Provider setting: %s " % attr )
138152
139153 try :
140154 # Check if present in user settings
@@ -166,12 +180,13 @@ def __getattr__(self, attr):
166180 self .validate_setting (attr , val )
167181
168182 # Cache the result
183+ self ._cached_attrs .add (attr )
169184 setattr (self , attr , val )
170185 return val
171186
172187 def validate_setting (self , attr , val ):
173188 if not val and attr in self .mandatory :
174- raise AttributeError ("OAuth2Provider setting: %r is mandatory" % ( attr ) )
189+ raise AttributeError ("OAuth2Provider setting: %s is mandatory" % attr )
175190
176191 @property
177192 def server_kwargs (self ):
@@ -199,5 +214,21 @@ def server_kwargs(self):
199214 kwargs .update (self .EXTRA_SERVER_KWARGS )
200215 return kwargs
201216
217+ def reload (self ):
218+ for attr in self ._cached_attrs :
219+ delattr (self , attr )
220+ self ._cached_attrs .clear ()
221+ if hasattr (self , "_user_settings" ):
222+ delattr (self , "_user_settings" )
223+
202224
203225oauth2_settings = OAuth2ProviderSettings (USER_SETTINGS , DEFAULTS , IMPORT_STRINGS , MANDATORY )
226+
227+
228+ def reload_oauth2_settings (* args , ** kwargs ):
229+ setting = kwargs ["setting" ]
230+ if setting == "OAUTH2_PROVIDER" :
231+ oauth2_settings .reload ()
232+
233+
234+ setting_changed .connect (reload_oauth2_settings )
0 commit comments