0
0
Fork 0
mirror of https://github.com/alerta/alerta.git synced 2025-02-14 01:31:22 +00:00
alerta_alerta/tests/test_providers.py
2019-03-30 23:29:28 +01:00

763 lines
36 KiB
Python

import json
import unittest
import jwt
import requests_mock
from alerta.app import create_app, db
from alerta.models.enums import Scope
from alerta.models.key import ApiKey
class AuthProvidersTestCase(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
db.destroy()
@requests_mock.mock()
def test_azure(self, m):
test_config = {
'TESTING': True,
'AUTH_REQUIRED': True,
'CUSTOMER_VIEWS': True,
'AZURE_TENANT': 'f24341ef-7a6f-4cff-abb7-99a11ab11127'
}
self.app = create_app(test_config)
self.client = self.app.test_client()
with self.app.test_request_context('/'):
self.app.preprocess_request()
self.api_key = ApiKey(
user='admin@alerta.io',
scopes=[Scope.admin, Scope.read, Scope.write],
text='demo-key'
)
self.api_key.create()
self.headers = {
'Authorization': 'Key %s' % self.api_key.key,
'Content-type': 'application/json'
}
# add customer mapping
payload = {
'customer': 'Alerta IO',
'match': 'nfsatterly@gmail.com'
}
response = self.client.post('/customer', data=json.dumps(payload),
content_type='application/json', headers=self.headers)
self.assertEqual(response.status_code, 201)
authorization_grant = """
{
"code": "AQABAAIAAACEfexXxjamQb3OeGQ4GugvJfMVkt3b4O9rcjh8Euhco7OpeacDZ2B-y249nPI6bFmVXZHz5x-NVY7G9UumTVrd9GZGLt7g4PN6WL50NxPROTFTZWOX3lZW4FHh6VQh9TfQ6w2-V_G4YUkJe14MZVlunWg7_AEi0HcINg1k6T1yeM9R538zzDoypaH9kP3s1QwK5O4nsBbt8azqW4QdEoQQDs1r9W9UnV3GTAEdQdS-tpaeax0-ZVlX0GlQdygw0eDfAsRxFZV2qRY9DcUyLDL_mFrlh35T7NuihSkJTvm5vIu5kzqm6Lub5oKJBBIIvQzUbW8_waTIjIPh28D1drKDCY0_QSneZsrndHTYrLJaBtJqz-M0yd6bE6xz1Vh96G997DzWyxW_ZsRaT2YIrg0CD407cqSTDrsz4GiuBbtLsSHSBwMYNSYL7RKW-uxiVD8aRMn46OSVB2nkDuKGqsv7fEcBWEQ-YQM4cYhJp6V6UWG3XBOP-O0fqlFXLyztVB8rHXyVUAllkPYEl3DVW1ToJKSr-zPLo__RXZEXGCmGvMDHFg51O04Vh21KyiGfDtuRwrv_XuMao8342G9aFanCE6oMrNx2qqWZ9fCaVmd0K5ODgUVhSx_Rd1yYVmz39X9iuFuasx5X5ftZlcdPiy0b6rsqLAlfZcRvgkS21DtwCOLvk7g4ND_k2kDDMx_EyEeaf_cosas4l_Iwxcbng6ZBkP6e2y90ccSAUAtCoCR_rOLyEP_h_FgWJ_eGJWQZGQaLWyl0ELGHPAiFq0E2lyFFJ7z3FMVA50FzGtK7ndBrYs01ZA5845_oxdzkJzQyDYY_5Vw0qJ-nmTeSrgXdbPk9RiwfsdOrKscMi-Vmz2kiKfGxa0adKFx6KKbFjs4_X-66KciSMy_b-kEG8P7m-069qxR6XL_i3SfcGiN18io9PCcqgi_0MIwLMQyO-wl0soF-PZVf4zF1ofjccxnQbpJEW2qU9x5r5bCghgA0aD3wtx0WvNx221AJ28jJ00SRd2B36zkfHe5VXuuip_lnpY8SRO6Tb5vL5BYMo9erCMQhv_lOxcsfmlJ0TqeBDyv2pbIPxBqUILtSoJeW-uQxyZMuIAA",
"clientId": "38ba6223-a887-43e2-9f7d-8d539df55f67",
"redirectUri": "http://local.alerta.io:8000"
}
"""
discovery_doc = """
{
"authorization_endpoint": "https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/oauth2/authorize",
"token_endpoint": "https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/oauth2/token",
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"private_key_jwt",
"client_secret_basic"
],
"jwks_uri": "https://login.microsoftonline.com/common/discovery/keys",
"response_modes_supported": [
"query",
"fragment",
"form_post"
],
"subject_types_supported": [
"pairwise"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"http_logout_supported": true,
"frontchannel_logout_supported": true,
"end_session_endpoint": "https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/oauth2/logout",
"response_types_supported": [
"code",
"id_token",
"code id_token",
"token id_token",
"token"
],
"scopes_supported": [
"openid"
],
"issuer": "https://sts.windows.net/f24341ef-7a6f-4cff-abb7-99a11ab11127/",
"claims_supported": [
"sub",
"iss",
"cloud_instance_name",
"cloud_instance_host_name",
"cloud_graph_host_name",
"msgraph_host",
"aud",
"exp",
"iat",
"auth_time",
"acr",
"amr",
"nonce",
"email",
"given_name",
"family_name",
"nickname"
],
"microsoft_multi_refresh_token": true,
"check_session_iframe": "https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/oauth2/checksession",
"userinfo_endpoint": "https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/openid/userinfo",
"tenant_region_scope": "EU",
"cloud_instance_name": "microsoftonline.com",
"cloud_graph_host_name": "graph.windows.net",
"msgraph_host": "graph.microsoft.com",
"rbac_url": "https://pas.windows.net"
}
"""
access_token = """
{
"token_type": "Bearer",
"scope": "User.Read",
"expires_in": "3600",
"ext_expires_in": "3600",
"expires_on": "1553983022",
"not_before": "1553979122",
"resource": "00000002-0000-0000-c000-000000000000",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik4tbEMwbi05REFMcXdodUhZbkhRNjNHZUNYYyIsImtpZCI6Ik4tbEMwbi05REFMcXdodUhZbkhRNjNHZUNYYyJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9mMjQzNDFlZi03YTZmLTRjZmYtYWJiNy05OWExMWFiMTExMjcvIiwiaWF0IjoxNTUzOTc5MTIyLCJuYmYiOjE1NTM5NzkxMjIsImV4cCI6MTU1Mzk4MzAyMiwiYWNyIjoiMSIsImFpbyI6IkFVUUF1LzhLQUFBQStQZzdRcW5EUFY3Q1JFdEsweUlESFdoTHVLL1BzZFQ3ZmtKSHE3YmxFT0dZMGpyTERvanJ4STVpUjk1eU0xZCsrVkQwZ3VuTSt5K2RpYVhvL0ErdzZBPT0iLCJhbHRzZWNpZCI6IjE6bGl2ZS5jb206MDAwMzQwMDFGMTI1MUFBRCIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiIzOGJhNjIyMy1hODg3LTQzZTItOWY3ZC04ZDUzOWRmNTVmNjciLCJhcHBpZGFjciI6IjEiLCJlbWFpbCI6Im5mc2F0dGVybHlAZ21haWwuY29tIiwiZmFtaWx5X25hbWUiOiJTYXR0ZXJseSIsImdpdmVuX25hbWUiOiJOaWNrIiwiaWRwIjoibGl2ZS5jb20iLCJpcGFkZHIiOiIxNDUuMTQuMTEyLjEwMyIsIm5hbWUiOiJOaWNrIFNhdHRlcmx5Iiwib2lkIjoiZGNhMGFjYWItMTcyNy00MTJiLWEwM2EtMGUzYTRiNjYyNmIxIiwicHVpZCI6IjEwMDMyMDAwM0M2ODk5ODYiLCJzY3AiOiJVc2VyLlJlYWQiLCJzdWIiOiJndWN1a2FaNzRrSmtxVGZpdGpQQ1ZsVWkyQ1J4NUtVdVFaTDlNaWpRUlZRIiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkVVIiwidGlkIjoiZjI0MzQxZWYtN2E2Zi00Y2ZmLWFiYjctOTlhMTFhYjExMTI3IiwidW5pcXVlX25hbWUiOiJsaXZlLmNvbSNuZnNhdHRlcmx5QGdtYWlsLmNvbSIsInV0aSI6ImJOeC1UbVlZY2tXbUxmekxFLUVWQUEiLCJ2ZXIiOiIxLjAifQ.GM_KwtpOX18LHgA-0y7sdKM5DKiHaoSfA81lClJulkJ2nPJROpGND226m2MJycQqrNrYz-kEMe-6_rpApian1-xGygsprwa4lDwUtIlxa_PQs4-DQB9GFC9h31o4bPhnP5QqH5bjNZzpUTX_9v91qe9hwpbBct0fHgl9uVZD-aW8TYCLNx5_OhAb9uOmCN6prvmhK4Ttv47UU4mfWmXMInUlRIZUJ-84izdqWPeV9rk6Y6WqttwFNVunzXUGQ_1FujJB2RbHXbSrk-JKl12HOm0NA-m4Xxn0Z0K3oA2LOYtwCiTvrNtlcUDr6Lwy3vGnNtzzUAwsrTCWWvwzrfEpWw",
"refresh_token": "AQABAAAAAACEfexXxjamQb3OeGQ4GugvEpV_oEBJ-4rwh3wnP_fgyuzUG0l2_I6ofeaxYrRJbmZIuybWJMVtrFt1mcxepuqkYP_X8ngoivbN4RI0kRtxI59bLbedLhq3lUUlcJIThiPLL0WRPDy7St6gICL-vbsEMe4y_1ltjoiGBlj8OaOk4o5BVWbKkXtzy2gI6IPNKHukHZ00T1sPZWA0YrObLlu9h-Tt1CcdoLxWSWRGshATAu-XepC7MNgmjSvQAUXxuW7Y6t_w3gSHGyNlPpEVm_H3oKU2RLSMvQsLi-PKLJ0WS3DXYy01V6AG3huyWY562Cd80xcgT1Ly2gl4kBjsxGwABxwNSEcgyCWVs4nzWKCdzcZ1mscyAtmY4Kr74xxGlIwPQ6Sx34gLEunnoHDGXn_RE0ipzc7qg-e5Ws8bv8_JLVHQYXm4Mi_5KRpuh_5tFBtbn5aUc6TJQqRyQOUrG_A4IER_YbTN0u90Io0C4acrp9GVidpFagmG2vL-dqczZ-rv0rLmhX0uRE__PHz7biY0UaRNURgS4hkDB33vyEsw5o-E3N9b09ajwhHiz55PkV22LfESB5ebPpRW2d5AZmKwPBkE57Z0i9oC8Z_ZfIrO2xo_deDXFiKKndFbzIlnYc4Th37lcVBd5B3yDAtfLJNkw7dtCHA4caS7kYayako2cPvkYpM13Jh3dNEiYtY9rUeaF8fkj0pvOH0g4gITQdRcMAFtyHosXrRWMrbweIVYpZ5HOF18abZcmnGs41jUjci4GR_q0SJvdt15-QdmMdDu4GlFFfNvZTtpxKb51ref1a44sdTr77fgFWVFVlYgaw3yyDV3PoYrrWksf3xFEYfOvfhZ6OkroYewPGcVwcDW-4WkEceD-RcMRzkjd1Mecu5RAPQeIWjxort6Gq1OvVHbUl4eSLA256mxLJur0W84vOHZpv3rgg9SbUP81tcPRwYGT00xJDt-mXh1mEx9RukPLpJ_BgU51TvOnch_YsFCnRW-C2jBY40OJvHqpFxZ2vUhpiROxj9phJEPO0APWTdpmXmQdycWchfoxB9LhCLF6S16fX-3rmvMc-woIhV0oNQmZt5n2HHPx-LQsHVOkNs93nr6yzIcNXLfw-QkJScArlLwgtEJ9vXVnefCLhA6TNHXYxquf6FJbarih4LB-51Cf9NmejaA8-nWLL6Sdv5234fXm-9mVq1gKeAdIM4JctidYyfm7juuDZtY3ocDiHGNK-gqPmOklWxp2hOL6ry3haoqC--j9DFNbN6cAavMX00t_NBTKA8U4qRY6yHidF_xoxM9_HwZp0SHJgJzYYKRJKxc0pfvRFHFM_Ciwb4xsFjn7OIMoxkfvAUD2Mp2JaZuQBXeOSt4l-oe1xKQoJbGdcEZa1J9Gr0BRoQhtvFiUoJa3ahNlPTsbCY38oFFS7tnIAA",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIzOGJhNjIyMy1hODg3LTQzZTItOWY3ZC04ZDUzOWRmNTVmNjciLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9mMjQzNDFlZi03YTZmLTRjZmYtYWJiNy05OWExMWFiMTExMjcvIiwiaWF0IjoxNTUzOTc5MTIyLCJuYmYiOjE1NTM5NzkxMjIsImV4cCI6MTU1Mzk4MzAyMiwiYW1yIjpbInB3ZCJdLCJlbWFpbCI6Im5mc2F0dGVybHlAZ21haWwuY29tIiwiZmFtaWx5X25hbWUiOiJTYXR0ZXJseSIsImdpdmVuX25hbWUiOiJOaWNrIiwiaWRwIjoibGl2ZS5jb20iLCJpcGFkZHIiOiIxNDUuMTQuMTEyLjEwMyIsIm5hbWUiOiJOaWNrIFNhdHRlcmx5Iiwib2lkIjoiZGNhMGFjYWItMTcyNy00MTJiLWEwM2EtMGUzYTRiNjYyNmIxIiwic3ViIjoiOUhZaGR3X2Y3NjdyWE5JazUyamFfNldNeTE3UENTTGttcXZQSGlwcnNjYyIsInRpZCI6ImYyNDM0MWVmLTdhNmYtNGNmZi1hYmI3LTk5YTExYWIxMTEyNyIsInVuaXF1ZV9uYW1lIjoibGl2ZS5jb20jbmZzYXR0ZXJseUBnbWFpbC5jb20iLCJ2ZXIiOiIxLjAifQ."
}
"""
m.get('https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/.well-known/openid-configuration', text=discovery_doc)
m.post('https://login.microsoftonline.com/f24341ef-7a6f-4cff-abb7-99a11ab11127/oauth2/token', text=access_token)
response = self.client.post('/auth/azure', data=authorization_grant, content_type='application/json')
self.assertEqual(response.status_code, 200, response.data)
data = json.loads(response.data.decode('utf-8'))
claims = jwt.decode(data['token'], verify=False)
self.assertEqual(claims['name'], 'Nick Satterly', claims)
self.assertEqual(claims['preferred_username'], 'nfsatterly@gmail.com', claims)
self.assertEqual(claims['provider'], 'azure', claims)
# self.assertEqual(claims['roles'], [], claims)
self.assertEqual(claims['orgs'], ['gmail.com'], claims)
self.assertEqual(claims['scope'], 'read write', claims)
self.assertEqual(claims['email'], 'nfsatterly@gmail.com', claims)
self.assertEqual(claims.get('email_verified'), None, claims)
self.assertEqual(claims['customers'], ['Alerta IO'], claims)
@requests_mock.mock()
def test_gitlab(self, m):
test_config = {
'TESTING': True,
'AUTH_REQUIRED': True,
'CUSTOMER_VIEWS': True,
'ALLOWED_GITLAB_GROUPS': ['alerta-project']
}
self.app = create_app(test_config)
self.client = self.app.test_client()
with self.app.test_request_context('/'):
self.app.preprocess_request()
self.api_key = ApiKey(
user='admin@alerta.io',
scopes=[Scope.admin, Scope.read, Scope.write],
text='demo-key'
)
self.api_key.create()
self.headers = {
'Authorization': 'Key %s' % self.api_key.key,
'Content-type': 'application/json'
}
# add customer mapping
payload = {
'customer': 'Alerta IO',
'match': 'alertaio'
}
response = self.client.post('/customer', data=json.dumps(payload),
content_type='application/json', headers=self.headers)
self.assertEqual(response.status_code, 201)
authorization_grant = """
{
"code": "68d753e94fab78d24e13cfa34882c2740b74ba251859bec147f56281d6ea1dd1",
"clientId": "765904e9909fc9cc5c448a887849029d999cc2e400e097221bf910be39a16678",
"redirectUri": "http://local.alerta.io:8000"
}
"""
access_token = """
{
"access_token": "2152f0d2256fe245a98532e699cc7fae51c24fc85437d0f095246ae0890db0fe",
"token_type": "bearer",
"refresh_token": "10687059782a69dd76db7466b5f6fbe3395b9db09e78319db61d5473e31e7b2f",
"scope": "openid profile email",
"created_at": 1553982929,
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Imtld2lRcTlqaUM4NEN2U3NKWU9CLU42QThXRkxTVjIwTWIteTdJbFdEU1EifQ.eyJpc3MiOiJodHRwczovL2dpdGxhYi5jb20iLCJzdWIiOiIxNTY1MDEyIiwiYXVkIjoiNzY1OTA0ZTk5MDlmYzljYzVjNDQ4YTg4Nzg0OTAyOWQ5OTljYzJlNDAwZTA5NzIyMWJmOTEwYmUzOWExNjY3OCIsImV4cCI6MTU1Mzk4MzE2MywiaWF0IjoxNTUzOTgzMDQzLCJhdXRoX3RpbWUiOjE1NTMwMjQ3ODksInN1Yl9sZWdhY3kiOiJlZDk4YjUwZGI5NzdlNmNlMTczMjRhYTkyMmMzZDBlYmIwMzdiYTRjNjBkN2RlZjE2YjQ5YzlkYmJmYjIyYzc1In0.O0SpmNXksWxM1WFH9G8_0cK4d1nVg2bYV2ICUZLn6kKX5ZJ48TOTtNMPpSGF_8MkF-ZlPNse9bsx8Dp_1BmIZCVqhV0bMkRGHtPUYZJEflLln8-mOOpg0ave55HG3yYXTaegPc60CDA-UnXTVhOkzVnvjPF2RcD7EgVKXYOyI2uJ9aebz43_h02eNjIAnJig8VZAeJZbt-0LE2rMlMB3aLS9a3C015_HR9cjqoeZ4ckUpg4F3xRpROpA5hZvpRsZRRq5W56mlSrZ_6GysPCxsruxOgNkw9Of5j-i1IWGxH0mM8oG4EtRIL7y4sBO16YYKVQihkJ1zAtFLa5wQH7pK6I4uShJAoqq21EhDJqZU3-ucuWupbQHubybGdrl_y6Gk6oxFb8BHHf2yE6faQ1QznwT5kiqZH1vdCGr9HP2PheNKZnXuGn-EKy0HRI_tuN5tcIvHV4cXa6xbeiYGCgbZWqJpLWTCLDuPzT_BsinLwgZW5bvO7zXs6N5VRaWWbC03A9FWIZK9tl1xFGfa411eFVM-G5UBEjJNvT0kZHdiNHGkNG-MyO1soT0p741e-yvKQEIQwdo6kyNZ-ZJ6yA0NSmHZy4b3DM67zn5L8uZ0fSToQV0oYnbDjn40Tm83qL3oZqvLr4Y1kKQjO9AK5kOzLtFRNqxvZ2d-FtkdyHgTKM"
}
"""
tokeninfo = """
{
"resource_owner_id": 1565012,
"scopes": [
"openid",
"profile",
"email"
],
"expires_in_seconds": null,
"application": {
"uid": "765904e9909fc9cc5c448a887849029d999cc2e400e097221bf910be39a16678"
},
"created_at": 1553982929
}
"""
userinfo = """
{
"sub": "1565012",
"sub_legacy": "ed98b50db977e6ce17324aa922c3d0ebb037ba4c60d7def16b49c9dbbfb22c75",
"name": "Nick Satterly",
"nickname": "satterly",
"email": "nfsatterly@gmail.com",
"email_verified": true,
"website": "http://alerta.io",
"profile": "https://gitlab.com/satterly",
"picture": "https://secure.gravatar.com/avatar/520444488b63424244e4c90a5b943b91?s=80&d=identicon",
"groups": [
"team-alerta",
"alertaio",
"alerta-project",
"team-alerta/core",
"team-alerta/cli",
"team-alerta/sdk"
]
}
"""
m.post(self.app.config['GITLAB_URL'] + '/oauth/token', text=access_token)
m.get(self.app.config['GITLAB_URL'] + '/oauth/token/info', text=tokeninfo)
m.post(self.app.config['GITLAB_URL'] + '/oauth/userinfo', text=userinfo)
response = self.client.post('/auth/gitlab', data=authorization_grant, content_type='application/json')
self.assertEqual(response.status_code, 200, response.data)
data = json.loads(response.data.decode('utf-8'))
claims = jwt.decode(data['token'], verify=False)
self.assertEqual(claims['name'], 'Nick Satterly', claims)
self.assertEqual(claims['preferred_username'], 'satterly', claims)
self.assertEqual(claims['provider'], 'gitlab', claims)
# self.assertEqual(claims['roles'], [], claims)
self.assertEqual(claims['groups'],
['team-alerta', 'alertaio', 'alerta-project',
'team-alerta/core', 'team-alerta/cli', 'team-alerta/sdk'],
claims)
self.assertEqual(claims['scope'], 'read write', claims)
self.assertEqual(claims['email'], 'nfsatterly@gmail.com', claims)
self.assertEqual(claims.get('email_verified'), None, claims)
self.assertEqual(claims['customers'], ['Alerta IO'], claims)
@requests_mock.mock()
def test_google(self, m):
test_config = {
'TESTING': True,
'AUTH_REQUIRED': True,
'CUSTOMER_VIEWS': True
}
self.app = create_app(test_config)
self.client = self.app.test_client()
with self.app.test_request_context('/'):
self.app.preprocess_request()
self.api_key = ApiKey(
user='admin@alerta.io',
scopes=[Scope.admin, Scope.read, Scope.write],
text='demo-key'
)
self.api_key.create()
self.headers = {
'Authorization': 'Key %s' % self.api_key.key,
'Content-type': 'application/json'
}
# add customer mapping
payload = {
'customer': 'Google Inc.',
'match': 'gmail.com'
}
response = self.client.post('/customer', data=json.dumps(payload),
content_type='application/json', headers=self.headers)
self.assertEqual(response.status_code, 201)
authorization_grant = """
{
"code": "4/HAGPqNLjICAusQsYooo85izagxMM-_KJe2ZrEO7_lRPY7sG7-G79KMt-aZu-L6DF8Yy-Umb5iNXMdzFC041PdEE",
"clientId": "736147134702-glkb1pesv716j1utg4llg7c3rr7nnhli.apps.googleusercontent.com",
"redirectUri": "http://local.alerta.io:8000"
}
"""
discovery_doc = """
{
"issuer": "https://accounts.google.com",
"authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
"token_endpoint": "https://oauth2.googleapis.com/token",
"userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
"revocation_endpoint": "https://oauth2.googleapis.com/revoke",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token",
"none"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"profile"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"iss",
"locale",
"name",
"picture",
"sub"
],
"code_challenge_methods_supported": [
"plain",
"S256"
]
}
"""
access_token = """
{
"access_token": "ya29.GmPbBq199Kx4bH7wwQrAnuQ4F6DhVn9Y3qCVnalVqVnOcFhJSqV5dZiABs4jbS8LFyVFBBYy_VXLmCRt4h4eP7sN11NyIK1kj-7M0t1RB6GvKS1ElLZBjvVzDDCoHG3SFVJVZAc",
"expires_in": 3599,
"scope": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email openid",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImE0MzEzZTdmZDFlOWUyYTRkZWQzYjI5MmQyYTdmNGU1MTk1NzQzMDgiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI3MzYxNDcxMzQ3MDItZ2xrYjFwZXN2NzE2ajF1dGc0bGxnN2MzcnI3bm5obGkuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI3MzYxNDcxMzQ3MDItZ2xrYjFwZXN2NzE2ajF1dGc0bGxnN2MzcnI3bm5obGkuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDQwMDQ3NjQ4MjQwNjYzNTkzOTAiLCJlbWFpbCI6Im5mc2F0dGVybHlAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF0X2hhc2giOiJVY29QSlE5d3ZNYTljY2VLdmZHdXVBIiwibmFtZSI6Ik5pY2sgU2F0dGVybHkiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDYuZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1KU2dzbjFpbFhhRS9BQUFBQUFBQUFBSS9BQUFBQUFBQUFMcy9pRFRybjFTdFo1Yy9zOTYtYy9waG90by5qcGciLCJnaXZlbl9uYW1lIjoiTmljayIsImZhbWlseV9uYW1lIjoiU2F0dGVybHkiLCJsb2NhbGUiOiJlbi1HQiIsImlhdCI6MTU1Mzg2MDE0MiwiZXhwIjoxNTUzODYzNzQyfQ.MM14xSL1E1VfHtoSUCqe1L8R6M8xY7tkr0D8PoMhOAGheXehUruGl9R73mI8ciALkqRWZJMWO-v7wgEEik9r5jJh3NbRGT0I4obQMKsKglyAvdYKl5_heB18tkg-p08EKt90CGW7bIHVyZbHPBqW0U1EvN34v2qpDv2OuErHSfJhPAY514i0EltRKhKf4t2PdbfDq6_iSz5cVCbAIzFHj7NRHL42GsYsxWohfF4OckXOQCScJk7upyFPKP2UZ14vkARIn5sagmyLynKvnXLtwwBx5n9zvsKyx63wrGsQDd8TfuN6kWM-eDI796QfW62iZ1-I0XAe_CJdjcpjA7M4Uw"
}
"""
m.get('https://accounts.google.com/.well-known/openid-configuration', text=discovery_doc)
m.post('https://oauth2.googleapis.com/token', text=access_token)
response = self.client.post('/auth/google', data=authorization_grant, content_type='application/json')
self.assertEqual(response.status_code, 200, response.data)
data = json.loads(response.data.decode('utf-8'))
claims = jwt.decode(data['token'], verify=False)
self.assertEqual(claims['name'], 'Nick Satterly', claims)
self.assertEqual(claims['preferred_username'], 'nfsatterly@gmail.com', claims)
self.assertEqual(claims['provider'], 'google', claims)
# self.assertEqual(claims['roles'], [], claims)
self.assertEqual(claims['orgs'], ['gmail.com'], claims)
self.assertEqual(claims['scope'], 'read write', claims)
self.assertEqual(claims['email'], 'nfsatterly@gmail.com', claims)
self.assertEqual(claims.get('email_verified'), None, claims)
self.assertEqual(claims['customers'], ['Google Inc.'], claims)
@requests_mock.mock()
def test_openid_auth0(self, m):
test_config = {
'TESTING': True,
'AUTH_REQUIRED': True,
'CUSTOMER_VIEWS': True,
'OIDC_ISSUER_URL': 'https://dev-66191jdr.eu.auth0.com/'
}
self.app = create_app(test_config)
self.client = self.app.test_client()
with self.app.test_request_context('/'):
self.app.preprocess_request()
self.api_key = ApiKey(
user='admin@alerta.io',
scopes=[Scope.admin, Scope.read, Scope.write],
text='demo-key'
)
self.api_key.create()
self.headers = {
'Authorization': 'Key %s' % self.api_key.key,
'Content-type': 'application/json'
}
# add customer mapping
payload = {
'customer': 'Foo Corp',
'match': 'admin'
}
response = self.client.post('/customer', data=json.dumps(payload),
content_type='application/json', headers=self.headers)
self.assertEqual(response.status_code, 201)
authorization_grant = """
{
"code": "q79ntL3d9mzPFAU-",
"clientId": "LMMEZSlPYKvM14cFxnWNWkC4DgvRk0dZ",
"redirectUri": "http://local.alerta.io:8000",
"state": "051pvr3x5e4y"
}
"""
discovery_doc = """
{
"issuer": "https://dev-66191jdr.eu.auth0.com/",
"authorization_endpoint": "https://dev-66191jdr.eu.auth0.com/authorize",
"token_endpoint": "https://dev-66191jdr.eu.auth0.com/oauth/token",
"userinfo_endpoint": "https://dev-66191jdr.eu.auth0.com/userinfo",
"mfa_challenge_endpoint": "https://dev-66191jdr.eu.auth0.com/mfa/challenge",
"jwks_uri": "https://dev-66191jdr.eu.auth0.com/.well-known/jwks.json",
"registration_endpoint": "https://dev-66191jdr.eu.auth0.com/oidc/register",
"revocation_endpoint": "https://dev-66191jdr.eu.auth0.com/oauth/revoke",
"scopes_supported": [
"openid",
"profile",
"offline_access",
"name",
"given_name",
"family_name",
"nickname",
"email",
"email_verified",
"picture",
"created_at",
"identities",
"phone",
"address"
],
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token"
],
"response_modes_supported": [
"query",
"fragment",
"form_post"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"HS256",
"RS256"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post"
],
"claims_supported": [
"aud",
"auth_time",
"created_at",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"identities",
"iss",
"name",
"nickname",
"phone_number",
"picture",
"sub"
],
"request_uri_parameter_supported": false
}
"""
access_token = """
{
"access_token": "h2JFhciS6loTegmGVvGrap5rXZlO-MLg",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1qZEZOakl4TmpoRk4wWTROMEU0UmtGQ09EVXlRekF5TVVOQlF6a3hRak5GTURJMk1rVXlNQSJ9.eyJuaWNrbmFtZSI6ImFkbWluIiwibmFtZSI6ImFkbWluQGFsZXJ0YS5kZXYiLCJwaWN0dXJlIjoiaHR0cHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvMzA2YTMxOTRmYzZhNzJkZTk1OTE3MWQyMjQyZjMxYTc_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLmF1dGgwLmNvbSUyRmF2YXRhcnMlMkZhZC5wbmciLCJ1cGRhdGVkX2F0IjoiMjAxOS0wMy0zMFQwNjo1ODozNS4yNTZaIiwiZW1haWwiOiJhZG1pbkBhbGVydGEuZGV2IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJpc3MiOiJodHRwczovL2Rldi02NjE5MWpkci5ldS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWM5ZjEwNmQxODUxOGMxMWI3MGNhZTk5IiwiYXVkIjoiTE1NRVpTbFBZS3ZNMTRjRnhuV05Xa0M0RGd2UmswZFoiLCJpYXQiOjE1NTM5Mjk1NzYsImV4cCI6MTU1Mzk2NTU3Nn0.lTiboCdvtzIpFWnX2sOqtAgrY5UDe15HjVaiDUPkZPXGpx837o85IVq6YL0OFu2OOqZI3jD_7G-0GsWJpTW7EsIzNfFmWF2s0mTHf0fz1ab6bwBBANEPnAgbbGf-ZyNJNrVdhqy3cJJjpdyc5_9U2Y8ZCzC9wX0f1Fc-0d7sIFJQfLH-GHzoCtKeI7nqSQus8NCS8cToPcw_V7kkgsSSiG4ZRxwymcxANeXqWKoyT2GrOEIGWZZBznwXDu5l42QNvSFkueQjCF9Q5IB7O0G3lRVwssEBQXE6VRymGQjDnN5Ie-66dPQwX7YEbNbOQXCkQqvy8v52yUmlltMwcjToHQ",
"scope": "openid profile email",
"expires_in": 86400,
"token_type": "Bearer"
}
"""
userinfo = """
{
"sub": "auth0|5c9f106d18518c11b70cae99",
"nickname": "admin",
"name": "admin@alerta.dev",
"picture": "https://s.gravatar.com/avatar/306a3194fc6a72de959171d2242f31a7?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fad.png",
"updated_at": "2019-03-30T06:58:35.256Z",
"email": "admin@alerta.dev",
"email_verified": false
}
"""
m.get('https://dev-66191jdr.eu.auth0.com/.well-known/openid-configuration', text=discovery_doc)
m.post('https://dev-66191jdr.eu.auth0.com/oauth/token', text=access_token)
m.get('https://dev-66191jdr.eu.auth0.com/userinfo', text=userinfo)
response = self.client.post('/auth/openid', data=authorization_grant, content_type='application/json')
self.assertEqual(response.status_code, 200, response.data)
data = json.loads(response.data.decode('utf-8'))
claims = jwt.decode(data['token'], verify=False)
self.assertEqual(claims['name'], 'admin@alerta.dev', claims)
self.assertEqual(claims['preferred_username'], 'admin', claims)
self.assertEqual(claims['provider'], 'openid', claims)
# self.assertEqual(claims['roles'], [], claims)
# self.assertEqual(claims['orgs'], [], claims)
self.assertEqual(claims['scope'], 'read write', claims)
self.assertEqual(claims['email'], 'admin@alerta.dev', claims)
self.assertEqual(claims.get('email_verified'), None, claims)
self.assertEqual(claims['customers'], ['Foo Corp'], claims)
@requests_mock.mock()
def test_openid_okta(self, m):
test_config = {
'TESTING': True,
'AUTH_REQUIRED': True,
'CUSTOMER_VIEWS': True,
'OIDC_ISSUER_URL': 'https://dev-490527.okta.com/oauth2/default'
}
self.app = create_app(test_config)
self.client = self.app.test_client()
with self.app.test_request_context('/'):
self.app.preprocess_request()
self.api_key = ApiKey(
user='admin@alerta.io',
scopes=[Scope.admin, Scope.read, Scope.write],
text='demo-key'
)
self.api_key.create()
self.headers = {
'Authorization': 'Key %s' % self.api_key.key,
'Content-type': 'application/json'
}
# add customer mapping
payload = {
'customer': 'Alerta Dev',
'match': 'nfs@alerta.dev'
}
response = self.client.post('/customer', data=json.dumps(payload),
content_type='application/json', headers=self.headers)
self.assertEqual(response.status_code, 201)
authorization_grant = """
{
"code": "tdjeq4_jMQ0P9K-4Csod",
"clientId": "0oac5s46zwh5crGiH356",
"redirectUri": "http://local.alerta.io:8000",
"state": "p3hmwtujboq"
}
"""
discovery_doc = """
{
"issuer": "https://dev-490527.okta.com/oauth2/default",
"authorization_endpoint": "https://dev-490527.okta.com/oauth2/default/v1/authorize",
"token_endpoint": "https://dev-490527.okta.com/oauth2/default/v1/token",
"userinfo_endpoint": "https://dev-490527.okta.com/oauth2/default/v1/userinfo",
"registration_endpoint": "https://dev-490527.okta.com/oauth2/v1/clients",
"jwks_uri": "https://dev-490527.okta.com/oauth2/default/v1/keys",
"response_types_supported": [
"code",
"id_token",
"code id_token",
"code token",
"id_token token",
"code id_token token"
],
"response_modes_supported": [
"query",
"fragment",
"form_post",
"okta_post_message"
],
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"password"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"profile",
"email",
"address",
"phone",
"offline_access"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"client_secret_jwt",
"private_key_jwt",
"none"
],
"claims_supported": [
"iss",
"ver",
"sub",
"aud",
"iat",
"exp",
"jti",
"auth_time",
"amr",
"idp",
"nonce",
"name",
"nickname",
"preferred_username",
"given_name",
"middle_name",
"family_name",
"email",
"email_verified",
"profile",
"zoneinfo",
"locale",
"address",
"phone_number",
"picture",
"website",
"gender",
"birthdate",
"updated_at",
"at_hash",
"c_hash"
],
"code_challenge_methods_supported": [
"S256"
],
"introspection_endpoint": "https://dev-490527.okta.com/oauth2/default/v1/introspect",
"introspection_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"client_secret_jwt",
"private_key_jwt",
"none"
],
"revocation_endpoint": "https://dev-490527.okta.com/oauth2/default/v1/revoke",
"revocation_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"client_secret_jwt",
"private_key_jwt",
"none"
],
"end_session_endpoint": "https://dev-490527.okta.com/oauth2/default/v1/logout",
"request_parameter_supported": true,
"request_object_signing_alg_values_supported": [
"HS256",
"HS384",
"HS512",
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512"
]
}
"""
access_token = """
{
"access_token": "eyJraWQiOiJLRnZiSVpNamprNkdyNDdTckVLTzhUZ2VlU3N3amxRMzNYN0pDZ2NuZVBrIiwiYWxnIjoiUlMyNTYifQ.eyJ2ZXIiOjEsImp0aSI6IkFULlFVZTdDNW1MTmFnT0xVU3VISXdyZFBXN2lPOHVRREdpTVJpS213ZEFZcTQiLCJpc3MiOiJodHRwczovL2Rldi00OTA1Mjcub2t0YS5jb20vb2F1dGgyL2RlZmF1bHQiLCJhdWQiOiJhcGk6Ly9kZWZhdWx0IiwiaWF0IjoxNTUzOTgyMjgzLCJleHAiOjE1NTM5ODU4ODMsImNpZCI6IjBvYWM1czQ2endoNWNyR2lIMzU2IiwidWlkIjoiMDB1YzVzb3BjZWI4OWg1U2szNTYiLCJzY3AiOlsib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIl0sInN1YiI6Im5mc0BhbGVydGEuZGV2In0.AnQ4r4lXCHRg3kyzFd8uL-5Hgb-9KcAxcjkc32CkJiOogtyp0a3IVHJN6usgl2qTbMxur4R1pMgwn9MlZ4njiflkmADctcrsD5iLtCCzS8AC59XQJsq9xHjAfdRfuaqsWL00Fz2XRyjr3fZmLPzgP7RXXf96Efho9lhefZuSUPaSO46JSdPlTG-_wxTVhaxwLI_b405Dqfv_kS3Ksv5gevbAAHQ8_WRtzNzQoPN_8WR-XO6XHYgC7xKW3yiu01Yn59YRouzIDtQKXNRPMr2CigwbMw2lkikL9eYqLozQ6O7_h2o1pd-X_oJ1QbNyOBjnynIlwS3S9Aws3B-N_KhtSQ",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email",
"id_token": "eyJraWQiOiJLRnZiSVpNamprNkdyNDdTckVLTzhUZ2VlU3N3amxRMzNYN0pDZ2NuZVBrIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMHVjNXNvcGNlYjg5aDVTazM1NiIsIm5hbWUiOiJOaWNrIFNhdHRlcmx5IiwiZW1haWwiOiJuZnNAYWxlcnRhLmRldiIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9kZXYtNDkwNTI3Lm9rdGEuY29tL29hdXRoMi9kZWZhdWx0IiwiYXVkIjoiMG9hYzVzNDZ6d2g1Y3JHaUgzNTYiLCJpYXQiOjE1NTM5ODIyODMsImV4cCI6MTU1Mzk4NTg4MywianRpIjoiSUQuTHhEWGFOV2VibVRUekxmVHMxUXBBa05pem50VldaNDYycTZFMGlWZE9SOCIsImFtciI6WyJwd2QiXSwiaWRwIjoiMDBvYzVzb21nRXJJWHdjRDgzNTYiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZnNAYWxlcnRhLmRldiIsImF1dGhfdGltZSI6MTU1Mzk3MDM5NSwiYXRfaGFzaCI6IjFTbUJKN0s4UkN3dXcxeWJVV1ptdHcifQ.AyWlF4UCBRmdXDJHP6tvu5Z1QjBDzNjXZPKtRtOVdJRhIEMB5rfDMgYh5eBbv5aoK_ZYeHtSNRpXHgof6OldEWZnl8dac-iRiHeFMR65p7YqCpbxzbzYPcDuIbGY_MffGNbH34dDSFruKGg2He8atUwSIczxzMP_5kLgZk2oCMU7S_Uijzf5eosho7AOQ-ybAaWDlxLrxdH8Q0kCfdWcOu0JHFHFlh0-VvCWQVe4uZ6rGdl8_OdaeVdt6xHukEYQTR1QWmmAejEccQ04mgHmgHAjGxNAsXMzOT9mE-FQaDdQkbnap97jYWtIKp78580A5InJedJ3fn_c3brIo2MZYQ"
}
"""
userinfo = """
{
"sub": "00uc5sopceb89h5Sk356",
"name": "Nick Satterly",
"locale": "en-US",
"email": "nfs@alerta.dev",
"preferred_username": "nfs@alerta.dev",
"given_name": "Nick",
"family_name": "Satterly",
"zoneinfo": "America/Los_Angeles",
"updated_at": 1551995091,
"email_verified": true,
"groups": [
"Everyone"
]
}
"""
m.get('https://dev-490527.okta.com/oauth2/default/.well-known/openid-configuration', text=discovery_doc)
m.post('https://dev-490527.okta.com/oauth2/default/v1/token', text=access_token)
m.get('https://dev-490527.okta.com/oauth2/default/v1/userinfo', text=userinfo)
response = self.client.post('/auth/openid', data=authorization_grant, content_type='application/json')
self.assertEqual(response.status_code, 200, response.data)
data = json.loads(response.data.decode('utf-8'))
claims = jwt.decode(data['token'], verify=False)
self.assertEqual(claims['scope'], 'read write', claims)
self.assertEqual(claims['name'], 'Nick Satterly', claims)
self.assertEqual(claims['preferred_username'], 'nfs@alerta.dev', claims)
self.assertEqual(claims['provider'], 'openid', claims)
self.assertEqual(claims['roles'], ['user'], claims)
# self.assertEqual(claims['orgs'], [], claims)
self.assertEqual(claims['scope'], 'read write', claims)
self.assertEqual(claims['email'], 'nfs@alerta.dev', claims)
self.assertEqual(claims.get('email_verified'), None, claims)
self.assertEqual(claims['customers'], ['Alerta Dev'], claims)