django-clerk-users 0.1.2__tar.gz → 0.1.4__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.
Files changed (110) hide show
  1. django_clerk_users-0.1.4/.claude/skills/gh-issues/SKILL.md +64 -0
  2. django_clerk_users-0.1.4/.claude/skills/release/SKILL.md +50 -0
  3. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/PKG-INFO +1 -1
  4. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/pyproject.toml +1 -1
  5. django_clerk_users-0.1.4/src/django_clerk_users/admin.py +64 -0
  6. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/apps.py +0 -3
  7. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/authentication/utils.py +9 -1
  8. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/management/commands/migrate_users_to_clerk.py +8 -1
  9. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/management/commands/sync_clerk_organizations.py +9 -2
  10. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/management/commands/sync_clerk_users.py +9 -2
  11. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/middleware/auth.py +8 -1
  12. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/uv.lock +1 -1
  13. django_clerk_users-0.1.2/src/django_clerk_users/checks.py +0 -127
  14. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/.flake8 +0 -0
  15. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/.github/workflows/main.yaml +0 -0
  16. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/.gitignore +0 -0
  17. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/.pre-commit-config.yaml +0 -0
  18. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/.python-version +0 -0
  19. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/CLAUDE.md +0 -0
  20. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/HYBRID_AUTH.md +0 -0
  21. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/LICENSE +0 -0
  22. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/README.md +0 -0
  23. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/README.md +0 -0
  24. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/TESTING.md +0 -0
  25. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/.env.example +0 -0
  26. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/.gitignore +0 -0
  27. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/__init__.py +0 -0
  28. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/admin.py +0 -0
  29. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/apps.py +0 -0
  30. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/migrations/__init__.py +0 -0
  31. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/models.py +0 -0
  32. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/tests.py +0 -0
  33. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/urls.py +0 -0
  34. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/api/views.py +0 -0
  35. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/backend/__init__.py +0 -0
  36. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/backend/asgi.py +0 -0
  37. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/backend/settings.py +0 -0
  38. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/backend/urls.py +0 -0
  39. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/backend/wsgi.py +0 -0
  40. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/backend/manage.py +0 -0
  41. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/fixtures/test-users.ts +0 -0
  42. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/global-setup.ts +0 -0
  43. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/package.json +0 -0
  44. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/playwright.config.ts +0 -0
  45. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/scripts/setup-test-users.ts +0 -0
  46. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/tests/auth.spec.ts +0 -0
  47. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/tests/protected-api.spec.ts +0 -0
  48. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/e2e/tsconfig.json +0 -0
  49. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/.env.example +0 -0
  50. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/.gitignore +0 -0
  51. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/.nvmrc +0 -0
  52. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/README.md +0 -0
  53. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/eslint.config.js +0 -0
  54. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/index.html +0 -0
  55. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/package-lock.json +0 -0
  56. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/package.json +0 -0
  57. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/public/vite.svg +0 -0
  58. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/src/App.css +0 -0
  59. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/src/App.jsx +0 -0
  60. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/src/assets/react.svg +0 -0
  61. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/src/index.css +0 -0
  62. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/src/main.jsx +0 -0
  63. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/examples/django_react_example/frontend/vite.config.js +0 -0
  64. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/rav.yaml +0 -0
  65. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/__init__.py +0 -0
  66. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/authentication/__init__.py +0 -0
  67. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/authentication/backends.py +0 -0
  68. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/authentication/drf.py +0 -0
  69. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/caching.py +0 -0
  70. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/client.py +0 -0
  71. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/decorators.py +0 -0
  72. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/exceptions.py +0 -0
  73. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/management/__init__.py +0 -0
  74. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/management/commands/__init__.py +0 -0
  75. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/managers.py +0 -0
  76. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/middleware/__init__.py +0 -0
  77. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/migrations/0001_initial.py +0 -0
  78. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/migrations/0002_make_clerk_id_nullable.py +0 -0
  79. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/migrations/__init__.py +0 -0
  80. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/models.py +0 -0
  81. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/__init__.py +0 -0
  82. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/admin.py +0 -0
  83. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/apps.py +0 -0
  84. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/middleware.py +0 -0
  85. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/migrations/0001_initial.py +0 -0
  86. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/migrations/__init__.py +0 -0
  87. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/models.py +0 -0
  88. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/organizations/webhooks.py +0 -0
  89. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/settings.py +0 -0
  90. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/testing.py +0 -0
  91. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/utils.py +0 -0
  92. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/webhooks/__init__.py +0 -0
  93. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/webhooks/handlers.py +0 -0
  94. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/webhooks/security.py +0 -0
  95. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/webhooks/signals.py +0 -0
  96. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/src/django_clerk_users/webhooks/views.py +0 -0
  97. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/__init__.py +0 -0
  98. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/settings.py +0 -0
  99. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_authentication.py +0 -0
  100. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_caching.py +0 -0
  101. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_decorators.py +0 -0
  102. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_drf.py +0 -0
  103. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_hybrid_auth.py +0 -0
  104. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_import.py +0 -0
  105. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_middleware.py +0 -0
  106. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_models.py +0 -0
  107. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_organizations.py +0 -0
  108. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_testing.py +0 -0
  109. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_utils.py +0 -0
  110. {django_clerk_users-0.1.2 → django_clerk_users-0.1.4}/tests/test_webhooks.py +0 -0
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: gh-issues
3
+ description: Review open GitHub issues and start working on one. Lists issues, shows details, creates a branch, and sets up todos.
4
+ argument-hint: "[issue-number]"
5
+ ---
6
+
7
+ # GitHub Issues Skill
8
+
9
+ Help the user review and start working on GitHub issues from the current repository.
10
+
11
+ ## Workflow
12
+
13
+ ### Step 1: List Open Issues
14
+
15
+ If no issue number was provided as an argument, list open issues:
16
+
17
+ ```bash
18
+ gh issue list --state open --limit 20
19
+ ```
20
+
21
+ Present the issues in a clear format and ask the user which one they'd like to work on using AskUserQuestion. Include issue number, title, and labels.
22
+
23
+ ### Step 2: Get Issue Details
24
+
25
+ Once an issue is selected (either from argument or user selection), fetch the full details:
26
+
27
+ ```bash
28
+ gh issue view <issue-number>
29
+ ```
30
+
31
+ Display:
32
+ - Title and description
33
+ - Labels and assignees
34
+ - Any linked PRs or related issues
35
+ - Comments (if relevant)
36
+
37
+ ### Step 3: Create a Working Branch
38
+
39
+ Always create a new branch for this issue:
40
+
41
+ ```bash
42
+ git checkout -b <branch-name>
43
+ ```
44
+
45
+ Suggest a branch name based on the issue (e.g., `fix/123-brief-description` or `feat/123-brief-description`).
46
+
47
+ ### Step 4: Create Todo List
48
+
49
+ Based on the issue description and any acceptance criteria, use TodoWrite to create a structured task list. Break down the work into:
50
+ - Investigation/research tasks (if needed)
51
+ - Implementation tasks
52
+ - Testing tasks
53
+ - Documentation updates (if needed)
54
+
55
+ ### Step 5: Start Working
56
+
57
+ Begin working on the first todo item. Use the codebase exploration tools to understand the relevant code before making changes.
58
+
59
+ ## Important Notes
60
+
61
+ - Always check `git status` before creating a branch to ensure clean working state
62
+ - If the issue is unclear, ask clarifying questions before starting work
63
+ - Reference the issue number in commit messages (e.g., "Fix #123: description")
64
+ - Keep the user informed of progress by updating todos as you work
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: release
3
+ description: Release a new version by bumping version, tagging, and pushing to GitHub.
4
+ argument-hint: "[patch|minor|major|X.Y.Z]"
5
+ ---
6
+
7
+ # Release Skill
8
+
9
+ Release a new version of this Copier template to GitHub.
10
+
11
+ ## Arguments (optional)
12
+
13
+ - `$ARGUMENTS` - Bump type: `patch` (default), `minor`, or `major`. Or a specific version like `0.5.0`.
14
+
15
+ ## Steps
16
+
17
+ 1. Get the current version from the latest git tag:
18
+ ```bash
19
+ git describe --tags --abbrev=0
20
+ ```
21
+
22
+ 2. Determine the new version:
23
+ - If no argument or `patch`: increment patch (0.2.4 -> 0.2.5)
24
+ - If `minor`: increment minor, reset patch (0.2.4 -> 0.3.0)
25
+ - If `major`: increment major, reset minor and patch (0.2.4 -> 1.0.0)
26
+ - If specific version provided (X.Y.Z format): use that version
27
+
28
+ 3. Confirm the version bump with the user using AskUserQuestion:
29
+ - Show current version and new version
30
+ - Ask for confirmation before proceeding
31
+
32
+ 4. Create a git tag: `v{version}`
33
+ ```bash
34
+ git tag v{version}
35
+ ```
36
+
37
+ 5. Push the tag to origin:
38
+ ```bash
39
+ git push origin v{version}
40
+ ```
41
+
42
+ 6. Report success with the new version number and a link to the GitHub releases page.
43
+
44
+ ## Important
45
+
46
+ - Do NOT include a co-authored-by line in commits
47
+ - The version should be in format `X.Y.Z` (e.g., `0.2.5`)
48
+ - Tags should be prefixed with `v` (e.g., `v0.2.5`)
49
+ - This template uses git tags as the version source (no version file to update)
50
+ - Ensure working directory is clean before tagging
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-clerk-users
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Integrate Clerk with Django
5
5
  Project-URL: Changelog, https://github.com/jmitchel3/django-clerk-users
