1+ # Copyright 2020 StrongDM Inc
2+ #
3+ # Licensed under the Apache License, Version 2.0 (the "License");
4+ # you may not use this file except in compliance with the License.
5+ # You may obtain a copy of the License at
6+ #
7+ # http://www.apache.org/licenses/LICENSE-2.0
8+ #
9+ # Unless required by applicable law or agreed to in writing, software
10+ # distributed under the License is distributed on an "AS IS" BASIS,
11+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ # See the License for the specific language governing permissions and
13+ # limitations under the License.
14+ #
115import yaml
216import os
317import strongdm
620from okta .models .user .User import User
721from okta .models .usergroup .UserGroup import UserGroup
822
23+
924def load_matchers ():
1025 f = open ('matchers.yml' )
11- data = yaml .load (f , Loader = yaml .Loader )
26+ data = yaml .load (f , Loader = yaml .Loader )
1227 return data
1328
29+
1430class OktaUser :
1531 def __init__ (self , login , first_name , last_name , groups ):
1632 self .login = login
1733 self .first_name = first_name
1834 self .last_name = last_name
1935 self .groups = groups
36+
2037 def __repr__ (self ):
21- return "%s %s" % (self .login ,self .groups )
38+ return "%s %s" % (self .login , self .groups )
39+
2240
2341def load_okta_users ():
2442 ret = []
25- apiClient = ApiClient (pathname = '/api/v1/users' , base_url = os .getenv ('OKTA_CLIENT_ORGURL' ), api_token = os .getenv ('OKTA_CLIENT_TOKEN' ))
43+ apiClient = ApiClient (pathname = '/api/v1/users' ,
44+ base_url = os .getenv ('OKTA_CLIENT_ORGURL' ),
45+ api_token = os .getenv ('OKTA_CLIENT_TOKEN' ))
2646 params = {
27- 'search' : "profile.department eq \" Engineering\" and (status eq \" ACTIVE\" )"
47+ 'search' :
48+ "profile.department eq \" Engineering\" and (status eq \" ACTIVE\" )"
2849 }
2950 response = ApiClient .get_path (apiClient , '/' , params = params )
3051 users = Utils .deserialize (response .text , User )
@@ -34,15 +55,18 @@ def load_okta_users():
3455 groups = []
3556 for ug in userGroups :
3657 groups .append (ug .profile .name )
37- oktaUser = OktaUser (u .profile .login , u .profile .firstName , u .profile .lastName , groups )
58+ oktaUser = OktaUser (u .profile .login , u .profile .firstName ,
59+ u .profile .lastName , groups )
3860 ret .append (oktaUser )
3961 return ret
4062
63+
4164def main ():
4265 try :
4366 okta_sync ()
4467 except Exception as ex :
45- print ("okta sync failed:" + str (ex ))
68+ print ("okta sync failed:" + str (ex ))
69+
4670
4771def okta_sync ():
4872 SDM_API_ACCESS_KEY = os .getenv ('SDM_API_ACCESS_KEY' )
@@ -52,23 +76,25 @@ def okta_sync():
5276
5377 if SDM_API_ACCESS_KEY is None or SDM_API_SECRET_KEY is None \
5478 or OKTA_CLIENT_TOKEN is None or OKTA_CLIENT_ORGURL is None :
55- print ("SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY, OKTA_CLIENT_TOKEN, and OKTA_CLIENT_ORGURL must be set" )
79+ print (
80+ "SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY, OKTA_CLIENT_TOKEN, and OKTA_CLIENT_ORGURL must be set"
81+ )
5682 return
5783
5884 matchers = load_matchers ()
5985 okta_users = load_okta_users ()
6086
6187 client = strongdm .Client (SDM_API_ACCESS_KEY , SDM_API_SECRET_KEY )
6288
63- accounts = {o .email :o .id for o in client .accounts .list ("" )}
89+ accounts = {o .email : o .id for o in client .accounts .list ("" )}
6490 permissions = [v for v in client .account_grants .list ("" )]
6591
6692 # define current state
6793 current = {}
6894 for p in permissions :
6995 if p .account_id not in current :
7096 current [p .account_id ] = set ()
71- current [p .account_id ].add ((p .resource_id ,p .id ))
97+ current [p .account_id ].add ((p .resource_id , p .id ))
7298
7399 # define desired state
74100 desired = {}
@@ -80,33 +106,35 @@ def okta_sync():
80106 if group ["name" ] in u .groups :
81107 if u .login not in accounts :
82108 continue
83- overlapping += 1
109+ overlapping += 1
84110 aid = accounts [u .login ]
85111 if aid not in desired :
86112 desired [aid ] = set ()
87113 desired [aid ].add (res .id )
88114
89115 # revoke things
90116 revocations = 0
91- for aid ,curRes in current .items ():
92- desRes = desired .get (aid ,set ())
117+ for aid , curRes in current .items ():
118+ desRes = desired .get (aid , set ())
93119 for rid in curRes :
94120 if rid [0 ] not in desRes :
95- revocations += 1
121+ revocations += 1
96122 client .account_grants .delete (rid [1 ])
97123
98124 # grant things
99125 grants = 0
100- for aid ,desRes in desired .items ():
101- curRes = current .get (aid ,set ())
126+ for aid , desRes in desired .items ():
127+ curRes = current .get (aid , set ())
102128 for rid in desRes :
103129 for cr in curRes :
104130 if rid != cr [0 ]:
105- grants += 1
106- client .account_grants .create (strongdm .AccountGrant (resource_id = rid , account_id = aid ))
131+ grants += 1
132+ client .account_grants .create (
133+ strongdm .AccountGrant (resource_id = rid , account_id = aid ))
107134
108135 print ("{} Okta users, {} strongDM users, {} overlapping users, {} grants, {} revocations" .format (\
109136 len (okta_users ),len (accounts ), overlapping , grants , revocations ))
110137
138+
111139if __name__ == '__main__' :
112140 main ()
0 commit comments