Skip to content

Commit 3bf64a8

Browse files
2 parents 16175e1 + 52fedae commit 3bf64a8

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ The first 2 flows (Local Login/O365 Login) enable users to login in with either
421421

422422
This flow shows how an administrator logs into the system and performs administrative operations.
423423

424-
After logging into the app with an Office 365 account,the administrator will be asked to link to a local account. This step is not required and can be skipped.
424+
After logging into the app with an Office 365 account, the administrator will be asked to link to a local account. This step is not required and can be skipped.
425425

426426
As mentioned earlier, the web app is a multi-tenant app which uses some application permissions, so tenant administrator must consent the app first.
427427

admin/views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def consent_alone(request):
5151

5252
def process_code(request):
5353
AuthService.validate_state(request)
54-
id_token = AuthService.get_id_token(request)
54+
id_token = AuthService.get_id_token(request)
5555
tenant_id = id_token.get('tid')
5656

5757
user_service.update_organization(tenant_id, True)
@@ -72,7 +72,8 @@ def unconsent(request):
7272
aad_graph_service = AADGraphService(user.tenant_id, token)
7373

7474
service_principal = aad_graph_service.get_service_principal()
75-
aad_graph_service.delete_service_principal(service_principal['objectId'])
75+
if service_principal:
76+
aad_graph_service.delete_service_principal(service_principal['objectId'])
7677
user_service.update_organization(user.tenant_id, False)
7778
link_service.remove_links(user.tenant_id)
7879

services/aad_graph_service.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* * See LICENSE in the project root for license information.
44
'''
55

6+
import re
67
import urllib
78
import constant
89
from services.rest_api_service import RestApiService
@@ -12,28 +13,37 @@ class AADGraphService(object):
1213
def __init__(self, tenant_id, access_token):
1314
self.api_base_uri = constant.Resources.AADGraph + '/' + tenant_id + '/'
1415
self.access_token = access_token
16+
self.skip_token_re = re.compile('(?<=skiptoken=).*')
1517
self.rest_api_service = RestApiService()
1618

1719
def get_service_principal(self):
1820
url = self.api_base_uri + "servicePrincipals?api-version=1.6&$filter=appId eq '%s'" % constant.client_id
1921
app_content = self.rest_api_service.get_json(url, self.access_token)
20-
return app_content['value'][0]
22+
return next(iter(app_content['value']), None)
2123

2224
def delete_service_principal(self, service_principal_id):
2325
version = '?api-version=1.6'
2426
url = self.api_base_uri + 'servicePrincipals/%s' % service_principal_id + version
2527
self.rest_api_service.delete(url, self.access_token)
2628

2729
def add_app_role_assignments(self, service_principal_id, service_principal_id_name):
28-
url = self.api_base_uri + 'users?api-version=1.6&$expand=appRoleAssignments'
29-
users_content = self.rest_api_service.get_json(url, self.access_token)
30-
users = users_content['value']
31-
3230
count = 0
33-
for user in users:
34-
if all(a['resourceId'] != service_principal_id for a in user['appRoleAssignments']):
35-
self._add_app_role_assignment(user, service_principal_id, service_principal_id_name)
36-
count = count + 1
31+
url = self.api_base_uri + 'users?api-version=1.6&$expand=appRoleAssignments'
32+
skip_token = None
33+
while True:
34+
url2 = url + '&$skiptoken=' + skip_token if skip_token else url
35+
users_content = self.rest_api_service.get_json(url2, self.access_token)
36+
users = users_content['value']
37+
skip_token = self._get_skip_token(users_content.get('odata.nextLink'))
38+
for user in users:
39+
if all(a['resourceId'] != service_principal_id for a in user['appRoleAssignments']):
40+
try:
41+
self._add_app_role_assignment(user, service_principal_id, service_principal_id_name)
42+
count = count + 1
43+
except:
44+
pass
45+
if skip_token == None:
46+
break;
3747
return count
3848

3949
def _add_app_role_assignment(self, user, service_principal_id, service_principal_id_name):
@@ -47,3 +57,10 @@ def _add_app_role_assignment(self, user, service_principal_id, service_principal
4757
}
4858
post_url = self.api_base_uri + 'users/%s' % user['objectId'] + '/appRoleAssignments?api-version=1.6'
4959
self.rest_api_service.post_json(post_url, self.access_token, data=app_role_assignment)
60+
61+
def _get_skip_token(self, nextlink):
62+
if nextlink:
63+
matches = self.skip_token_re.findall(nextlink)
64+
if matches:
65+
return matches[0]
66+
return None

0 commit comments

Comments
 (0)