6
6
  Project-URL: Documentation, https://github.com/jmitchel3/django-clerk-users
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "django-clerk-users"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  description = "Integrate Clerk with Django"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -0,0 +1,64 @@
1
+ """
2
+ Django admin configuration for ClerkUser model.
3
+ """
4
+
5
+ from django.contrib import admin
6
+ from django.contrib.auth.admin import UserAdmin
7
+
8
+ from django_clerk_users.models import ClerkUser
9
+
10
+
11
+ @admin.register(ClerkUser)
12
+ class ClerkUserAdmin(UserAdmin):
13
+ list_display = [
14
+ "email",
15
+ "first_name",
16
+ "last_name",
17
+ "clerk_id",
18
+ "is_staff",
19
+ "is_active",
20
+ ]
21
+ list_filter = ["is_staff", "is_active", "created_at"]
22
+ search_fields = ["email", "first_name", "last_name", "clerk_id"]
23
+ ordering = ["-created_at"]
24
+
25
+ fieldsets = (
26
+ (None, {"fields": ("email", "password")}),
27
+ ("Personal info", {"fields": ("first_name", "last_name", "image_url")}),
28
+ ("Clerk", {"fields": ("clerk_id", "uid")}),
29
+ (
30
+ "Permissions",
31
+ {
32
+ "fields": (
33
+ "is_active",
34
+ "is_staff",
35
+ "is_superuser",
36
+ "groups",
37
+ "user_permissions",
38
+ )
39
+ },
40
+ ),
41
+ (
42
+ "Timestamps",
43
+ {"fields": ("created_at", "updated_at", "last_login", "last_logout")},
44
+ ),
45
+ )
46
+
47
+ add_fieldsets = (
48
+ (
49
+ None,
50
+ {
51
+ "classes": ("wide",),
52
+ "fields": ("email", "password1", "password2"),
53
+ },
54
+ ),
55
+ )
56
+
57
+ readonly_fields = [
58
+ "uid",
59
+ "clerk_id",
60
+ "created_at",
61
+ "updated_at",
62
+ "last_login",
63
+ "last_logout",
64
+ ]
@@ -7,9 +7,6 @@ class DjangoClerkUsersConfig(AppConfig):
7
7
  default_auto_field = "django.db.models.BigAutoField"
