blob: 140e0245e76867613dfa54d12bcc013e6d556c9f [file] [log] [blame]
Eduardo Sousa819d34c2018-07-31 01:20:02 +01001# -*- coding: utf-8 -*-
2
Eduardo Sousad795f872019-02-05 16:05:53 +00003# Copyright 2018 Whitestack, LLC
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16#
17# For those usages not covered by the Apache License, Version 2.0 please
18# contact: esousa@whitestack.com or glavado@whitestack.com
19##
20
Eduardo Sousa819d34c2018-07-31 01:20:02 +010021"""
22Authconn implements an Abstract class for the Auth backend connector
23plugins with the definition of the methods to be implemented.
24"""
25
26__author__ = "Eduardo Sousa <esousa@whitestack.com>"
27__date__ = "$27-jul-2018 23:59:59$"
28
29from http import HTTPStatus
30
31
32class AuthException(Exception):
33 """
tiernoc8445362019-06-14 12:07:15 +000034 Authentication error, because token, user password not recognized
Eduardo Sousa819d34c2018-07-31 01:20:02 +010035 """
36 def __init__(self, message, http_code=HTTPStatus.UNAUTHORIZED):
Eduardo Sousa5c01e192019-05-08 02:35:47 +010037 super(AuthException, self).__init__(message)
Eduardo Sousa819d34c2018-07-31 01:20:02 +010038 self.http_code = http_code
Eduardo Sousa819d34c2018-07-31 01:20:02 +010039
40
tiernoc8445362019-06-14 12:07:15 +000041class AuthExceptionUnauthorized(AuthException):
42 """
43 Authentication error, because not having rights to make this operation
44 """
45 pass
46
47
Eduardo Sousa819d34c2018-07-31 01:20:02 +010048class AuthconnException(Exception):
49 """
50 Common and base class Exception for all authconn exceptions.
51 """
52 def __init__(self, message, http_code=HTTPStatus.UNAUTHORIZED):
Eduardo Sousa5c01e192019-05-08 02:35:47 +010053 super(AuthconnException, self).__init__(message)
Eduardo Sousa819d34c2018-07-31 01:20:02 +010054 self.http_code = http_code
55
56
57class AuthconnConnectionException(AuthconnException):
58 """
59 Connectivity error with Auth backend.
60 """
61 def __init__(self, message, http_code=HTTPStatus.BAD_GATEWAY):
Eduardo Sousa5c01e192019-05-08 02:35:47 +010062 super(AuthconnConnectionException, self).__init__(message, http_code)
Eduardo Sousa819d34c2018-07-31 01:20:02 +010063
64
65class AuthconnNotSupportedException(AuthconnException):
66 """
67 The request is not supported by the Auth backend.
68 """
69 def __init__(self, message, http_code=HTTPStatus.NOT_IMPLEMENTED):
Eduardo Sousa5c01e192019-05-08 02:35:47 +010070 super(AuthconnNotSupportedException, self).__init__(message, http_code)
Eduardo Sousa819d34c2018-07-31 01:20:02 +010071
72
73class AuthconnNotImplementedException(AuthconnException):
74 """
75 The method is not implemented by the Auth backend.
76 """
77 def __init__(self, message, http_code=HTTPStatus.NOT_IMPLEMENTED):
Eduardo Sousa5c01e192019-05-08 02:35:47 +010078 super(AuthconnNotImplementedException, self).__init__(message, http_code)
Eduardo Sousa819d34c2018-07-31 01:20:02 +010079
80
81class AuthconnOperationException(AuthconnException):
82 """
83 The operation executed failed.
84 """
85 def __init__(self, message, http_code=HTTPStatus.INTERNAL_SERVER_ERROR):
Eduardo Sousa5c01e192019-05-08 02:35:47 +010086 super(AuthconnOperationException, self).__init__(message, http_code)
Eduardo Sousa819d34c2018-07-31 01:20:02 +010087
88
tiernocf042d32019-06-13 09:06:40 +000089class AuthconnNotFoundException(AuthconnException):
90 """
91 The operation executed failed because element not found.
92 """
93 def __init__(self, message, http_code=HTTPStatus.NOT_FOUND):
94 super().__init__(message, http_code)
95
96
tierno1f029d82019-06-13 22:37:04 +000097class AuthconnConflictException(AuthconnException):
98 """
99 The operation has conflicts.
100 """
101 def __init__(self, message, http_code=HTTPStatus.CONFLICT):
102 super().__init__(message, http_code)
103
104
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100105class Authconn:
106 """
107 Abstract base class for all the Auth backend connector plugins.
108 Each Auth backend connector plugin must be a subclass of
109 Authconn class.
110 """
111 def __init__(self, config):
112 """
113 Constructor of the Authconn class.
114
115 Note: each subclass
116
117 :param config: configuration dictionary containing all the
118 necessary configuration parameters.
119 """
120 self.config = config
121
tierno38dcfeb2019-06-10 16:44:00 +0000122 def authenticate(self, user, password, project=None, token=None):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100123 """
tierno38dcfeb2019-06-10 16:44:00 +0000124 Authenticate a user using username/password or token, plus project
125 :param user: user: name, id or None
126 :param password: password or None
127 :param project: name, id, or None. If None first found project will be used to get an scope token
128 :param token: previous token to obtain authorization
129 :return: the scoped token info or raises an exception. The token is a dictionary with:
130 _id: token string id,
131 username: username,
132 project_id: scoped_token project_id,
133 project_name: scoped_token project_name,
134 expires: epoch time when it expires,
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100135
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100136 """
137 raise AuthconnNotImplementedException("Should have implemented this")
138
tierno38dcfeb2019-06-10 16:44:00 +0000139 # def authenticate_with_token(self, token, project=None):
140 # """
141 # Authenticate a user using a token. Can be used to revalidate the token
142 # or to get a scoped token.
143 #
144 # :param token: a valid token.
145 # :param project: (optional) project for a scoped token.
146 # :return: return a revalidated token, scoped if a project was passed or
147 # the previous token was already scoped.
148 # """
149 # raise AuthconnNotImplementedException("Should have implemented this")
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100150
151 def validate_token(self, token):
152 """
153 Check if the token is valid.
154
155 :param token: token to validate
156 :return: dictionary with information associated with the token. If the
157 token is not valid, returns None.
158 """
159 raise AuthconnNotImplementedException("Should have implemented this")
160
161 def revoke_token(self, token):
162 """
163 Invalidate a token.
164
165 :param token: token to be revoked
166 """
167 raise AuthconnNotImplementedException("Should have implemented this")
168
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100169 def get_user_project_list(self, token):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100170 """
171 Get all the projects associated with a user.
172
173 :param token: valid token
174 :return: list of projects
175 """
176 raise AuthconnNotImplementedException("Should have implemented this")
177
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100178 def get_user_role_list(self, token):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100179 """
180 Get role list for a scoped project.
181
182 :param token: scoped token.
183 :return: returns the list of roles for the user in that project. If
184 the token is unscoped it returns None.
185 """
186 raise AuthconnNotImplementedException("Should have implemented this")
187
188 def create_user(self, user, password):
189 """
190 Create a user.
191
192 :param user: username.
193 :param password: password.
194 :raises AuthconnOperationException: if user creation failed.
195 """
196 raise AuthconnNotImplementedException("Should have implemented this")
197
tiernocf042d32019-06-13 09:06:40 +0000198 def update_user(self, user, new_name=None, new_password=None):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100199 """
tiernocf042d32019-06-13 09:06:40 +0000200 Change the user name and/or password.
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100201
tiernocf042d32019-06-13 09:06:40 +0000202 :param user: username or user_id
203 :param new_name: new name
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100204 :param new_password: new password.
tiernocf042d32019-06-13 09:06:40 +0000205 :raises AuthconnOperationException: if change failed.
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100206 """
207 raise AuthconnNotImplementedException("Should have implemented this")
208
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100209 def delete_user(self, user_id):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100210 """
211 Delete user.
212
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100213 :param user_id: user identifier.
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100214 :raises AuthconnOperationException: if user deletion failed.
215 """
216 raise AuthconnNotImplementedException("Should have implemented this")
217
tiernocf042d32019-06-13 09:06:40 +0000218 def get_user_list(self, filter_q=None):
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100219 """
220 Get user list.
221
tiernocf042d32019-06-13 09:06:40 +0000222 :param filter_q: dictionary to filter user list by name (username is also admited) and/or _id
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100223 :return: returns a list of users.
224 """
225
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100226 def create_role(self, role):
227 """
228 Create a role.
229
230 :param role: role name.
231 :raises AuthconnOperationException: if role creation failed.
232 """
233 raise AuthconnNotImplementedException("Should have implemented this")
234
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100235 def delete_role(self, role_id):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100236 """
237 Delete a role.
238
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100239 :param role_id: role identifier.
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100240 :raises AuthconnOperationException: if user deletion failed.
241 """
242 raise AuthconnNotImplementedException("Should have implemented this")
243
tierno1f029d82019-06-13 22:37:04 +0000244 def get_role_list(self, filter_q=None):
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100245 """
246 Get all the roles.
247
tierno1f029d82019-06-13 22:37:04 +0000248 :param filter_q: dictionary to filter role list by _id and/or name.
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100249 :return: list of roles
250 """
251 raise AuthconnNotImplementedException("Should have implemented this")
252
tierno1f029d82019-06-13 22:37:04 +0000253 def update_role(self, role, new_name):
254 """
255 Change the name of a role
256 :param role: role name or id to be changed
257 :param new_name: new name
258 :return: None
259 """
260 raise AuthconnNotImplementedException("Should have implemented this")
261
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100262 def create_project(self, project):
263 """
264 Create a project.
265
266 :param project: project name.
tierno4015b472019-06-10 13:57:29 +0000267 :return: the internal id of the created project
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100268 :raises AuthconnOperationException: if project creation failed.
269 """
270 raise AuthconnNotImplementedException("Should have implemented this")
271
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100272 def delete_project(self, project_id):
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100273 """
274 Delete a project.
275
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100276 :param project_id: project identifier.
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100277 :raises AuthconnOperationException: if project deletion failed.
278 """
279 raise AuthconnNotImplementedException("Should have implemented this")
280
tierno38dcfeb2019-06-10 16:44:00 +0000281 def get_project_list(self, filter_q=None):
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100282 """
283 Get all the projects.
284
tierno38dcfeb2019-06-10 16:44:00 +0000285 :param filter_q: dictionary to filter project list, by "name" and/or "_id"
Eduardo Sousa5c01e192019-05-08 02:35:47 +0100286 :return: list of projects
287 """
288 raise AuthconnNotImplementedException("Should have implemented this")
289
tierno4015b472019-06-10 13:57:29 +0000290 def update_project(self, project_id, new_name):
291 """
292 Change the name of a project
293 :param project_id: project to be changed
294 :param new_name: new name
295 :return: None
296 """
297 raise AuthconnNotImplementedException("Should have implemented this")
298
Eduardo Sousa819d34c2018-07-31 01:20:02 +0100299 def assign_role_to_user(self, user, project, role):
300 """
301 Assigning a role to a user in a project.
302
303 :param user: username.
304 :param project: project name.
305 :param role: role name.
306 :raises AuthconnOperationException: if role assignment failed.
307 """
308 raise AuthconnNotImplementedException("Should have implemented this")
309
310 def remove_role_from_user(self, user, project, role):
311 """
312 Remove a role from a user in a project.
313
314 :param user: username.
315 :param project: project name.
316 :param role: role name.
317 :raises AuthconnOperationException: if role assignment revocation failed.
318 """
319 raise AuthconnNotImplementedException("Should have implemented this")