|
8 | 8 |
|
9 | 9 | In order to configure some objects in PyOIDC, you need a settings object. |
10 | 10 | If you need to add some settings, make sure that you settings class inherits from the appropriate class in this module. |
| 11 | +
|
| 12 | +The settings make use of `pydantic <https://docs.pydantic.dev/usage/settings/>`_ library. |
| 13 | +It is possible to instance them directly or use environment values to fill the settings. |
11 | 14 | """ |
12 | | -import typing |
13 | 15 | from typing import Optional |
14 | 16 | from typing import Tuple |
15 | 17 | from typing import Union |
16 | 18 |
|
17 | 19 | import requests |
| 20 | +from pydantic import BaseSettings |
18 | 21 |
|
19 | 22 |
|
20 | | -class SettingsException(Exception): |
21 | | - """Exception raised by misconfigured settings class.""" |
22 | | - |
| 23 | +class PyoidcSettings(BaseSettings): |
| 24 | + """Main class for all settings shared among consumer and client.""" |
23 | 25 |
|
24 | | -class PyoidcSettings: |
| 26 | + verify_ssl: Union[bool, str] = True |
25 | 27 | """ |
26 | | - Main class for all settings shared among consumer and client. |
27 | | -
|
28 | | - Keyword Args: |
29 | | - verify_ssl |
30 | | - Control TLS server certificate validation. |
31 | | - If set to True the certificate is validated against the global settings, |
32 | | - if set to False, no validation is performed. |
33 | | - If set to a filename this is used as a certificate bundle in openssl format. |
34 | | - If set to a directory name this is used as a CA directory in the openssl format. |
35 | | - client_cert |
36 | | - Local cert to use as client side certificate. |
37 | | - Can be a single file (containing the private key and the certificate) or a tuple of both file's path. |
38 | | - timeout |
39 | | - Timeout for requests library. |
40 | | - Can be specified either as a single float or as a tuple of floats. |
41 | | - For more details, refer to ``requests`` documentation. |
| 28 | + Control TLS server certificate validation: |
42 | 29 |
|
| 30 | + * If set to True the certificate is validated against the global settings, |
| 31 | + * If set to False, no validation is performed. |
| 32 | + * If set to a filename this is used as a certificate bundle in openssl format. |
| 33 | + * If set to a directory name this is used as a CA directory in the openssl format. |
43 | 34 | """ |
44 | | - |
45 | | - def __init__( |
46 | | - self, |
47 | | - verify_ssl: Union[bool, str] = True, |
48 | | - client_cert: Union[None, str, Tuple[str, str]] = None, |
49 | | - timeout: Union[float, Tuple[float, float]] = 5, |
50 | | - ): |
51 | | - self.verify_ssl = verify_ssl |
52 | | - self.client_cert = client_cert |
53 | | - self.timeout = timeout |
54 | | - |
55 | | - def __setattr__(self, name, value): |
56 | | - """This attempts to check if value matches the expected value.""" |
57 | | - annotation = typing.get_type_hints(self.__init__)[name] # type: ignore |
58 | | - # Expand Union -> Since 3.8, this can be written as typing.get_origin |
59 | | - if getattr(annotation, "__origin__", annotation) is Union: |
60 | | - expanded = tuple(an for an in annotation.__args__) |
61 | | - else: |
62 | | - expanded = (annotation,) |
63 | | - # Convert Generics |
64 | | - # FIXME: this doesn't check the args of the generic |
65 | | - resolved = tuple(getattr(an, "__origin__", an) for an in expanded) |
66 | | - # Add int if float is present |
67 | | - if float in resolved: |
68 | | - resolved = resolved + (int,) |
69 | | - # FIXME: Add more valid substitution |
70 | | - if isinstance(value, resolved): |
71 | | - # FIXME: Handle bool being an instance of int... |
72 | | - super().__setattr__(name, value) |
73 | | - else: |
74 | | - raise SettingsException( |
75 | | - "%s has a type of %s, expected any of %s." |
76 | | - % (name, type(value), resolved), |
77 | | - ) |
78 | | - |
79 | | - |
80 | | -class ClientSettings(PyoidcSettings): |
| 35 | + client_cert: Union[None, str, Tuple[str, str]] = None |
| 36 | + """ |
| 37 | + Local cert to use as client side certificate. |
| 38 | + Can be a single file (containing the private key and the certificate) or a tuple of both file's path. |
| 39 | + """ |
| 40 | + timeout: Union[float, Tuple[float, float]] = 5 |
| 41 | + """ |
| 42 | + Timeout for requests library. |
| 43 | + Can be specified either as a single float or as a tuple of floats. |
| 44 | + For more details, refer to ``requests`` documentation. |
81 | 45 | """ |
82 | | - Base settings for consumer shared among OAuth 2.0 and OpenID Connect. |
83 | 46 |
|
84 | | - Keyword Args: |
85 | | - requests_session |
86 | | - Instance of `requests.Session` with configuration options. |
87 | 47 |
|
88 | | - """ |
| 48 | +class ClientSettings(PyoidcSettings): |
| 49 | + """Base settings for consumer shared among OAuth 2.0 and OpenID Connect.""" |
89 | 50 |
|
90 | | - def __init__( |
91 | | - self, |
92 | | - verify_ssl: Union[bool, str] = True, |
93 | | - client_cert: Union[None, str, Tuple[str, str]] = None, |
94 | | - timeout: Union[float, Tuple[float, float]] = 5, |
95 | | - requests_session: Optional[requests.Session] = None, |
96 | | - ): |
97 | | - super().__init__( |
98 | | - verify_ssl=verify_ssl, client_cert=client_cert, timeout=timeout |
99 | | - ) |
100 | | - # For session persistence |
101 | | - self.requests_session = requests_session |
| 51 | + requests_session: Optional[requests.Session] = None |
| 52 | + """Instance of `requests.Session` with configuration options.""" |
102 | 53 |
|
103 | 54 |
|
104 | 55 | class OauthClientSettings(ClientSettings): |
@@ -131,6 +82,3 @@ class OauthProviderSettings(OauthServerSettings): |
131 | 82 |
|
132 | 83 | class OicProviderSettings(OicServerSettings): |
133 | 84 | """Specific settings for OpenID Connect provider.""" |
134 | | - |
135 | | - # TODO: Decide on inheritance... |
136 | | - # It might be better to have a mixin providing OIC specific stuff? |
0 commit comments