8
8
 
9
9
  def ready(self):
10
- # Import checks to register them with Django
11
- from django_clerk_users import checks # noqa: F401
12
-
13
10
  # Disconnect Django's update_last_login signal
14
11
  # Clerk manages authentication externally
15
12
  from django.contrib.auth import get_user_model
@@ -13,7 +13,11 @@ from clerk_backend_api.security.types import AuthenticateRequestOptions
13
13
  from django.core.cache import cache
14
14
 
15
15
  from django_clerk_users.client import get_clerk_client
16
- from django_clerk_users.exceptions import ClerkAuthenticationError, ClerkTokenError
16
+ from django_clerk_users.exceptions import (
17
+ ClerkAuthenticationError,
18
+ ClerkConfigurationError,
19
+ ClerkTokenError,
20
+ )
17
21
  from django_clerk_users.settings import CLERK_AUTH_PARTIES, CLERK_CACHE_TIMEOUT
18
22
 
19
23
  if TYPE_CHECKING:
@@ -72,7 +76,11 @@ def get_clerk_payload_from_request(request: "HttpRequest") -> dict[str, Any] | N
72
76
 
73
77
  try:
74
78
  clerk = get_clerk_client()
79
+ except ClerkConfigurationError:
80
+ # Clerk is not configured, skip authentication silently
81
+ return None
75
82
 
83
+ try:
76
84
  # Build auth options with authorized parties
77
85
  auth_options = None
78
86
  if CLERK_AUTH_PARTIES:
@@ -14,6 +14,7 @@ from django.apps import apps
14
14
  from django.core.management.base import BaseCommand, CommandError
15
15
 
16
16
  from django_clerk_users.client import get_clerk_client
