|
2 | 2 |
|
3 | 3 | import pyrfc3339 |
4 | 4 |
|
5 | | -from . import tag |
| 5 | +from . import tag, errors |
| 6 | +from .client import client |
6 | 7 |
|
7 | 8 | log = logging.getLogger(__name__) |
8 | 9 |
|
@@ -31,6 +32,7 @@ def last_connection(self): |
31 | 32 |
|
32 | 33 | @property |
33 | 34 | def access(self): |
| 35 | + """Identifies the controller access levels of this user""" |
34 | 36 | return self._user_info.access |
35 | 37 |
|
36 | 38 | @property |
@@ -59,19 +61,108 @@ async def set_password(self, password): |
59 | 61 | await self.controller.change_user_password(self.username, password) |
60 | 62 | self._user_info.password = password |
61 | 63 |
|
62 | | - async def grant(self, acl='login'): |
63 | | - """Set access level of this user on the controller. |
| 64 | + async def modify_model_access(self, acl, action, model_name): |
| 65 | + """Grants or revokes the given access level for this user for a given model |
64 | 66 |
|
65 | | - :param str acl: Access control ('login', 'add-model', or 'superuser') |
| 67 | + :param str acl: Model access levels (see access module) |
| 68 | + :param str action: grant/revoke |
| 69 | + :param str model_name: Name of the model |
| 70 | +
|
| 71 | + :return bool: True if access changed, Error if user already has it |
| 72 | + """ |
| 73 | + modelmanager_facade = client.ModelManagerFacade.from_connection( |
| 74 | + self.controller.connection()) |
| 75 | + models = await self.controller.model_uuids() |
| 76 | + if model_name not in models: |
| 77 | + raise errors.JujuError(f'Unable to find model : {model_name}') |
| 78 | + changes = client.ModifyModelAccess(acl, action, tag.model(models[model_name]), self.tag) |
| 79 | + await modelmanager_facade.ModifyModelAccess(changes=[changes]) |
| 80 | + return True |
| 81 | + |
| 82 | + async def modify_controller_access(self, acl, action): |
| 83 | + """Grants or revokes the given access level for this user on the current controller |
| 84 | +
|
| 85 | + :param str acl: Controller access levels (see access module) |
| 86 | + :param str action: grant/revoke |
| 87 | +
|
| 88 | + :return bool: True if access changed, Error if user already has it |
| 89 | + """ |
| 90 | + controller_facade = client.ControllerFacade.from_connection(self.controller.connection()) |
| 91 | + changes = client.ModifyControllerAccess(acl, action, self.tag) |
| 92 | + await controller_facade.ModifyControllerAccess(changes=[changes]) |
| 93 | + |
| 94 | + new_access = acl |
| 95 | + if action == 'revoke': |
| 96 | + new_access = '' |
| 97 | + self._user_info.access = new_access |
| 98 | + return True |
| 99 | + |
| 100 | + async def modify_offer_access(self, acl, action, offer_url): |
| 101 | + """Grants or revokes the given access level for this user on a given offer |
| 102 | +
|
| 103 | + :param str acl: Controller access levels (see access module) |
| 104 | + :param str action: grant/revoke |
| 105 | + :param str offer_url: url for the offer |
| 106 | +
|
| 107 | + :return bool: True if access changed, Error if user already has it |
66 | 108 | """ |
67 | | - if await self.controller.grant(self.username, acl): |
68 | | - self._user_info.access = acl |
| 109 | + application_offers_facade = client.ApplicationOffersFacade.from_connection( |
| 110 | + self.controller.connection()) |
| 111 | + changes = client.ModifyOfferAccess(acl, action, offer_url, self.tag) |
| 112 | + await application_offers_facade.ModifyOfferAccess(changes=[changes]) |
| 113 | + return True |
| 114 | + |
| 115 | + async def grant_or_revoke(self, acl, action, **kwargs): |
| 116 | + """Grants or revokes the given access level of this user on model, offer or controller, |
| 117 | + depending on the access level (see the access module) |
| 118 | +
|
| 119 | + :param str acl: Access control level |
| 120 | + :param str action: 'grant' or 'revoke' |
| 121 | +
|
| 122 | + Depending on the access level, the available keyword parameters are: |
| 123 | + :param str model_name: name of the model if acl is one of model access levels |
| 124 | + :param str offer_url: url for the offer if acl is one of offer access levels |
| 125 | +
|
| 126 | + :return: True if access changed, False if user already has it |
| 127 | + """ |
| 128 | + try: |
| 129 | + if 'model_name' in kwargs: |
| 130 | + return await self.modify_model_access(acl, action, kwargs['model_name']) |
| 131 | + elif 'offer_url' in kwargs: |
| 132 | + return await self.modify_offer_access(acl, action, kwargs['offer_url']) |
| 133 | + else: |
| 134 | + return await self.modify_controller_access(acl, action) |
| 135 | + except errors.JujuError as e: |
| 136 | + if 'user already has' in str(e): |
| 137 | + return False |
| 138 | + else: |
| 139 | + raise |
| 140 | + |
| 141 | + async def grant(self, acl, **kwargs): |
| 142 | + """Grant the given access level of this user on model, offer or controller, depending on |
| 143 | + the access level (see the access module) |
| 144 | +
|
| 145 | + :param str acl: Access control level |
| 146 | +
|
| 147 | + Depending on the access level, the available keyword parameters are: |
| 148 | + :param str model_name: name of the model if acl is one of model access levels |
| 149 | + :param str offer_url: url for the offer if acl is one of offer access levels |
| 150 | +
|
| 151 | + :return: None or Error |
| 152 | + """ |
| 153 | + return await self.grant_or_revoke(acl, 'grant', **kwargs) |
| 154 | + |
| 155 | + async def revoke(self, acl='login', **kwargs): |
| 156 | + """The opposite of user.grant(). Revokes the given access level of this user on model, |
| 157 | + offer or controller, depending on the given access level. |
| 158 | +
|
| 159 | + :param str acl: Access control level (see access module) |
69 | 160 |
|
70 | | - async def revoke(self, acl='login'): |
71 | | - """Removes all access rights for this user from the controller. |
| 161 | + Available keyword parameters are: |
| 162 | + :param str model_name: name of the model if acl is one of model access levels |
| 163 | + :param str offer_url: url for the offer if acl is one of offer access levels |
72 | 164 | """ |
73 | | - await self.controller.revoke(self.username, acl) |
74 | | - self._user_info.access = '' |
| 165 | + return await self.grant_or_revoke(acl, 'revoke', **kwargs) |
75 | 166 |
|
76 | 167 | async def disable(self): |
77 | 168 | """Disable this user. |
|
0 commit comments