Skip to content

Commit 7ca8e13

Browse files
authored
OIDC support (#33)
1 parent 01062d8 commit 7ca8e13

File tree

23 files changed

+209
-502
lines changed

23 files changed

+209
-502
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
4+
## 0.8.0 - 2024-03-03
5+
6+
- OIDC support
7+
38
## 0.7.0 - 2024-02-18
49

510
- Refactoring - all sql functions to have session as first arg

README.md

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ Following authentication methods are supported:
88

99
* database - authenticate against user credentials from the database's
1010
core_user table
11-
* google auth - authenticate against Google's user account credentials
12-
* github auth - authenticate against Github's user account credentials
11+
* oidc - authenticate against OIDC provider
12+
* ldap - authenticate with LDAP
1313

1414
When authentication succeeds, auth server responds with a valid
1515
cryptographically signed JWT access token.
@@ -94,58 +94,23 @@ volumes:
9494
maria:
9595
```
9696

97-
In order to enable authentication via Google accounts you need to
97+
In order to enable authentication via OIDC provider you need to
9898
provide following environment variables:
9999

100-
* `PAPERMERGE__AUTH__GOOGLE_CLIENT_SECRET`
101-
* `PAPERMERGE__AUTH__GOOGLE_CLIENT_ID`
102-
* `PAPERMERGE__AUTH__GOOGLE_AUTHORIZE_URL`
103-
* `PAPERMERGE__AUTH__GOOGLE_REDIRECT_URI`
100+
* `PAPERMERGE__AUTH__OIDC_CLIENT_SECRET`
101+
* `PAPERMERGE__AUTH__OIDC_CLIENT_ID`
102+
* `PAPERMERGE__AUTH__OIDC_AUTHORIZE_URL`
103+
* `PAPERMERGE__AUTH__OIDC_REDIRECT_URI`
104104

105-
You need to provider all four values. First two, client_id and client_secret,
106-
you obtain when registering oauth2 client with Google.
105+
You need to provider all four values.
107106

108-
`PAPERMERGE__AUTH__GOOGLE_AUTHORIZE_URL` is the URL of the Google authorization
109-
server. As of writing this documentation, its value is:
107+
`PAPERMERGE__AUTH__OIDC_REDIRECT_URI` should be:
110108

111-
https://accounts.google.com/o/oauth2/auth
112-
113-
just keep in mind that it may change thus you need to check Google's oauth2
114-
documentation for its current value.
115-
116-
`PAPERMERGE__AUTH__GOOGLE_REDIRECT_URI` should be:
117-
118-
<http|https>://<your domain>/google/callback
109+
<http|https>://<your domain>/oidc/callback
119110

120111
Above value should be same as in field "Authorized redirect URI" when
121112
registering oauth2 client.
122113

123-
To enable authentication via Github accounts you need to provider following env
124-
variables:
125-
126-
* `PAPERMERGE__AUTH__GITHUB_CLIENT_SECRET`
127-
* `PAPERMERGE__AUTH__GITHUB_CLIENT_ID`
128-
* `PAPERMERGE__AUTH__GITHUB_AUTHORIZE_URL`
129-
* `PAPERMERGE__AUTH__GITHUB_REDIRECT_URI`
130-
131-
Similarely with Google's oauth2 case, you need to provide all four values.
132-
Client secret and client id you get when registering oauth2 client.
133-
134-
Current value for `PAPERMERGE__AUTH__GITHUB_AUTHORIZE_URL`, is
135-
136-
https://github.com/login/oauth/authorize
137-
138-
Keep in mind to double check GitHub's documentation for up-to-date GitHub
139-
oauth2 authentication server URL.
140-
141-
Value for `PAPERMERGE__AUTH__GITHUB_REDIRECT_URI` should be:
142-
143-
<http|https>://<your domain>/github/callback
144-
145-
Above value should be same as in field "Authorized callback URI" when
146-
registering Github oauth2 client.
147-
148-
149114
You can also start the auth server with poetry:
150115

151116
$ poetry run uvicorn auth_server.main:app \
@@ -218,20 +183,11 @@ which means that many scheme described in sqlalchemy docs will not
218183
work for papermerge-core.
219184

220185

221-
### Google Auth
222-
223-
Either all four values should be provided or none.
224-
225-
* `PAPERMERGE__AUTH__GOOGLE_CLIENT_SECRET`
226-
* `PAPERMERGE__AUTH__GOOGLE_CLIENT_ID`
227-
* `PAPERMERGE__AUTH__GOOGLE_AUTHORIZE_URL`
228-
* `PAPERMERGE__AUTH__GOOGLE_REDIRECT_URI`
229-
230-
### Github Auth
186+
### OIDC Auth
231187

232188
Either all four values should be provided or none.
233189

234-
* `PAPERMERGE__AUTH__GITHUB_CLIENT_SECRET`
235-
* `PAPERMERGE__AUTH__GITHUB_CLIENT_ID`
236-
* `PAPERMERGE__AUTH__GITHUB_AUTHORIZE_URL`
237-
* `PAPERMERGE__AUTH__GITHUB_REDIRECT_URI`
190+
* `PAPERMERGE__AUTH__OIDC_CLIENT_SECRET`
191+
* `PAPERMERGE__AUTH__OIDC_CLIENT_ID`
192+
* `PAPERMERGE__AUTH__OIDC_AUTHORIZE_URL`
193+
* `PAPERMERGE__AUTH__OIDC_REDIRECT_URI`

auth_server/auth.py

Lines changed: 17 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
1313
from .database.models import User
1414
from . import schemas
1515
from .config import Settings
16-
from .backends import (
17-
GoogleAuth,
18-
GithubAuth,
19-
)
16+
from .backends import OIDCAuth
2017
from .backends import ldap
2118
from .utils import raise_on_empty
2219

@@ -33,42 +30,26 @@ async def authenticate(
3330
provider: schemas.AuthProvider = schemas.AuthProvider.DB,
3431
client_id: str | None = None,
3532
code: str | None = None,
36-
redirect_uri: str | None = None
33+
redirect_url: str | None = None
3734
) -> schemas.User | None:
3835

3936
# provider = DB
4037
if username and password and provider == schemas.AuthProvider.DB:
4138
# password based authentication against database
4239
return db_auth(db, username, password)
4340

44-
if provider == schemas.AuthProvider.GOOGLE:
45-
# provider = GOOGLE (oauth2/google)
41+
if provider == schemas.AuthProvider.OIDC:
4642
raise_on_empty(
4743
code=code,
4844
client_id=client_id,
4945
provider=provider,
50-
redirect_uri=redirect_uri
46+
redirect_url=redirect_url
5147
)
52-
# oauth 2.0, google provider
53-
return await google_auth(
48+
return await oidc_auth(
5449
db,
5550
client_id=client_id,
5651
code=code,
57-
redirect_uri=redirect_uri
58-
)
59-
elif provider == schemas.AuthProvider.GITHUB:
60-
# provider = GitHub (oauth2/github)
61-
raise_on_empty(
62-
code=code,
63-
client_id=client_id,
64-
provider=provider,
65-
redirect_uri=redirect_uri
66-
)
67-
return await github_auth(
68-
db,
69-
client_id=client_id,
70-
code=code,
71-
redirect_uri=redirect_uri
52+
redirect_url=redirect_url
7253
)
7354
elif provider == schemas.AuthProvider.LDAP:
7455
# provider = ldap
@@ -163,69 +144,33 @@ async def ldap_auth(
163144
return get_or_create_user_by_email(db, email)
164145

165146

166-
async def google_auth(
147+
async def oidc_auth(
167148
db: Session,
168149
client_id: str,
169150
code: str,
170-
redirect_uri: str
151+
redirect_url: str
171152
) -> User | None:
172-
if settings.papermerge__auth__google_client_secret is None:
173-
raise HTTPException(
174-
status_code=400,
175-
detail = "Google client secret is empty"
176-
)
177-
178-
client = GoogleAuth(
179-
client_secret = settings.papermerge__auth__google_client_secret,
180-
client_id=client_id,
181-
code=code,
182-
redirect_uri = redirect_uri
183-
)
184-
185-
logger.debug("Auth:google: sign in")
186-
187-
try:
188-
await client.signin()
189-
except Exception as ex:
190-
logger.warning(f"Auth:google: sign in failed with {ex}")
191-
192-
raise HTTPException(
193-
status_code=401,
194-
detail = f"401 Unauthorized. Auth provider error: {ex}."
195-
)
196-
197-
email = await client.user_email()
198-
199-
return get_or_create_user_by_email(db, email)
200-
201-
202-
async def github_auth(
203-
db: Session,
204-
client_id: str,
205-
code: str,
206-
redirect_uri: str
207-
) -> User:
208-
209-
logger.info("Auth:Github: sign in")
210-
if settings.papermerge__auth__github_client_secret is None:
153+
if settings.papermerge__auth__oidc_client_secret is None:
211154
raise HTTPException(
212155
status_code=400,
213-
detail = "Github client secret is empty"
156+
detail = "OIDC client secret is empty"
214157
)
215158

216-
client = GithubAuth(
217-
client_secret = settings.papermerge__auth__github_client_secret,
159+
client = OIDCAuth(
160+
client_secret=settings.papermerge__auth__oidc_client_secret,
161+
access_token_url=settings.papermerge__auth__oidc_access_token_url,
162+
user_info_url=settings.papermerge__auth__oidc_user_info_url,
218163
client_id=client_id,
219164
code=code,
220-
redirect_uri = redirect_uri
165+
redirect_url=redirect_url
221166
)
222167

223-
logger.debug("Auth:Github: sign in")
168+
logger.debug("Auth:oidc: sign in")
224169

225170
try:
226171
await client.signin()
227172
except Exception as ex:
228-
logger.warning(f"Auth:Github: sign in failed with {ex}")
173+
logger.warning(f"Auth:oidc: sign in failed with {ex}")
229174

230175
raise HTTPException(
231176
status_code=401,

auth_server/backends/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
from .google import GoogleAuth
2-
from .github import GithubAuth
1+
from .oidc import OIDCAuth
32
from .ldap import LDAPAuth

auth_server/backends/github.py

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

0 commit comments

Comments
 (0)