Skip to content

Commit ad0cd09

Browse files
authored
Merge pull request #289 from Xpirix/add_social_auth
Add social authentication using django-allauth
2 parents 596e09e + 4e69232 commit ad0cd09

File tree

24 files changed

+933
-171
lines changed

24 files changed

+933
-171
lines changed

dockerize/docker/REQUIREMENTS.txt

Lines changed: 37 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,48 @@
1+
bandit~=1.9
2+
beautifulsoup4~=4.12
3+
celery~=5.3
4+
cryptography~=46.0.6
5+
detect-secrets~=1.5
16
django~=4.2
2-
django-auth-ldap~=4.6
3-
python-ldap~=3.4
4-
django-taggit~=5.0
5-
django-tinymce==4.1.0
6-
psycopg2-binary~=2.9
7-
# Updates for Django 2
8-
git+https://github.com/metamatik/django-templatetag-sugar.git
9-
# Updates for Django 4
10-
git+https://github.com/Xpirix/django-ratings.git@modernize
11-
django-taggit-autosuggest~=0.4
7+
django-allauth~=65.15
128
django-annoying~=0.10
13-
14-
# Updates for Django 2
15-
# git+https://github.com/elpaso/rpc4django.git@modernize
16-
rpc4django~=0.6
17-
Pillow~=10.1
18-
django-taggit-templatetags
19-
# Updates for Django 4
20-
git+https://github.com/Xpirix/django-simplemenu.git@modernize
9+
django-auth-ldap~=4.6
2110
django-bootstrap-pagination-forked~=1.7
22-
django-sortable-listview~=0.43
23-
sorl-thumbnail~=12.10
24-
django-extensions~=3.2
2511
django-debug-toolbar~=4.2
26-
whoosh~=2.7
12+
django-extensions~=3.2
2713
django-haystack~=3.2
28-
29-
feedparser~=6.0
30-
celery~=5.3
31-
32-
# pin due to issues with a breaking change
33-
# https://github.com/celery/celery/issues/7783
34-
importlib_metadata<5
35-
36-
requests~=2.31
37-
38-
markdown~=3.5
39-
14+
django-matomo==0.1.6
15+
django-preferences==1.0.0
16+
django-rest-auth==0.9.5
17+
django-rest-multiple-models==2.1.3
18+
django-sortable-listview~=0.43
19+
django-taggit~=5.0
20+
django-taggit-autosuggest~=0.4
21+
django-taggit-templatetags
22+
django-tinymce==4.1.0
23+
django-webpack-loader~=3.1
4024
djangorestframework~=3.14
41-
pyjwt~=2.8
4225
djangorestframework-simplejwt~=5.3
43-
sorl-thumbnail-serializer-field==0.2.1
44-
django-rest-auth==0.9.5
4526
drf-yasg~=1.21
46-
django-rest-multiple-models==2.1.3
47-
48-
django-preferences==1.0.0
49-
geoip2==4.5.0
50-
django-matomo==0.1.6
51-
uwsgi~=2.0
27+
feedparser~=6.0
28+
flake8~=7.3
29+
flake8-json~=24.4
5230
freezegun~=1.4
53-
31+
geoip2==4.5.0
32+
git+https://github.com/Xpirix/django-ratings.git@modernize
33+
git+https://github.com/Xpirix/django-simplemenu.git@modernize
34+
git+https://github.com/metamatik/django-templatetag-sugar.git
35+
importlib_metadata<5
36+
markdown~=3.5
37+
oauthlib~=3.2
38+
Pillow~=10.1
39+
psycopg2-binary~=2.9
40+
pyjwt~=2.8
41+
requests~=2.31
42+
rpc4django~=0.6
5443
sentry-sdk~=2.2
55-
django-webpack-loader~=3.1
56-
57-
beautifulsoup4~=4.12
5844
setuptools~=75.1
59-
60-
# Security scanning tools for QGIS Plugin analysis (invoked via subprocess)
61-
# Bandit - Security vulnerability scanner for Python code
62-
bandit~=1.9
63-
64-
# detect-secrets - Finds hardcoded secrets in code
65-
detect-secrets~=1.5
66-
67-
# flake8 for code quality
68-
flake8~=7.3
69-
70-
# flake8-json for structured output (optional but recommended)
71-
flake8-json~=24.4
45+
sorl-thumbnail~=12.10
46+
sorl-thumbnail-serializer-field==0.2.1
47+
uwsgi~=2.0
48+
whoosh~=2.7

