Skip to content

Commit 046656a

Browse files
authored
Add MS Azure and OpenID Connect login (#179)
1 parent 75725fc commit 046656a

5 files changed

Lines changed: 88 additions & 8 deletions

File tree

alertaclient/api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,16 @@ def login(self, username, password):
301301
return self.http.post('/auth/login', data)
302302

303303
def token(self, provider, data):
304+
if provider == 'azure':
305+
return self.http.post('/auth/azure', data)
304306
if provider == 'github':
305307
return self.http.post('/auth/github', data)
306308
if provider == 'gitlab':
307309
return self.http.post('/auth/gitlab', data)
308310
if provider == 'google':
309311
return self.http.post('/auth/google', data)
312+
if provider == 'openid':
313+
return self.http.post('/auth/openid', data)
310314

311315
def userinfo(self):
312316
return self.http.get('/userinfo')

alertaclient/auth/azure.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
import webbrowser
3+
from uuid import uuid4
4+
5+
from alertaclient.auth.token import TokenHandler
6+
7+
8+
def login(client, azure_tenant, client_id):
9+
xsrf_token = str(uuid4())
10+
redirect_uri = 'http://localhost:9004'
11+
12+
url = (
13+
'https://login.microsoftonline.com/{azure_tenant}/oauth2/authorize?'
14+
'response_type=code'
15+
'&client_id={client_id}'
16+
'&redirect_uri={redirect_uri}'
17+
'&state={state}'
18+
).format(
19+
azure_tenant=azure_tenant,
20+
client_id=client_id,
21+
redirect_uri=redirect_uri,
22+
state=xsrf_token
23+
)
24+
25+
webbrowser.open(url, new=0, autoraise=True)
26+
auth = TokenHandler()
27+
access_token = auth.get_access_token(xsrf_token)
28+
29+
data = {
30+
'code': access_token,
31+
'clientId': client_id,
32+
'redirectUri': redirect_uri
33+
}
34+
return client.token('azure', data)

alertaclient/auth/oidc.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
import webbrowser
3+
from uuid import uuid4
4+
5+
from alertaclient.auth.token import TokenHandler
6+
7+
8+
def login(client, oidc_auth_url, client_id):
9+
xsrf_token = str(uuid4())
10+
redirect_uri = 'http://127.0.0.1:9004'
11+
12+
url = (
13+
'{oidc_auth_url}?'
14+
'response_type=code'
15+
'&client_id={client_id}'
16+
'&redirect_uri={redirect_uri}'
17+
'&scope=openid%20profile%20email'
18+
'&state={state}'
19+
).format(
20+
oidc_auth_url=oidc_auth_url,
21+
client_id=client_id,
22+
redirect_uri=redirect_uri,
23+
state=xsrf_token
24+
)
25+
26+
webbrowser.open(url, new=0, autoraise=True)
27+
auth = TokenHandler()
28+
access_token = auth.get_access_token(xsrf_token)
29+
30+
data = {
31+
'code': access_token,
32+
'clientId': client_id,
33+
'redirectUri': redirect_uri
34+
}
35+
return client.token('openid', data)

alertaclient/commands/cmd_login.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import click
55

6-
from alertaclient.auth import github, gitlab, google
6+
from alertaclient.auth import azure, github, gitlab, google, oidc
77
from alertaclient.auth.token import Jwt
88
from alertaclient.auth.utils import save_token
99
from alertaclient.exceptions import AuthError
@@ -13,21 +13,25 @@
1313
@click.argument('username', required=False)
1414
@click.pass_obj
1515
def cli(obj, username):
16-
"""Authenticate using Github, Gitlab, Google OAuth2 or Basic Auth
17-
username/password instead of using an API key."""
16+
"""Authenticate using Azure, Github, Gitlab, Google OAuth2, OpenID or
17+
Basic Auth username/password instead of using an API key."""
1818
client = obj['client']
1919
provider = obj['provider']
2020
client_id = obj['client_id']
2121

2222
try:
23-
if provider == 'github':
23+
if provider == 'azure':
24+
token = azure.login(client, obj['azure_tenant'], client_id)['token']
25+
elif provider == 'github':
2426
token = github.login(client, obj['github_url'], client_id)['token']
2527
elif provider == 'gitlab':
2628
token = gitlab.login(client, obj['gitlab_url'], client_id)['token']
2729
elif provider == 'google':
2830
if not username:
2931
username = click.prompt('Email')
3032
token = google.login(client, username, client_id)['token']
33+
elif provider == 'openid':
34+
token = oidc.login(client, obj['oidc_auth_url'], client_id)['token']
3135
elif provider == 'basic':
3236
if not username:
3337
username = click.prompt('Email')

alertaclient/config.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import json
21
import configparser
2+
import json
33
import os
44

55
import requests
@@ -59,8 +59,11 @@ def get_remote_config(self, endpoint=None):
5959
r.raise_for_status()
6060
remote_config = r.json()
6161
except requests.RequestException as e:
62-
raise ClientException("Failed to get config from {}. Reason: {}".format(config_url, e))
63-
except json.decoder.JSONDecodeError:
64-
raise ClientException("Failed to get config from {}: Reason: not a JSON object".format(config_url))
62+
raise ClientException('Failed to get config from {}. Reason: {}'.format(config_url, e))
63+
except json.decoder.JSONDecodeError:
64+
raise ClientException('Failed to get config from {}: Reason: not a JSON object'.format(config_url))
65+
66+
if not self.options['client_id']:
67+
del self.options['client_id']
6568

6669
self.options = {**remote_config, **self.options}

0 commit comments

Comments
 (0)