codekingpro/portable-devtools
114k
1from authlib.oauth2.rfc8414 import AuthorizationServerMetadata2from authlib.oauth2.rfc8414.models import validate_array_value3 4 5class OpenIDProviderMetadata(AuthorizationServerMetadata):6 REGISTRY_KEYS = [7 'issuer', 'authorization_endpoint', 'token_endpoint',8 'jwks_uri', 'registration_endpoint', 'scopes_supported',9 'response_types_supported', 'response_modes_supported',10 'grant_types_supported',11 'token_endpoint_auth_methods_supported',12 'token_endpoint_auth_signing_alg_values_supported',13 'service_documentation', 'ui_locales_supported',14 'op_policy_uri', 'op_tos_uri',15 16 # added by OpenID17 'acr_values_supported', 'subject_types_supported',18 'id_token_signing_alg_values_supported',19 'id_token_encryption_alg_values_supported',20 'id_token_encryption_enc_values_supported',21 'userinfo_signing_alg_values_supported',22 'userinfo_encryption_alg_values_supported',23 'userinfo_encryption_enc_values_supported',24 'request_object_signing_alg_values_supported',25 'request_object_encryption_alg_values_supported',26 'request_object_encryption_enc_values_supported',27 'display_values_supported',28 'claim_types_supported',29 'claims_supported',30 'claims_locales_supported',31 'claims_parameter_supported',32 'request_parameter_supported',33 'request_uri_parameter_supported',34 'require_request_uri_registration',35 36 # not defined by OpenID37 # 'revocation_endpoint',38 # 'revocation_endpoint_auth_methods_supported',39 # 'revocation_endpoint_auth_signing_alg_values_supported',40 # 'introspection_endpoint',41 # 'introspection_endpoint_auth_methods_supported',42 # 'introspection_endpoint_auth_signing_alg_values_supported',43 # 'code_challenge_methods_supported',44 ]45 46 def validate_jwks_uri(self):47 # REQUIRED in OpenID Connect48 jwks_uri = self.get('jwks_uri')49 if jwks_uri is None:50 raise ValueError('"jwks_uri" is required')51 return super().validate_jwks_uri()52 53 def validate_acr_values_supported(self):54 """OPTIONAL. JSON array containing a list of the Authentication55 Context Class References that this OP supports.56 """57 validate_array_value(self, 'acr_values_supported')58 59 def validate_subject_types_supported(self):60 """REQUIRED. JSON array containing a list of the Subject Identifier61 types that this OP supports. Valid types include pairwise and public.62 """63 # 1. REQUIRED64 values = self.get('subject_types_supported')65 if values is None:66 raise ValueError('"subject_types_supported" is required')67 68 # 2. JSON array69 if not isinstance(values, list):70 raise ValueError('"subject_types_supported" MUST be JSON array')71 72 # 3. Valid types include pairwise and public73 valid_types = {'pairwise', 'public'}74 if not valid_types.issuperset(set(values)):75 raise ValueError(76 '"subject_types_supported" contains invalid values')77 78 def validate_id_token_signing_alg_values_supported(self):79 """REQUIRED. JSON array containing a list of the JWS signing80 algorithms (alg values) supported by the OP for the ID Token to81 encode the Claims in a JWT [JWT]. The algorithm RS256 MUST be82 included. The value none MAY be supported, but MUST NOT be used83 unless the Response Type used returns no ID Token from the84 Authorization Endpoint (such as when using the Authorization85 Code Flow).86 """87 # 1. REQUIRED88 values = self.get('id_token_signing_alg_values_supported')89 if values is None:90 raise ValueError('"id_token_signing_alg_values_supported" is required')91 92 # 2. JSON array93 if not isinstance(values, list):94 raise ValueError('"id_token_signing_alg_values_supported" MUST be JSON array')95 96 # 3. The algorithm RS256 MUST be included97 if 'RS256' not in values:98 raise ValueError(99 '"RS256" MUST be included in "id_token_signing_alg_values_supported"')100 101 def validate_id_token_encryption_alg_values_supported(self):102 """OPTIONAL. JSON array containing a list of the JWE encryption103 algorithms (alg values) supported by the OP for the ID Token to104 encode the Claims in a JWT.105 """106 validate_array_value(self, 'id_token_encryption_alg_values_supported')107 108 def validate_id_token_encryption_enc_values_supported(self):109 """OPTIONAL. JSON array containing a list of the JWE encryption110 algorithms (enc values) supported by the OP for the ID Token to111 encode the Claims in a JWT.112 """113 validate_array_value(self, 'id_token_encryption_enc_values_supported')114 115 def validate_userinfo_signing_alg_values_supported(self):116 """OPTIONAL. JSON array containing a list of the JWS signing117 algorithms (alg values) [JWA] supported by the UserInfo Endpoint118 to encode the Claims in a JWT. The value none MAY be included.119 """120 validate_array_value(self, 'userinfo_signing_alg_values_supported')121 122 def validate_userinfo_encryption_alg_values_supported(self):123 """OPTIONAL. JSON array containing a list of the JWE encryption124 algorithms (alg values) [JWA] supported by the UserInfo Endpoint125 to encode the Claims in a JWT.126 """127 validate_array_value(self, 'userinfo_encryption_alg_values_supported')128 129 def validate_userinfo_encryption_enc_values_supported(self):130 """OPTIONAL. JSON array containing a list of the JWE encryption131 algorithms (enc values) [JWA] supported by the UserInfo Endpoint132 to encode the Claims in a JWT.133 """134 validate_array_value(self, 'userinfo_encryption_enc_values_supported')135 136 def validate_request_object_signing_alg_values_supported(self):137 """OPTIONAL. JSON array containing a list of the JWS signing138 algorithms (alg values) supported by the OP for Request Objects,139 which are described in Section 6.1 of OpenID Connect Core 1.0.140 These algorithms are used both when the Request Object is passed141 by value (using the request parameter) and when it is passed by142 reference (using the request_uri parameter). Servers SHOULD support143 none and RS256.144 """145 values = self.get('request_object_signing_alg_values_supported')146 if not values:147 return148 149 if not isinstance(values, list):150 raise ValueError('"request_object_signing_alg_values_supported" MUST be JSON array')151 152 # Servers SHOULD support none and RS256153 if 'none' not in values or 'RS256' not in values:154 raise ValueError(155 '"request_object_signing_alg_values_supported" '156 'SHOULD support none and RS256')157 158 def validate_request_object_encryption_alg_values_supported(self):159 """OPTIONAL. JSON array containing a list of the JWE encryption160 algorithms (alg values) supported by the OP for Request Objects.161 These algorithms are used both when the Request Object is passed162 by value and when it is passed by reference.163 """164 validate_array_value(self, 'request_object_encryption_alg_values_supported')165 166 def validate_request_object_encryption_enc_values_supported(self):167 """OPTIONAL. JSON array containing a list of the JWE encryption168 algorithms (enc values) supported by the OP for Request Objects.169 These algorithms are used both when the Request Object is passed170 by value and when it is passed by reference.171 """172 validate_array_value(self, 'request_object_encryption_enc_values_supported')173 174 def validate_display_values_supported(self):175 """OPTIONAL. JSON array containing a list of the display parameter176 values that the OpenID Provider supports. These values are described177 in Section 3.1.2.1 of OpenID Connect Core 1.0.178 """179 values = self.get('display_values_supported')180 if not values:181 return182 183 if not isinstance(values, list):184 raise ValueError('"display_values_supported" MUST be JSON array')185 186 valid_values = {'page', 'popup', 'touch', 'wap'}187 if not valid_values.issuperset(set(values)):188 raise ValueError('"display_values_supported" contains invalid values')189 190 def validate_claim_types_supported(self):191 """OPTIONAL. JSON array containing a list of the Claim Types that192 the OpenID Provider supports. These Claim Types are described in193 Section 5.6 of OpenID Connect Core 1.0. Values defined by this194 specification are normal, aggregated, and distributed. If omitted,195 the implementation supports only normal Claims.196 """197 values = self.get('claim_types_supported')198 if not values:199 return200 201 if not isinstance(values, list):202 raise ValueError('"claim_types_supported" MUST be JSON array')203 204 valid_values = {'normal', 'aggregated', 'distributed'}205 if not valid_values.issuperset(set(values)):206 raise ValueError('"claim_types_supported" contains invalid values')207 208 def validate_claims_supported(self):209 """RECOMMENDED. JSON array containing a list of the Claim Names210 of the Claims that the OpenID Provider MAY be able to supply values211 for. Note that for privacy or other reasons, this might not be an212 exhaustive list.213 """214 validate_array_value(self, 'claims_supported')215 216 def validate_claims_locales_supported(self):217 """OPTIONAL. Languages and scripts supported for values in Claims218 being returned, represented as a JSON array of BCP47 [RFC5646]219 language tag values. Not all languages and scripts are necessarily220 supported for all Claim values.221 """222 validate_array_value(self, 'claims_locales_supported')223 224 def validate_claims_parameter_supported(self):225 """OPTIONAL. Boolean value specifying whether the OP supports use of226 the claims parameter, with true indicating support. If omitted, the227 default value is false.228 """229 _validate_boolean_value(self, 'claims_parameter_supported')230 231 def validate_request_parameter_supported(self):232 """OPTIONAL. Boolean value specifying whether the OP supports use of233 the request parameter, with true indicating support. If omitted, the234 default value is false.235 """236 _validate_boolean_value(self, 'request_parameter_supported')237 238 def validate_request_uri_parameter_supported(self):239 """OPTIONAL. Boolean value specifying whether the OP supports use of240 the request_uri parameter, with true indicating support. If omitted,241 the default value is true.242 """243 _validate_boolean_value(self, 'request_uri_parameter_supported')244 245 def validate_require_request_uri_registration(self):246 """OPTIONAL. Boolean value specifying whether the OP requires any247 request_uri values used to be pre-registered using the request_uris248 registration parameter. Pre-registration is REQUIRED when the value249 is true. If omitted, the default value is false.250 """251 _validate_boolean_value(self, 'require_request_uri_registration')252 253 @property254 def claim_types_supported(self):255 # If omitted, the implementation supports only normal Claims256 return self.get('claim_types_supported', ['normal'])257 258 @property259 def claims_parameter_supported(self):260 # If omitted, the default value is false.261 return self.get('claims_parameter_supported', False)262 263 @property264 def request_parameter_supported(self):265 # If omitted, the default value is false.266 return self.get('request_parameter_supported', False)267 268 @property269 def request_uri_parameter_supported(self):270 # If omitted, the default value is true.271 return self.get('request_uri_parameter_supported', True)272 273 @property274 def require_request_uri_registration(self):275 # If omitted, the default value is false.276 return self.get('require_request_uri_registration', False)277 278 279def _validate_boolean_value(metadata, key):280 if key not in metadata:281 return282 if metadata[key] not in (True, False):283 raise ValueError(f'"{key}" MUST be boolean')284 