trishul-oauth-client 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,134 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ lerna-debug.log*
8
+ .pnpm-debug.log*
9
+
10
+ # Diagnostic reports (https://nodejs.org/api/report.html)
11
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12
+
13
+ # Runtime data
14
+ pids
15
+ *.pid
16
+ *.seed
17
+ *.pid.lock
18
+
19
+ # Directory for instrumented libs generated by jscoverage/JSCover
20
+ lib-cov
21
+
22
+ # Coverage directory used by tools like istanbul
23
+ coverage
24
+ *.lcov
25
+
26
+ # nyc test coverage
27
+ .nyc_output
28
+
29
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30
+ .grunt
31
+
32
+ # Bower dependency directory (https://bower.io/)
33
+ bower_components
34
+
35
+ # node-waf configuration
36
+ .lock-wscript
37
+
38
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
39
+ build/Release
40
+
41
+ # Dependency directories
42
+ node_modules/
43
+ jspm_packages/
44
+
45
+ # Snowpack dependency directory (https://snowpack.dev/)
46
+ web_modules/
47
+
48
+ # TypeScript cache
49
+ *.tsbuildinfo
50
+
51
+ # Optional npm cache directory
52
+ .npm
53
+
54
+ # Optional eslint cache
55
+ .eslintcache
56
+
57
+ # Microbundle cache
58
+ .rpt2_cache/
59
+ .rts2_cache_cjs/
60
+ .rts2_cache_es/
61
+ .rts2_cache_umd/
62
+
63
+ # Optional REPL history
64
+ .node_repl_history
65
+
66
+ # Output of 'npm pack'
67
+ *.tgz
68
+
69
+ # Yarn Integrity file
70
+ .yarn-integrity
71
+
72
+ # dotenv environment variables file
73
+ .env
74
+ .env.test
75
+ .env.production
76
+ .env.local
77
+ .env.development.local
78
+ .env.test.local
79
+ .env.production.local
80
+
81
+ # parcel-bundler cache (https://parceljs.org/)
82
+ .cache
83
+ .parcel-cache
84
+
85
+ # Next.js build output
86
+ .next
87
+ out
88
+
89
+ # Nuxt.js build output
90
+ .nuxt
91
+ dist
92
+
93
+ # Gatsby files
94
+ .cache/
95
+ # Comment in the public line in if your project uses Gatsby and not Next.js
96
+ # public
97
+
98
+ # Identity service React build output (generated by vite build)
99
+ services/identity-service/src/public/auth-ui/
100
+
101
+ # vuepress build output
102
+ .vuepress/dist
103
+
104
+ # Serverless directories
105
+ .serverless/
106
+
107
+ # FuseBox cache
108
+ .fusebox/
109
+
110
+ # DynamoDB Local files
111
+ .dynamodb/
112
+
113
+ # TernJS port file
114
+ .tern-port
115
+
116
+ # Stores VSCode versions used for testing VSCode extensions
117
+ .vscode-test
118
+
119
+ # yarn v2
120
+ .yarn/cache
121
+ .yarn/unplugged
122
+ .yarn/build-state.yml
123
+ .yarn/install-state.gz
124
+ .pnp.*
125
+
126
+ .DS_Store
127
+
128
+ # Enterprise Roadmap
129
+ docs/enterprise_roadmap.md
130
+
131
+ scratch/*
132
+
133
+ # Claude
134
+ .claude/settings.local.json
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: trishul-oauth-client
3
+ Version: 0.1.0
4
+ Summary: Enterprise-grade OIDC/OAuth client library for Python (FastAPI, Flask, Django)
5
+ Project-URL: Homepage, https://trishuliam.com
6
+ Project-URL: Repository, https://github.com/shubhamssinghs/trishul-iam
7
+ Author-email: TrishulIAM Team <team@trishuliam.com>
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Security
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.8
21
+ Requires-Dist: httpx>=0.24.0
22
+ Requires-Dist: pyjwt[crypto]>=2.8.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: black>=23.0.0; extra == 'dev'
25
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
26
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
27
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
28
+ Requires-Dist: respx>=0.20.0; extra == 'dev'
29
+ Provides-Extra: django
30
+ Requires-Dist: django>=4.0.0; extra == 'django'
31
+ Provides-Extra: fastapi
32
+ Requires-Dist: fastapi>=0.100.0; extra == 'fastapi'
33
+ Provides-Extra: flask
34
+ Requires-Dist: flask>=2.0.0; extra == 'flask'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Trishul OAuth Client for Python
38
+
39
+ An enterprise-grade, highly secure OIDC/OAuth 2.0 client library for Python. Supports standard OIDC authorization code flow with secure PKCE validation, state validation, and plug-and-play integrations for **FastAPI**, **Flask**, and **Django**.
40
+
41
+ ---
42
+
43
+ ## Features
44
+
45
+ - **Sync & Async Core Engine**: Fully support both sync and async frameworks out-of-the-box.
46
+ - **Secure PKCE (S256)**: Auto-generated PKCE verification pairs for absolute security against code interception attacks.
47
+ - **OIDC Discovery Configuration**: Automatic parsing and local caching of the openid-configuration metadata.
48
+ - **Cryptographic Signature Verification**: Validates ID Token signatures locally using the server's JWKS endpoint.
49
+ - **Automatic Silent Token Rotation**: Seamless refresh-token based token rotation without user disruption.
50
+ - **Out-of-the-Box Web Framework Integrations** for:
51
+ - **FastAPI / Starlette**
52
+ - **Flask**
53
+ - **Django**
54
+
55
+ ---
56
+
57
+ ## Installation
58
+
59
+ Install from PyPI (once published):
60
+
61
+ ```bash
62
+ pip install trishul-oauth-client
63
+ ```
64
+
65
+ Or install with framework-specific dependency packages:
66
+
67
+ ```bash
68
+ # For FastAPI
69
+ pip install "trishul-oauth-client[fastapi]"
70
+
71
+ # For Flask
72
+ pip install "trishul-oauth-client[flask]"
73
+
74
+ # For Django
75
+ pip install "trishul-oauth-client[django]"
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Quickstart
81
+
82
+ ### 1. Initialize Client
83
+ ```python
84
+ from trishul_oauth import TrishulOAuth, MemoryStorage
85
+
86
+ client = TrishulOAuth({
87
+ "issuer": "https://identity.yourdomain.com",
88
+ "clientId": "your_client_id",
89
+ "clientSecret": "your_client_secret",
90
+ "redirectUri": "http://localhost:8000/callback",
91
+ "usePKCE": True,
92
+ })
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Web Framework Integrations
98
+
99
+ ### 1. FastAPI / Starlette
100
+ Fully async dependency injection provider:
101
+
102
+ ```python
103
+ from fastapi import FastAPI, Depends, HTTPException
104
+ from trishul_oauth import TrishulOAuth
105
+ from trishul_oauth.integrations.fastapi import TrishulSecurity
106
+
107
+ app = FastAPI()
108
+ client = TrishulOAuth({
109
+ "issuer": "https://identity.yourdomain.com",
110
+ "clientId": "your_client_id",
111
+ "redirectUri": "http://localhost:8000/callback",
112
+ })
113
+
114
+ # Initialize FastAPI Security provider
115
+ security = TrishulSecurity(client)
116
+
117
+ @app.get("/api/dashboard")
118
+ async def dashboard(user = Depends(security.require_auth(scopes=["profile"]))):
119
+ return {
120
+ "status": "success",
121
+ "message": f"Welcome back, {user.get('name')}!",
122
+ "profile": user
123
+ }
124
+ ```
125
+
126
+ ### 2. Flask
127
+ Clean view decorators and session injectors:
128
+
129
+ ```python
130
+ from flask import Flask, session, render_template
131
+ from trishul_oauth import TrishulOAuth
132
+ from trishul_oauth.integrations.flask import FlaskOAuth
133
+
134
+ app = Flask(__name__)
135
+ app.secret_key = "your_super_secret_session_key"
136
+
137
+ client = TrishulOAuth({
138
+ "issuer": "https://identity.yourdomain.com",
139
+ "clientId": "your_client_id",
140
+ "clientSecret": "your_client_secret",
141
+ "redirectUri": "http://localhost:5000/callback",
142
+ })
143
+
144
+ oauth = FlaskOAuth(client)
145
+
146
+ @app.route("/dashboard")
147
+ @oauth.require_auth(scopes=["profile"])
148
+ def dashboard():
149
+ # Retrieve user info from global Flask context
150
+ user = oauth.current_user
151
+ return f"Welcome back, {user['name']}!"
152
+ ```
153
+
154
+ ### 3. Django
155
+ Middleware and view decorators for robust authentication:
156
+
157
+ ```python
158
+ # settings.py
159
+ INSTALLED_APPS = [
160
+ ...
161
+ 'django.contrib.sessions',
162
+ ]
163
+
164
+ MIDDLEWARE = [
165
+ ...
166
+ 'django.contrib.sessions.middleware.SessionMiddleware',
167
+ 'trishul_oauth.integrations.django.TrishulOAuthMiddleware',
168
+ ]
169
+
170
+ from trishul_oauth import TrishulOAuth
171
+ TRISHUL_OAUTH_CLIENT = TrishulOAuth({
172
+ "issuer": "https://identity.yourdomain.com",
173
+ "clientId": "your_client_id",
174
+ "clientSecret": "your_client_secret",
175
+ })
176
+
177
+
178
+ # views.py
179
+ from django.http import JsonResponse
180
+ from trishul_oauth.integrations.django import require_auth
181
+
182
+ @require_auth(scopes=["profile"])
183
+ def dashboard_view(request):
184
+ user = request.trishul_user
185
+ return JsonResponse({
186
+ "status": "success",
187
+ "user": user
188
+ })
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Running Package Tests
194
+
195
+ Verify everything runs cleanly using `pytest`:
196
+
197
+ ```bash
198
+ pytest tests/
199
+ ```
200
+
201
+ ---
202
+
203
+ ## License
204
+
205
+ MIT License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,169 @@
1
+ # Trishul OAuth Client for Python
2
+
3
+ An enterprise-grade, highly secure OIDC/OAuth 2.0 client library for Python. Supports standard OIDC authorization code flow with secure PKCE validation, state validation, and plug-and-play integrations for **FastAPI**, **Flask**, and **Django**.
4
+
5
+ ---
6
+
7
+ ## Features
8
+
9
+ - **Sync & Async Core Engine**: Fully support both sync and async frameworks out-of-the-box.
10
+ - **Secure PKCE (S256)**: Auto-generated PKCE verification pairs for absolute security against code interception attacks.
11
+ - **OIDC Discovery Configuration**: Automatic parsing and local caching of the openid-configuration metadata.
12
+ - **Cryptographic Signature Verification**: Validates ID Token signatures locally using the server's JWKS endpoint.
13
+ - **Automatic Silent Token Rotation**: Seamless refresh-token based token rotation without user disruption.
14
+ - **Out-of-the-Box Web Framework Integrations** for:
15
+ - **FastAPI / Starlette**
16
+ - **Flask**
17
+ - **Django**
18
+
19
+ ---
20
+
21
+ ## Installation
22
+
23
+ Install from PyPI (once published):
24
+
25
+ ```bash
26
+ pip install trishul-oauth-client
27
+ ```
28
+
29
+ Or install with framework-specific dependency packages:
30
+
31
+ ```bash
32
+ # For FastAPI
33
+ pip install "trishul-oauth-client[fastapi]"
34
+
35
+ # For Flask
36
+ pip install "trishul-oauth-client[flask]"
37
+
38
+ # For Django
39
+ pip install "trishul-oauth-client[django]"
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Quickstart
45
+
46
+ ### 1. Initialize Client
47
+ ```python
48
+ from trishul_oauth import TrishulOAuth, MemoryStorage
49
+
50
+ client = TrishulOAuth({
51
+ "issuer": "https://identity.yourdomain.com",
52
+ "clientId": "your_client_id",
53
+ "clientSecret": "your_client_secret",
54
+ "redirectUri": "http://localhost:8000/callback",
55
+ "usePKCE": True,
56
+ })
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Web Framework Integrations
62
+
63
+ ### 1. FastAPI / Starlette
64
+ Fully async dependency injection provider:
65
+
66
+ ```python
67
+ from fastapi import FastAPI, Depends, HTTPException
68
+ from trishul_oauth import TrishulOAuth
69
+ from trishul_oauth.integrations.fastapi import TrishulSecurity
70
+
71
+ app = FastAPI()
72
+ client = TrishulOAuth({
73
+ "issuer": "https://identity.yourdomain.com",
74
+ "clientId": "your_client_id",
75
+ "redirectUri": "http://localhost:8000/callback",
76
+ })
77
+
78
+ # Initialize FastAPI Security provider
79
+ security = TrishulSecurity(client)
80
+
81
+ @app.get("/api/dashboard")
82
+ async def dashboard(user = Depends(security.require_auth(scopes=["profile"]))):
83
+ return {
84
+ "status": "success",
85
+ "message": f"Welcome back, {user.get('name')}!",
86
+ "profile": user
87
+ }
88
+ ```
89
+
90
+ ### 2. Flask
91
+ Clean view decorators and session injectors:
92
+
93
+ ```python
94
+ from flask import Flask, session, render_template
95
+ from trishul_oauth import TrishulOAuth
96
+ from trishul_oauth.integrations.flask import FlaskOAuth
97
+
98
+ app = Flask(__name__)
99
+ app.secret_key = "your_super_secret_session_key"
100
+
101
+ client = TrishulOAuth({
102
+ "issuer": "https://identity.yourdomain.com",
103
+ "clientId": "your_client_id",
104
+ "clientSecret": "your_client_secret",
105
+ "redirectUri": "http://localhost:5000/callback",
106
+ })
107
+
108
+ oauth = FlaskOAuth(client)
109
+
110
+ @app.route("/dashboard")
111
+ @oauth.require_auth(scopes=["profile"])
112
+ def dashboard():
113
+ # Retrieve user info from global Flask context
114
+ user = oauth.current_user
115
+ return f"Welcome back, {user['name']}!"
116
+ ```
117
+
118
+ ### 3. Django
119
+ Middleware and view decorators for robust authentication:
120
+
121
+ ```python
122
+ # settings.py
123
+ INSTALLED_APPS = [
124
+ ...
125
+ 'django.contrib.sessions',
126
+ ]
127
+
128
+ MIDDLEWARE = [
129
+ ...
130
+ 'django.contrib.sessions.middleware.SessionMiddleware',
131
+ 'trishul_oauth.integrations.django.TrishulOAuthMiddleware',
132
+ ]
133
+
134
+ from trishul_oauth import TrishulOAuth
135
+ TRISHUL_OAUTH_CLIENT = TrishulOAuth({
136
+ "issuer": "https://identity.yourdomain.com",
137
+ "clientId": "your_client_id",
138
+ "clientSecret": "your_client_secret",
139
+ })
140
+
141
+
142
+ # views.py
143
+ from django.http import JsonResponse
144
+ from trishul_oauth.integrations.django import require_auth
145
+
146
+ @require_auth(scopes=["profile"])
147
+ def dashboard_view(request):
148
+ user = request.trishul_user
149
+ return JsonResponse({
150
+ "status": "success",
151
+ "user": user
152
+ })
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Running Package Tests
158
+
159
+ Verify everything runs cleanly using `pytest`:
160
+
161
+ ```bash
162
+ pytest tests/
163
+ ```
164
+
165
+ ---
166
+
167
+ ## License
168
+
169
+ MIT License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,43 @@
1
+ import asyncio
2
+ import os
3
+ import sys
4
+
5
+ from trishul_oauth import TrishulOAuth, TrishulOAuthError
6
+
7
+ async def main():
8
+ print("=== Trishul OAuth Client Python Playground ===")
9
+
10
+ # 1. Initialize Client pointing to local identity service
11
+ config = {
12
+ "issuer": os.getenv("TRISHUL_ISSUER", "http://localhost:3001"),
13
+ "clientId": os.getenv("TRISHUL_CLIENT_ID", "test_client"),
14
+ "redirectUri": "http://localhost:8000/callback",
15
+ "usePKCE": True,
16
+ "debug": True,
17
+ }
18
+
19
+ print(f"Connecting to Identity Issuer: {config['issuer']}")
20
+ client = TrishulOAuth(config)
21
+
22
+ try:
23
+ # 2. Fetch OIDC Configuration
24
+ print("\n1. Querying OpenID Discovery endpoint...")
25
+ discovery = await client.async_get_discovery()
26
+ print(f"✅ Success! Token Endpoint: {discovery['token_endpoint']}")
27
+
28
+ # 3. Create redirect authorize URL
29
+ print("\n2. Generating OIDC Authorization redirect URL...")
30
+ auth_data = await client.async_create_authorization_url()
31
+ print(f"✅ Authorization URL: {auth_data['url']}")
32
+ print(f"🔑 Saved Verification State: {auth_data['state']}")
33
+
34
+ print("\nReady to authenticate. Push to repository to trigger GHA pipeline!")
35
+
36
+ except TrishulOAuthError as e:
37
+ print(f"❌ Error during OIDC communication: {str(e)}")
38
+ if e.original_error:
39
+ print(f"Details: {e.original_error}")
40
+ sys.exit(1)
41
+
42
+ if __name__ == "__main__":
43
+ asyncio.run(main())
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "trishul-oauth-client"
7
+ dynamic = ["version"]
8
+ description = "Enterprise-grade OIDC/OAuth client library for Python (FastAPI, Flask, Django)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "TrishulIAM Team", email = "team@trishuliam.com" }
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: Security",
26
+ "Topic :: Software Development :: Libraries :: Python Modules"
27
+ ]
28
+ dependencies = [
29
+ "httpx>=0.24.0",
30
+ "pyjwt[crypto]>=2.8.0",
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ fastapi = ["fastapi>=0.100.0"]
35
+ flask = ["flask>=2.0.0"]
36
+ django = ["django>=4.0.0"]
37
+ dev = [
38
+ "pytest>=7.0.0",
39
+ "pytest-asyncio>=0.21.0",
40
+ "respx>=0.20.0",
41
+ "black>=23.0.0",
42
+ "mypy>=1.0.0"
43
+ ]
44
+
45
+ [project.urls]
46
+ Homepage = "https://trishuliam.com"
47
+ Repository = "https://github.com/shubhamssinghs/trishul-iam"
48
+
49
+ [tool.hatch.version]
50
+ path = "trishul_oauth/__init__.py"
51
+
52
+ [tool.hatch.build.targets.wheel]
53
+ packages = ["trishul_oauth"]
@@ -0,0 +1 @@
1
+ # Trishul OAuth Client tests subpackage.