17
+ from django_clerk_users.exceptions import ClerkConfigurationError
17
18
 
18
19
 
19
20
  class Command(BaseCommand):
@@ -86,7 +87,13 @@ class Command(BaseCommand):
86
87
  "You must specify --email, --all, or --created-before"
87
88
  )
88
89
 
89
- clerk = get_clerk_client()
90
+ try:
91
+ clerk = get_clerk_client()
92
+ except ClerkConfigurationError:
93
+ raise CommandError(
94
+ "CLERK_SECRET_KEY is not configured. "
95
+ "Set it in your Django settings to use Clerk sync commands."
96
+ )
90
97
 
91
98
  # Build queryset
92
99
  queryset = SourceUser.objects.all()
@@ -2,9 +2,10 @@
2
2
  Management command to sync organizations from Clerk to Django.
3
3
  """
4
4
 
5
- from django.core.management.base import BaseCommand
5
+ from django.core.management.base import BaseCommand, CommandError
6
6
 
7
7
  from django_clerk_users.client import get_clerk_client
8
+ from django_clerk_users.exceptions import ClerkConfigurationError
8
9
 
9
10
 
10
11
  class Command(BaseCommand):
@@ -61,7 +62,13 @@ class Command(BaseCommand):
61
62
  sync_members = options["sync_members"]
62
63
  dry_run = options["dry_run"]
63
64
 
64
- clerk = get_clerk_client()
65
+ try:
66
+ clerk = get_clerk_client()
67
+ except ClerkConfigurationError:
68
+ raise CommandError(
69
+ "CLERK_SECRET_KEY is not configured. "
70
+ "Set it in your Django settings to use Clerk sync commands."
71
+ )
65
72
 
66
73
  created_count = 0
67
74
  updated_count = 0
@@ -2,9 +2,10 @@
2
2
  Management command to sync users from Clerk to Django.
3
3
  """
4
4
 
5
- from django.core.management.base import BaseCommand
5
+ from django.core.management.base import BaseCommand, CommandError
6
6
 
7
7
  from django_clerk_users.client import get_clerk_client
8
+ from django_clerk_users.exceptions import ClerkConfigurationError
8
9
  from django_clerk_users.utils import update_or_create_clerk_user
9
10
 
10
11
 
@@ -41,7 +42,13 @@ class Command(BaseCommand):
41
42
  sync_all = options["all"]
42
43
  dry_run = options["dry_run"]
43
44
 
44
- clerk = get_clerk_client()
45
+ try:
46
+ clerk = get_clerk_client()
47
+ except ClerkConfigurationError:
48
+ raise CommandError(
49
+ "CLERK_SECRET_KEY is not configured. "
50
+ "Set it in your Django settings to use Clerk sync commands."
51
+ )
45
52
 
46
53
  created_count = 0
47
54
  updated_count = 0
@@ -20,7 +20,10 @@ from django_clerk_users.authentication.utils import (
20
20
  get_or_create_user_from_payload,
21
21
  )
22
22
  from django_clerk_users.exceptions import ClerkAuthenticationError, ClerkTokenError
23
- from django_clerk_users.settings import CLERK_SESSION_REVALIDATION_SECONDS
23
+ from django_clerk_users.settings import (
24
+ CLERK_SECRET_KEY,
25
+ CLERK_SESSION_REVALIDATION_SECONDS,
26
+ )
24
27
 
25
28
  if TYPE_CHECKING:
26
29
  from django.http import HttpRequest, HttpResponse
@@ -81,6 +84,10 @@ class ClerkAuthMiddleware:
81
84
  request.clerk_payload = None # type: ignore
82
85
  request.org = None # type: ignore
83
86
 
87
+ # Skip Clerk authentication if not configured
88
+ if not CLERK_SECRET_KEY:
89
+ return
90
+
84
91
  # Check if user is already authenticated via Django's standard auth
85
92
  # (e.g., admin login with username/password)
86
93
  if hasattr(request, "user") and request.user.is_authenticated:
