Skip to content

Commit cf1c788

Browse files
Merge pull request #56 from kinde-oss/main_V2_auth_fixes_and_enhancements
Main v2 auth fixes and enhancements
2 parents 143bb32 + 0c6501a commit cf1c788

28 files changed

+4241
-731
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
branches: [ "main", "staging" ]
66

77
push:
8-
branches: [ "main", "staging", "main_V2" ]
8+
branches: [ "main", "staging", "main_V2", "main_V2_auth_fixes_and_enhancements" ]
99

1010
concurrency:
1111
group: ${{ github.head_ref || github.run_id }}
@@ -44,7 +44,7 @@ jobs:
4444
pip install -r requirements.txt
4545
4646
- name: Run tests
47-
run: pytest --cov-branch --cov-report=xml
47+
run: pytest --cov=kinde_sdk --cov-branch --cov-report=xml
4848

4949
- name: Upload coverage reports to Codecov
5050
uses: codecov/codecov-action@v5

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,4 @@ Icon
241241
Network Trash Folder
242242
Temporary Items
243243
.apdisk
244+
.vscode/launch.json

README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,121 @@ You can also use the [Python starter kit here](https://github.com/kinde-starter-
1010

1111
For details on integrating this SDK into your project, head over to the [Kinde docs](https://kinde.com/docs/) and see the [Python SDK](https://kinde.com/docs/developer-tools/python-sdk/) doc 👍🏼.
1212

13+
## Storage Usage Examples
14+
15+
### Basic Usage
16+
```python
17+
from kinde_sdk.auth import OAuth
18+
from kinde_sdk.core.storage import StorageManager
19+
20+
# Basic initialization via OAuth
21+
# This is the recommended way to initialize the storage system
22+
# OAuth automatically initializes the StorageManager with the provided config
23+
oauth = OAuth(
24+
client_id="your_client_id",
25+
client_secret="your_client_secret",
26+
redirect_uri="your_redirect_uri"
27+
)
28+
29+
# Direct access to the storage manager
30+
# This is safe to use after OAuth initialization
31+
storage_manager = StorageManager()
32+
33+
# Store authentication data
34+
storage_manager.set("user_tokens", {
35+
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
36+
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
37+
"expires_at": 1678901234
38+
})
39+
40+
# Retrieve tokens
41+
tokens = storage_manager.get("user_tokens")
42+
if tokens:
43+
access_token = tokens.get("access_token")
44+
# Use the access token for API requests
45+
46+
# Delete tokens when logging out
47+
storage_manager.delete("user_tokens")
48+
```
49+
50+
### Using a Custom Storage Backend
51+
```python
52+
oauth = OAuth(
53+
client_id="your_client_id",
54+
storage_config={
55+
"type": "local_storage",
56+
"options": {
57+
# backend-specific options
58+
}
59+
}
60+
)
61+
```
62+
63+
### Handling Multi-Device Usage
64+
The StorageManager automatically assigns a unique device ID to each client instance, ensuring that
65+
the same user logged in on different devices won't experience session clashes. Keys are namespaced
66+
with the device ID by default.
67+
68+
```python
69+
# Get the current device ID
70+
device_id = storage_manager.get_device_id()
71+
print(f"Current device ID: {device_id}")
72+
73+
# Clear all data for the current device (useful for logout)
74+
storage_manager.clear_device_data()
75+
76+
# For data that should be shared across all devices for the same user
77+
# Use the "user:" prefix
78+
storage_manager.set("user:shared_preferences", {"theme": "dark"})
79+
80+
# For data that should be global across all users and devices
81+
# Use the "global:" prefix
82+
storage_manager.set("global:app_settings", {"version": "1.0.0"})
83+
```
84+
85+
## Best Practices for Storage Management
86+
87+
1. **Always initialize OAuth first**: The OAuth constructor initializes the StorageManager, so create your OAuth instance before accessing the storage.
88+
89+
2. **Manual initialization (if needed)**: If you need to use StorageManager before creating an OAuth instance, explicitly initialize it first:
90+
```python
91+
# Manual initialization
92+
storage_manager = StorageManager()
93+
storage_manager.initialize({"type": "memory"}) # or your preferred storage config
94+
95+
# You can also provide a specific device ID
96+
storage_manager.initialize(
97+
config={"type": "memory"},
98+
device_id="custom-device-identifier"
99+
)
100+
101+
# Now safe to use
102+
storage_manager.set("some_key", {"some": "value"})
103+
```
104+
105+
3. **Safe access pattern**: If you're unsure about initialization status, you can use this pattern:
106+
```python
107+
storage_manager = StorageManager()
108+
if not storage_manager._initialized:
109+
storage_manager.initialize()
110+
111+
# Now safe to use
112+
data = storage_manager.get("some_key")
113+
```
114+
115+
4. **Single configuration**: Configure the storage only once at application startup. Changing storage configuration mid-operation may lead to data inconsistency.
116+
117+
5. **Access from anywhere**: After initialization, you can safely access the StorageManager from any part of your application without passing it around.
118+
119+
6. **Device-specific data**: Understand that by default, data is stored with device-specific namespacing. To share data across devices, use the appropriate prefixes.
120+
121+
7. **Complete logout**: To ensure all device-specific data is cleared during logout, call `storage_manager.clear_device_data()`.
122+
123+
124+
125+
# After initializing both OAuth and KindeApiClient use the following fn to get proper urls
126+
api_client.fetch_openid_configuration(oauth)
127+
13128
## Publishing
14129

15130
The core team handles publishing.

kinde_sdk/auth/enums.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from enum import Enum
2+
3+
class GrantType(Enum):
4+
"""OAuth grant types."""
5+
CLIENT_CREDENTIALS = "client_credentials"
6+
AUTHORIZATION_CODE = "authorization_code"
7+
AUTHORIZATION_CODE_WITH_PKCE = "authorization_code_with_pkce"
8+
9+
class IssuerRouteTypes(Enum):
10+
"""Types of authentication routes."""
11+
LOGIN = "login"
12+
REGISTER = "register"
13+
14+
class PromptTypes(Enum):
15+
"""Authentication prompt types."""
16+
CREATE = "create"
17+
LOGIN = "login"
18+
CONSENT = "consent"
19+
SELECT_ACCOUNT = "select_account"
20+
NONE = "none"

kinde_sdk/auth/local_storage.py

Lines changed: 0 additions & 23 deletions
This file was deleted.

kinde_sdk/auth/login_options.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class LoginOptions:
2+
"""Login options constants for OAuth authentication."""
3+
4+
# Standard OAuth parameters
5+
RESPONSE_TYPE = "response_type"
6+
REDIRECT_URI = "redirect_uri"
7+
SCOPE = "scope"
8+
AUDIENCE = "audience"
9+
STATE = "state"
10+
NONCE = "nonce"
11+
CODE_CHALLENGE = "code_challenge"
12+
CODE_CHALLENGE_METHOD = "code_challenge_method"
13+
14+
# Organization parameters
15+
ORG_CODE = "org_code"
16+
ORG_NAME = "org_name"
17+
IS_CREATE_ORG = "is_create_org"
18+
19+
# User experience parameters
20+
PROMPT = "prompt"
21+
LANG = "lang"
22+
LOGIN_HINT = "login_hint"
23+
CONNECTION_ID = "connection_id"
24+
REDIRECT_URL = "redirect_url"
25+
HAS_SUCCESS_PAGE = "has_success_page"
26+
WORKFLOW_DEPLOYMENT_ID = "workflow_deployment_id"
27+
28+
# Additional parameters container
29+
AUTH_PARAMS = "auth_params"

kinde_sdk/auth/memory_storage.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)