|
1 |
import json
|
|
2 |
import datetime
|
|
3 |
import logging
|
|
4 |
import urlparse
|
|
5 |
from urllib import urlencode
|
|
6 |
import pprint
|
|
7 |
import os
|
|
8 |
|
|
9 |
import requests
|
|
10 |
from robobrowser.browser import RoboBrowser
|
|
11 |
|
|
12 |
from hobo.multitenant.middleware import TenantMiddleware
|
|
13 |
from tenant_schemas.utils import tenant_context
|
|
14 |
|
|
15 |
|
|
16 |
def run_on_all_tenants(f):
|
|
17 |
for tenant in TenantMiddleware.get_tenants():
|
|
18 |
with tenant_context(tenant):
|
|
19 |
try:
|
|
20 |
f(tenant)
|
|
21 |
except:
|
|
22 |
logging.exception('unable to provision')
|
|
23 |
|
|
24 |
def provision_users(tenant):
|
|
25 |
from django.conf import settings
|
|
26 |
|
|
27 |
if not getattr(settings, 'OZWILLO_ADMIN', None):
|
|
28 |
logging.warning('No OZWILLO_ADMIN setting found')
|
|
29 |
return
|
|
30 |
|
|
31 |
logger = logging.getLogger('ozwillo_synchro')
|
|
32 |
from authentic2_auth_oidc.models import OIDCProvider
|
|
33 |
for provider in OIDCProvider.objects.all():
|
|
34 |
if 'ozwillo' in provider.issuer:
|
|
35 |
auth_url = provider.authorization_endpoint
|
|
36 |
token_url = provider.token_endpoint
|
|
37 |
client_id = provider.client_id
|
|
38 |
client_secret = provider.client_secret
|
|
39 |
redirect_uri = urlparse.urljoin(tenant.get_base_url(), '/accounts/oidc/callback/')
|
|
40 |
instance_users_url = urlparse.urljoin(token_url.replace('accounts', 'kernel'), '/apps/acl/instance/')
|
|
41 |
break
|
|
42 |
else:
|
|
43 |
logger.warning('No ozwillo OIDC provider found for %s', tenant.get_base_url())
|
|
44 |
return
|
|
45 |
|
|
46 |
session = requests.Session()
|
|
47 |
session.verify = False
|
|
48 |
|
|
49 |
br = RoboBrowser(user_agent='Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0',
|
|
50 |
session=session)
|
|
51 |
|
|
52 |
query = urlencode({
|
|
53 |
'client_id': client_id,
|
|
54 |
'response_type': 'code',
|
|
55 |
'scope': 'openid offline_access',
|
|
56 |
'prompt': 'consent',
|
|
57 |
'redirect_uri': redirect_uri
|
|
58 |
})
|
|
59 |
response = br.open(auth_url + '?%s' % query)
|
|
60 |
response = br._states[-1].response
|
|
61 |
if br._states[-1].response.status_code != 200:
|
|
62 |
logger.warning(u'OIDC authorization request failed: %s %r', response.status_code, response._content[:1000])
|
|
63 |
return
|
|
64 |
referer = br.response.request.url
|
|
65 |
br.session.headers['Referer'] = referer
|
|
66 |
form = br.get_form(action='/a/login')
|
|
67 |
form['u'] = settings.OZWILLO_ADMIN[0]
|
|
68 |
form['pwd'] = settings.OZWILLO_ADMIN[1]
|
|
69 |
br.submit_form(form=form)
|
|
70 |
referer = br.response.request.url
|
|
71 |
br.session.headers['Referer'] = referer
|
|
72 |
form = br.get_form()
|
|
73 |
br.submit_form(form=form, allow_redirects=False)
|
|
74 |
|
|
75 |
cb_url = urlparse.urlparse(br.response.headers['location'])
|
|
76 |
|
|
77 |
code = urlparse.parse_qs(cb_url.query)['code'][0]
|
|
78 |
|
|
79 |
logger.info('Getting token from %s', token_url)
|
|
80 |
response = requests.post(token_url, auth=(client_id, client_secret),
|
|
81 |
data={
|
|
82 |
'code': code,
|
|
83 |
'redirect_uri': redirect_uri,
|
|
84 |
'grant_type': 'authorization_code'})
|
|
85 |
logger.info('Got %s', response.json())
|
|
86 |
access_token = response.json()['access_token']
|
|
87 |
logger.info('Getting instance users from %s', instance_users_url + client_id)
|
|
88 |
response = requests.get(instance_users_url + client_id,
|
|
89 |
headers={'Authorization': 'Bearer %s' % access_token})
|
|
90 |
logger.info('Got %s', response.json())
|
|
91 |
|
|
92 |
from django.contrib.auth import get_user_model
|
|
93 |
from authentic2_auth_oidc.models import OIDCAccount
|
|
94 |
|
|
95 |
User = get_user_model()
|
|
96 |
|
|
97 |
for user in response.json():
|
|
98 |
logging.info('Provisionning email %s with sub %s', user['user_email_address'], user['user_id'])
|
|
99 |
while True:
|
|
100 |
new_user = User.objects.create()
|
|
101 |
oidc_account, created = OIDCAccount.objects.select_related().get_or_create(provider=provider, sub=user['user_id'], defaults={'user': new_user})
|
|
102 |
if created:
|
|
103 |
if OIDCAccount.objects.filter(provider=provider, sub=user['user_id']).count() > 1:
|
|
104 |
oidc_account.delete()
|
|
105 |
new_user.delete()
|
|
106 |
continue
|
|
107 |
logging.info('provisionned with uuid %s', new_user.uuid)
|
|
108 |
break
|
|
109 |
else:
|
|
110 |
new_user.delete()
|
|
111 |
new_user = oidc_account.user
|
|
112 |
break
|
|
113 |
save = False
|
|
114 |
if new_user.username != user['user_name']:
|
|
115 |
new_user.username = user['user_name']
|
|
116 |
save = True
|
|
117 |
if new_user.email != user['user_email_address']:
|
|
118 |
new_user.email = user['user_email_address']
|
|
119 |
save = True
|
|
120 |
if new_user.ou != provider.ou:
|
|
121 |
new_user.ou = provider.ou
|
|
122 |
save = True
|
|
123 |
if save:
|
|
124 |
new_user.save()
|
|
125 |
|
|
126 |
|
|
127 |
run_on_all_tenants(provision_users)
|
0 |
|
-
|