docs/oauth-setup.md

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# OAuth Provider Setup
2+
3+
Each provider needs a **SocialApp** entry in the Django Admin.
4+
Go to: **Admin → Social Accounts → Social applications → Add social application**
5+
6+
Fields to fill:
7+
- **Provider** — select from the dropdown
8+
- **Name** — any label (e.g. "GitHub")
9+
- **Client ID** — the OAuth App ID / Client ID from the provider
10+
- **Secret key** — the OAuth Secret from the provider
11+
- **Key** — only required for Apple (the Key ID, see below)
12+
- **Settings** — optional JSON for provider-specific options (e.g. Apple's `certificate_key`)
13+
- **Sites** — move your site (e.g. `example.com`) from "Available" to "Chosen"
14+
15+
---
16+
17+
## GitHub
18+
19+
1. Go to <https://github.com/settings/developers>**OAuth Apps****New OAuth App**
20+
2. Fill in:
21+
- **Application name**: QGIS Plugins (or any label)
22+
- **Homepage URL**: `https://plugins.qgis.org`
23+
- **Authorization callback URL**: `https://plugins.qgis.org/accounts/github/login/callback/`
24+
3. Click **Register application**, then **Generate a new client secret**.
25+
4. In Django Admin:
26+
- Provider: `GitHub`
27+
- Client ID: the **Client ID** shown on the app page
28+
- Secret key: the **Client secret** you just generated
29+
30+
---
31+
32+
## Google
33+
34+
1. Go to <https://console.cloud.google.com/> → Select or create a project.
35+
2. Navigate to **APIs & Services → Credentials → Create Credentials → OAuth client ID**.
36+
3. Set **Application type** to **Web application**.
37+
4. Add to **Authorized redirect URIs**:
38+
```
39+
https://plugins.qgis.org/accounts/google/login/callback/
40+
```
41+
5. Click **Create**. Note the **Client ID** and **Client secret**.
42+
6. In Django Admin:
43+
- Provider: `Google`
44+
- Client ID: the Client ID
45+
- Secret key: the Client secret
46+
47+
> You may also need to enable the **Google People API** under **APIs & Services → Library**.
48+
49+
---
50+
51+
## GitLab
52+
53+
### GitLab.com (default)
54+
55+
1. Go to <https://gitlab.com/-/user_settings/applications>**Add new application**.
56+
2. Fill in:
57+
- **Name**: QGIS Plugins
58+
- **Redirect URI**: `https://plugins.qgis.org/accounts/gitlab/login/callback/`
59+
- **Scopes**: check `read_user`
60+
3. Click **Save application**. Note the **Application ID** and **Secret**.
61+
4. In Django Admin:
62+
- Provider: `GitLab`
63+
- Client ID: the Application ID
64+
- Secret key: the Secret
65+
66+
### Self-hosted GitLab instance
67+
68+
Uncomment and edit the `gitlab` section in `qgis-app/settings_local.py`
69+
(copy from `settings_local.py.templ`):
70+
71+
```python
72+
SOCIALACCOUNT_PROVIDERS = {
73+
"gitlab": {
74+
"GITLAB_URL": "https://your-gitlab.example.com",
75+
"SCOPE": ["read_user"],
76+
},
77+
}
78+
```
79+
80+
Then create the OAuth application on your self-hosted instance at
81+
`https://your-gitlab.example.com/-/profile/applications`.
82+
83+
---
84+
85+
## OpenStreetMap
86+
87+
1. Go to <https://www.openstreetmap.org/user/YOUR_USERNAME/oauth_clients/new>
88+
(replace `YOUR_USERNAME` with your OSM username).
89+
2. Fill in:
90+
- **Name**: QGIS Plugins
91+
- **Main Application URL**: `https://plugins.qgis.org`
92+
- **Callback URL**: `https://plugins.qgis.org/accounts/openstreetmap/login/callback/`
93+
- **Permissions**: check **Read user preferences**
94+
3. Click **Register**. Note the **Consumer Key** and **Consumer Secret**.
95+
4. In Django Admin:
96+
- Provider: `OpenStreetMap`
97+
- Client ID: the Consumer Key
98+
- Secret key: the Consumer Secret
99+
100+
> OSM uses OAuth 1.0a — django-allauth handles this transparently.
101+
102+
---
103+
104+
## Microsoft
105+
106+
1. Go to <https://portal.azure.com/>**Microsoft Entra ID → App registrations → New registration**.
107+
2. Fill in:
108+
- **Name**: QGIS Plugins
109+
- **Supported account types**: *Accounts in any organizational directory and personal Microsoft accounts* (for `"tenant": "common"`)
110+
- **Redirect URI**: Web — `https://plugins.qgis.org/accounts/microsoft/login/callback/`
111+
3. Click **Register**. Note the **Application (client) ID**.
112+
4. Go to **Certificates & secrets → New client secret**. Note the **Value** (only shown once).
113+
5. Go to **API permissions → Add a permission → Microsoft Graph → Delegated → User.Read** → Grant admin consent.
114+
6. In Django Admin:
115+
- Provider: `Microsoft`
116+
- Client ID: the Application (client) ID
117+
- Secret key: the client secret Value
118+
119+
> To restrict to a specific tenant (organisation), change `"tenant": "common"` to your **Directory (tenant) ID** in `settings_local.py`.
120+
121+
---
122+
123+
## Apple
124+
125+
Apple Sign In requires extra steps compared to other providers.
126+
127+
### Prerequisites
128+
You need an Apple Developer account (<https://developer.apple.com>).
129+
130+
### Steps
131+
132+
1. **Create an App ID**:
133+
- Go to **Certificates, Identifiers & Profiles → Identifiers → +**
134+
- Type: **App IDs****App**
135+
- Enable **Sign In with Apple**
136+
- Note the **Bundle ID** (e.g. `org.qgis.plugins`)
137+
138+
2. **Create a Services ID** (this is the OAuth client):
139+
- Go to **Identifiers → +****Services IDs**
140+
- Description: QGIS Plugins
141+
- Identifier: e.g. `org.qgis.plugins.web` (must be unique, different from Bundle ID)
142+
- Enable **Sign In with Apple → Configure**:
143+
- Primary App ID: select the App ID from step 1
144+
- Domains: `plugins.qgis.org`
145+
- Return URLs: `https://plugins.qgis.org/accounts/apple/login/callback/`
146+
- Note the **Services ID** identifier — this is your **Client ID**
147+
148+
3. **Create a Key**:
149+
- Go to **Keys → +**
150+
- Enable **Sign In with Apple → Configure** → select your Primary App ID
151+
- Click **Register** and **Download** the `.p8` file (only downloadable once)
152+
- Note the **Key ID**
153+
154+
4. In Django Admin:
155+
- Provider: `Apple`
156+
- Client ID: the **Services ID** identifier (e.g. `org.qgis.plugins.web`)
157+
- Secret key: your **Team ID** (found top-right in the developer portal, 10 chars)
158+
- Key: paste the full content of the downloaded `.p8` file
159+
160+
django-allauth uses the Team ID + Key ID + `.p8` content to generate a JWT client secret dynamically. You also need to set **Key ID** in `qgis-app/settings_local.py` (copy from `settings_local.py.templ`):
161+
162+
```python
163+
SOCIALACCOUNT_PROVIDERS = {
164+
"apple": {
165+
"APP": {
166+
"client_id": "org.qgis.plugins.web",
167+
"secret": "TEAM_ID",
168+
"key": "KEY_ID",
169+
"settings": {
170+
"certificate_key": """-----BEGIN PRIVATE KEY-----
171+
...your .p8 content here...
172+
-----END PRIVATE KEY-----"""
173+
}
174+
}
175+
},
176+
}
177+
```
178+
179+
The other fields (Client ID = Services ID, Secret key = Team ID) can also be stored in the DB via Admin as a fallback, but the `certificate_key` must be in settings.
180+
181+
---
182+
183+
## LinkedIn
184+
185+
1. Go to <https://www.linkedin.com/developers/apps/new> → Create an app.
186+
2. Fill in the required fields (App name, LinkedIn Page, logo).
187+
3. After creation, go to the **Auth** tab:
188+
- Note the **Client ID** and **Client Secret**
189+
- Add to **Authorized redirect URLs for your app**:
190+
```
191+
https://plugins.qgis.org/accounts/linkedin_oauth2/login/callback/
192+
```
193+
4. Go to the **Products** tab → Request access to **Sign In with LinkedIn using OpenID Connect**.
194+
5. In Django Admin:
195+
- Provider: `LinkedIn`
196+
- Client ID: the Client ID
197+
- Secret key: the Client Secret
198+
199+
> The `openid`, `profile`, and `email` scopes configured in settings require the **OpenID Connect** product to be approved. Standard OAuth2 (`r_liteprofile`, `r_emailaddress`) also works but uses the legacy `linkedin` provider.
200+
201+
---
202+
203+
## Telegram
204+
205+
Telegram uses a **Login Widget** rather than standard OAuth. There is no redirect URI.
206+
207+
1. Open Telegram and message **[@BotFather](https://t.me/BotFather)**.
208+
2. Send `/newbot` and follow the prompts to create a bot. Note the **bot token** (format: `123456789:ABC-...`).
209+
3. Send `/setdomain` to BotFather, select your bot, and enter your domain: `plugins.qgis.org`.
210+
4. In Django Admin:
211+
- Provider: `Telegram`
212+
- Client ID: your **bot username** (without `@`, e.g. `QGISPluginsBot`)
213+
- Secret key: the **bot token** (e.g. `123456789:ABC-...`)
214+
215+
> The Telegram provider works via a login widget that calls back to
216+
> `https://plugins.qgis.org/accounts/telegram/login/callback/`.
217+
> No client secret registration on a portal is needed — the bot token itself signs the payload.
218+
219+
---
220+
221+
## Callback URLs Summary
222+
223+
| Provider | Callback URL |
224+
|---|---|
225+
| GitHub | `/accounts/github/login/callback/` |
226+
| Google | `/accounts/google/login/callback/` |
227+
| GitLab | `/accounts/gitlab/login/callback/` |
228+
| OpenStreetMap | `/accounts/openstreetmap/login/callback/` |
229+
| Microsoft | `/accounts/microsoft/login/callback/` |
230+
| Apple | `/accounts/apple/login/callback/` |
231+
| LinkedIn | `/accounts/linkedin_oauth2/login/callback/` |
232+
| Telegram | `/accounts/telegram/login/callback/` |
233+
234+
Prepend your domain, e.g. `https://plugins.qgis.org/accounts/github/login/callback/`.
235+
236+
For local development replace the domain with `http://localhost:8000` and register a separate OAuth app (or add `localhost` as an allowed redirect on the existing one).

qgis-app/plugins/templates/plugins/plugin_detail.html

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -171,47 +171,6 @@
171171
<link rel="stylesheet" href="{% static "style/dataTables.bulma.css" %}">
172172
{{ block.super }}
173173
<style>
174-
.tooltip {
175-
position: relative;
176-
display: inline-block;
177-
opacity: 1 !important;
178-
margin-left: 10px;
179-
}
180-
181-
.tooltip .tooltiptext {
182-
visibility: hidden;
183-
width: 200px;
184-
background-color: #363636;
185-
color: #fff;
186-
text-align: center;
187-
border-radius: 6px;
188-
padding: 8px;
189-
position: absolute;
190-
z-index: 1000;
191-
bottom: 125%;
192-
left: 50%;
193-
margin-left: -100px;
194-
opacity: 0;
195-
transition: opacity 0.3s;
196-
font-size: 0.875rem;
197-
line-height: 1.4;
198-
}
199-
200-
.tooltip .tooltiptext::after {
201-
content: "";
202-
position: absolute;
203-
top: 100%;
204-
left: 50%;
205-
margin-left: -5px;
206-
border-width: 5px;
207-
border-style: solid;
208-
border-color: #363636 transparent transparent transparent;
209-
}
210-
211-
.tooltip:hover .tooltiptext {
212-
visibility: visible;
213-
opacity: 1;
214-
}
215174
.tab-content .tab-pane.is-active {
216175
display: block;
217176
}

0 commit comments

Comments
 (0)