66 :license: MIT, see LICENSE for more details.
77"""
88import datetime
9+ import logging
910from operator import itemgetter
1011
1112from SoftLayer import exceptions
1213from SoftLayer import utils
1314
14- from pprint import pprint as pp
15+ LOGGER = logging .getLogger (__name__ )
16+
1517
1618class UserManager (utils .IdentifierMixin , object ):
1719 """Manages Users.
@@ -34,6 +36,7 @@ def __init__(self, client):
3436 self .user_service = self .client ['SoftLayer_User_Customer' ]
3537 self .account_service = self .client ['SoftLayer_Account' ]
3638 self .resolvers = [self ._get_id_from_username ]
39+ self .all_permissions = None
3740
3841 def list_users (self , objectmask = None , objectfilter = None ):
3942 """Lists all users on an account
@@ -66,10 +69,13 @@ def get_user(self, user_id, objectmask=None):
6669 def get_all_permissions (self ):
6770 """Calls SoftLayer_User_CustomerPermissions_Permission::getAllObjects
6871
72+ Stores the result in self.all_permissions
6973 :returns: A list of dictionaries that contains all valid permissions
7074 """
71- permissions = self .client .call ('User_Customer_CustomerPermission_Permission' , 'getAllObjects' )
72- return sorted (permissions , key = itemgetter ('keyName' ))
75+ if self .all_permissions is None :
76+ permissions = self .client .call ('User_Customer_CustomerPermission_Permission' , 'getAllObjects' )
77+ self .all_permissions = sorted (permissions , key = itemgetter ('keyName' ))
78+ return self .all_permissions
7379
7480 def add_permissions (self , user_id , permissions ):
7581 """Enables a list of permissions for a user
@@ -82,6 +88,7 @@ def add_permissions(self, user_id, permissions):
8288 add_permissions(123, ['BANDWIDTH_MANAGE'])
8389 """
8490 pretty_permissions = self .format_permission_object (permissions )
91+ LOGGER .warning ("Adding the following permissions to %s: %s" , user_id , pretty_permissions )
8592 return self .user_service .addBulkPortalPermission (pretty_permissions , id = user_id )
8693
8794 def remove_permissions (self , user_id , permissions ):
@@ -95,8 +102,32 @@ def remove_permissions(self, user_id, permissions):
95102 remove_permissions(123, ['BANDWIDTH_MANAGE'])
96103 """
97104 pretty_permissions = self .format_permission_object (permissions )
105+ LOGGER .warning ("Removing the following permissions to %s: %s" , user_id , pretty_permissions )
98106 return self .user_service .removeBulkPortalPermission (pretty_permissions , id = user_id )
99107
108+ def permissions_from_user (self , user_id , from_user_id ):
109+ """Sets user_id's permission to be the same as from_user_id's
110+
111+ Any permissions from_user_id has will be added to user_id.
112+ Any permissions from_user_id doesn't have will be removed from user_id.
113+
114+ :param int user_id: The user to change permissions.
115+ :param int from_user_id: The use to base permissions from.
116+ :returns: True on success, Exception otherwise.
117+ """
118+ from_permissions = self .get_user_permissions (from_user_id )
119+ self .add_permissions (user_id , from_permissions )
120+ all_permissions = self .get_all_permissions ()
121+ remove_permissions = []
122+ for permission in all_permissions :
123+ # If permission does not exist for from_user_id add it to the list to be removed
124+ if _keyname_search (all_permissions , permission ):
125+ continue
126+ else :
127+ remove_permissions .append ({'keyName' : permission ['keyName' ]})
128+ self .remove_permissions (user_id , remove_permissions )
129+ return True
130+
100131 def get_user_permissions (self , user_id ):
101132 """Returns a sorted list of a users permissions"""
102133 permissions = self .user_service .getPermissions (id = user_id )
@@ -131,13 +162,14 @@ def get_events(self, user_id, start_date=None):
131162 """Gets the event log for a specific user, default start_date is 30 days ago
132163
133164 :param int id: User id to view
134- :param string start_date: "%Y-%m-%dT%H:%M:%s.0000-06:00" formatted string. Anything else wont work
165+ :param string start_date: "%Y-%m-%dT%H:%M:%s.0000-06:00" is the full formatted string.
166+ The Timezone part has to be HH:MM, notice the : there.
135167 :returns: https://softlayer.github.io/reference/datatypes/SoftLayer_Event_Log/
136168 """
137169
138170 if start_date is None :
139171 date_object = datetime .date .today () - datetime .timedelta (days = 30 )
140- start_date = date_object .strftime ("%Y-%m-%dT00:00:00.0000-06:00 " )
172+ start_date = date_object .strftime ("%Y-%m-%dT00:00:00" )
141173
142174 object_filter = {
143175 'userId' : {
@@ -149,7 +181,10 @@ def get_events(self, user_id, start_date=None):
149181 }
150182 }
151183
152- return self .client .call ('Event_Log' , 'getAllObjects' , filter = object_filter )
184+ events = self .client .call ('Event_Log' , 'getAllObjects' , filter = object_filter )
185+ if events is None :
186+ events = [{'eventName' : 'No Events Found' }]
187+ return events
153188
154189 def _get_id_from_username (self , username ):
155190 """Looks up a username's id
@@ -162,24 +197,39 @@ def _get_id_from_username(self, username):
162197 user = self .list_users (_mask , _filter )
163198 if len (user ) == 1 :
164199 return [user [0 ]['id' ]]
200+ elif len (user ) > 1 :
201+ raise exceptions .SoftLayerError ("Multiple users found with the name: %s" % username )
165202 else :
166- # Might eventually want to throw an exception if len(user) > 1
167203 raise exceptions .SoftLayerError ("Unable to find user id for %s" % username )
168204
169-
170205 def format_permission_object (self , permissions ):
171- """Formats a list of permission key names into something the SLAPI will respect"""
206+ """Formats a list of permission key names into something the SLAPI will respect.
207+
208+ :param list permissions: A list of SLAPI permissions keyNames.
209+ keyName of ALL will return all permissions.
210+ :returns: list of dictionaries that can be sent to the api to add or remove permissions
211+ :throws SoftLayerError: If any permission is invalid this exception will be thrown.
212+ """
172213 pretty_permissions = []
173214 available_permissions = self .get_all_permissions ()
174215 # pp(available_permissions)
175216 for permission in permissions :
217+ # Handle data retrieved directly from the API
218+ if isinstance (permission , dict ):
219+ permission = permission ['keyName' ]
176220 permission = permission .upper ()
177221 if permission == 'ALL' :
178222 return available_permissions
179223 # Search through available_permissions to make sure what the user entered was valid
180- if next ( filter ( lambda x : x [ 'keyName' ] == permission , available_permissions ), False ):
224+ if _keyname_search ( available_permissions , permission ):
181225 pretty_permissions .append ({'keyName' : permission })
182226 else :
183- raise exceptions .SoftLayerError ("%s is not a valid permission" % permission )
184- pp (pretty_permissions )
227+ raise exceptions .SoftLayerError ("|%s| is not a valid permission" % permission )
185228 return pretty_permissions
229+
230+
231+ def _keyname_search (haystack , needle ):
232+ for item in haystack :
233+ if item .get ('keyName' ) == needle :
234+ return True
235+ return False
0 commit comments