@@ -289,7 +289,7 @@ wheels = [
289
289
 
290
290
  [[package]]
291
291
  name = "django-clerk-users"
292
- version = "0.1.1"
292
+ version = "0.1.3"
293
293
  source = { editable = "." }
294
294
  dependencies = [
295
295
  { name = "clerk-backend-api" },
@@ -1,127 +0,0 @@
1
- """
2
- Django system checks for django-clerk-users configuration.
3
- """
4
-
5
- from django.conf import settings
6
- from django.core.checks import Error, Warning, register
7
-
8
-
9
- @register()
10
- def check_clerk_secret_key(app_configs, **kwargs):
11
- """Check that CLERK_SECRET_KEY is configured."""
12
- errors = []
13
- if not getattr(settings, "CLERK_SECRET_KEY", None):
14
- errors.append(
15
- Error(
16
- "CLERK_SECRET_KEY is not configured.",
17
- hint="Set CLERK_SECRET_KEY in your Django settings.",
18
- id="django_clerk_users.E001",
19
- )
20
- )
21
- return errors
22
-
23
-
24
- @register()
25
- def check_clerk_webhook_signing_key(app_configs, **kwargs):
26
- """Check that CLERK_WEBHOOK_SIGNING_KEY is configured."""
27
- warnings = []
28
- if not getattr(settings, "CLERK_WEBHOOK_SIGNING_KEY", None):
29
- warnings.append(
30
- Warning(
31
- "CLERK_WEBHOOK_SIGNING_KEY is not configured.",
32
- hint=(
33
- "Set CLERK_WEBHOOK_SIGNING_KEY in your Django settings "
34
- "if you plan to use Clerk webhooks."
35
- ),
36
- id="django_clerk_users.W001",
37
- )
38
- )
39
- return warnings
40
-
41
-
42
- @register()
43
- def check_auth_user_model(app_configs, **kwargs):
44
- """Check that AUTH_USER_MODEL is configured for Clerk."""
45
- warnings = []
46
- auth_user_model = getattr(settings, "AUTH_USER_MODEL", "auth.User")
47
-
48
- # Check if using a Clerk-compatible user model
49
- if not (
50
- auth_user_model.startswith("django_clerk_users.")
51
- or "clerk" in auth_user_model.lower()
52
- ):
53
- warnings.append(
54
- Warning(
55
- f"AUTH_USER_MODEL is set to '{auth_user_model}'.",
56
- hint=(
57
- "Consider using 'django_clerk_users.ClerkUser' or a custom model "
58
- "that extends AbstractClerkUser for full Clerk integration."
59
- ),
60
- id="django_clerk_users.W002",
61
- )
62
- )
63
- return warnings
64
-
65
-
66
- @register()
67
- def check_middleware_installed(app_configs, **kwargs):
68
- """Check that ClerkAuthMiddleware is installed."""
69
- warnings = []
70
- middleware = getattr(settings, "MIDDLEWARE", [])
71
-
72
- clerk_middleware = "django_clerk_users.middleware.ClerkAuthMiddleware"
73
- if clerk_middleware not in middleware:
74
- warnings.append(
75
- Warning(
76
- "ClerkAuthMiddleware is not in MIDDLEWARE.",
77
- hint=(
78
- f"Add '{clerk_middleware}' to MIDDLEWARE in your Django settings "
79
- "for automatic Clerk authentication."
80
- ),
81
- id="django_clerk_users.W003",
82
- )
83
- )
84
- return warnings
85
-
86
-
87
- @register()
88
- def check_authentication_backend(app_configs, **kwargs):
89
- """Check that ClerkBackend is in AUTHENTICATION_BACKENDS."""
90
- warnings = []
91
- backends = getattr(settings, "AUTHENTICATION_BACKENDS", [])
92
-
93
- clerk_backend = "django_clerk_users.authentication.ClerkBackend"
94
- if clerk_backend not in backends:
95
- warnings.append(
96
- Warning(
97
- "ClerkBackend is not in AUTHENTICATION_BACKENDS.",
98
- hint=(
99
- f"Add '{clerk_backend}' to AUTHENTICATION_BACKENDS in your "
100
- "Django settings."
101
- ),
102
- id="django_clerk_users.W004",
103
- )
104
- )
105
- return warnings
106
-
107
-
108
- @register()
109
- def check_frontend_hosts(app_configs, **kwargs):
110
- """Check that CLERK_FRONTEND_HOSTS is configured."""
111
- warnings = []
112
- frontend_hosts = getattr(settings, "CLERK_FRONTEND_HOSTS", [])
113
- auth_parties = getattr(settings, "CLERK_AUTH_PARTIES", [])
114
-
115
- if not frontend_hosts and not auth_parties:
116
- warnings.append(
117
- Warning(
118
- "CLERK_FRONTEND_HOSTS is not configured.",
119
- hint=(
120
- "Set CLERK_FRONTEND_HOSTS in your Django settings to the list of "
121
- "frontend URLs that will be sending authenticated requests "
122
- "(e.g., ['https://myapp.com', 'http://localhost:3000'])."
123
- ),
124
- id="django_clerk_users.W005",
125
- )
126
- )
127
- return warnings