def test_generate_token(self): token = ku.generate_token() matches = re.match('AUTH_tk[a-f0-9]{32}', token) self.assertTrue(matches is not None)
def handle_get_token(self, req): """ Handles the various `request for token and service end point(s)` calls. There are various formats to support the various auth servers in the past. "Active Mode" usage: All formats require GSS (Kerberos) authentication. GET <auth-prefix>/v1/<act>/auth GET <auth-prefix>/auth GET <auth-prefix>/v1.0 On successful authentication, the response will have X-Auth-Token and X-Storage-Token set to the token to use with Swift. "Passive Mode" usage:: GET <auth-prefix>/v1/<act>/auth X-Auth-User: <act>:<usr> or X-Storage-User: <usr> X-Auth-Key: <key> or X-Storage-Pass: <key> GET <auth-prefix>/auth X-Auth-User: <act>:<usr> or X-Storage-User: <act>:<usr> X-Auth-Key: <key> or X-Storage-Pass: <key> GET <auth-prefix>/v1.0 X-Auth-User: <act>:<usr> or X-Storage-User: <act>:<usr> X-Auth-Key: <key> or X-Storage-Pass: <key> Values should be url encoded, "act%3Ausr" instead of "act:usr" for example; however, for backwards compatibility the colon may be included unencoded. On successful authentication, the response will have X-Auth-Token and X-Storage-Token set to the token to use with Swift and X-Storage-URL set to the URL to the default Swift cluster to use. :param req: The swob.Request to process. :returns: swob.Response, 2xx on success with data set as explained above. """ # Validate the request info try: pathsegs = split_path(req.path_info, 1, 3, True) except ValueError: self.logger.increment('errors') return HTTPNotFound(request=req) if not ((pathsegs[0] == 'v1' and pathsegs[2] == 'auth') or pathsegs[0] in ('auth', 'v1.0')): return HTTPBadRequest(request=req) # Client is inside the domain if self.auth_method == "active": return HTTPSeeOther(location=self.ext_authentication_url) # Client is outside the domain elif self.auth_method == "passive": account, user, key = None, None, None # Extract user, account and key from request if pathsegs[0] == 'v1' and pathsegs[2] == 'auth': account = pathsegs[1] user = req.headers.get('x-storage-user') if not user: user = unquote(req.headers.get('x-auth-user', '')) if user: if ':' not in user: return HTTPUnauthorized(request=req) else: account2, user = user.split(':', 1) if account != account2: return HTTPUnauthorized(request=req) key = req.headers.get('x-storage-pass') if not key: key = unquote(req.headers.get('x-auth-key', '')) elif pathsegs[0] in ('auth', 'v1.0'): user = unquote(req.headers.get('x-auth-user', '')) if not user: user = req.headers.get('x-storage-user') if user: if ':' not in user: return HTTPUnauthorized(request=req) else: account, user = user.split(':', 1) key = unquote(req.headers.get('x-auth-key', '')) if not key: key = req.headers.get('x-storage-pass') if not (account or user or key): # If all are not given, client may be part of the domain return HTTPSeeOther(location=self.ext_authentication_url) elif None in (key, user, account): # If only one or two of them is given, but not all return HTTPUnauthorized(request=req) # Run kinit on the user if self.realm_name and "@" not in user: user = user + "@" + self.realm_name try: ret = run_kinit(user, key) except OSError as e: if e.errno == errno.ENOENT: return HTTPServerError("kinit command not found\n") if ret != 0: self.logger.warning("Failed: kinit %s", user) if ret == -1: self.logger.warning("Failed: kinit: Password has probably " "expired.") return HTTPServerError("Kinit is taking too long.\n") return HTTPUnauthorized(request=req) self.logger.debug("kinit succeeded") if "@" in user: user = user.split("@")[0] # Check if user really belongs to the account groups_list = get_groups_from_username(user).strip().split(",") user_group = ("%s%s" % (self.reseller_prefix, account)).lower() reseller_admin_group = \ ("%sreseller_admin" % self.reseller_prefix).lower() if user_group not in groups_list: # Check if user is reseller_admin. If not, return Unauthorized. # On AD/IdM server, auth_reseller_admin is a separate group if reseller_admin_group not in groups_list: return HTTPUnauthorized(request=req) mc = cache_from_env(req.environ) if not mc: raise Exception('Memcache required') token, expires, groups = get_auth_data(mc, user) if not token: token = generate_token() expires = time() + self.token_life groups = get_groups_from_username(user) set_auth_data(mc, user, token, expires, groups) headers = {'X-Auth-Token': token, 'X-Storage-Token': token} if self.debug_headers: headers.update({'X-Debug-Remote-User': user, 'X-Debug-Groups:': groups, 'X-Debug-Token-Life': self.token_life, 'X-Debug-Token-Expires': ctime(expires)}) resp = Response(request=req, headers=headers) resp.headers['X-Storage-Url'] = \ '%s/v1/%s%s' % (resp.host_url, self.reseller_prefix, account) return resp
def handle_get_token(self, req): """ Handles the various `request for token and service end point(s)` calls. There are various formats to support the various auth servers in the past. "Active Mode" usage: All formats require GSS (Kerberos) authentication. GET <auth-prefix>/v1/<act>/auth GET <auth-prefix>/auth GET <auth-prefix>/v1.0 On successful authentication, the response will have X-Auth-Token and X-Storage-Token set to the token to use with Swift. "Passive Mode" usage:: GET <auth-prefix>/v1/<act>/auth X-Auth-User: <act>:<usr> or X-Storage-User: <usr> X-Auth-Key: <key> or X-Storage-Pass: <key> GET <auth-prefix>/auth X-Auth-User: <act>:<usr> or X-Storage-User: <act>:<usr> X-Auth-Key: <key> or X-Storage-Pass: <key> GET <auth-prefix>/v1.0 X-Auth-User: <act>:<usr> or X-Storage-User: <act>:<usr> X-Auth-Key: <key> or X-Storage-Pass: <key> Values should be url encoded, "act%3Ausr" instead of "act:usr" for example; however, for backwards compatibility the colon may be included unencoded. On successful authentication, the response will have X-Auth-Token and X-Storage-Token set to the token to use with Swift and X-Storage-URL set to the URL to the default Swift cluster to use. :param req: The swob.Request to process. :returns: swob.Response, 2xx on success with data set as explained above. """ # Validate the request info try: pathsegs = split_path(req.path_info, 1, 3, True) except ValueError: self.logger.increment('errors') return HTTPNotFound(request=req) if not ((pathsegs[0] == 'v1' and pathsegs[2] == 'auth') or pathsegs[0] in ('auth', 'v1.0')): return HTTPBadRequest(request=req) # Client is inside the domain if self.auth_method == "active": return HTTPSeeOther(location=self.ext_authentication_url) # Client is outside the domain elif self.auth_method == "passive": account, user, key = None, None, None # Extract user, account and key from request if pathsegs[0] == 'v1' and pathsegs[2] == 'auth': account = pathsegs[1] user = req.headers.get('x-storage-user') if not user: user = unquote(req.headers.get('x-auth-user', '')) if user: if ':' not in user: return HTTPUnauthorized(request=req) else: account2, user = user.split(':', 1) if account != account2: return HTTPUnauthorized(request=req) key = req.headers.get('x-storage-pass') if not key: key = unquote(req.headers.get('x-auth-key', '')) elif pathsegs[0] in ('auth', 'v1.0'): user = unquote(req.headers.get('x-auth-user', '')) if not user: user = req.headers.get('x-storage-user') if user: if ':' not in user: return HTTPUnauthorized(request=req) else: account, user = user.split(':', 1) key = unquote(req.headers.get('x-auth-key', '')) if not key: key = req.headers.get('x-storage-pass') if not (account or user or key): # If all are not given, client may be part of the domain return HTTPSeeOther(location=self.ext_authentication_url) elif None in (key, user, account): # If only one or two of them is given, but not all return HTTPUnauthorized(request=req) # Run kinit on the user if self.realm_name and "@" not in user: user = user + "@" + self.realm_name try: ret = run_kinit(user, key) except OSError as e: if e.errno == errno.ENOENT: return HTTPServerError("kinit command not found\n") if ret != 0: self.logger.warning("Failed: kinit %s", user) if ret == -1: self.logger.warning("Failed: kinit: Password has probably " "expired.") return HTTPServerError("Kinit is taking too long.\n") return HTTPUnauthorized(request=req) self.logger.debug("kinit succeeded") if "@" in user: user = user.split("@")[0] # Check if user really belongs to the account groups_list = get_groups_from_username(user).strip().split(",") user_group = ("%s%s" % (self.reseller_prefix, account)).lower() reseller_admin_group = \ ("%sreseller_admin" % self.reseller_prefix).lower() if user_group not in groups_list: # Check if user is reseller_admin. If not, return Unauthorized. # On AD/IdM server, auth_reseller_admin is a separate group if reseller_admin_group not in groups_list: return HTTPUnauthorized(request=req) mc = cache_from_env(req.environ) if not mc: raise Exception('Memcache required') token, expires, groups = get_auth_data(mc, user) if not token: token = generate_token() expires = time() + self.token_life groups = get_groups_from_username(user) set_auth_data(mc, user, token, expires, groups) headers = {'X-Auth-Token': token, 'X-Storage-Token': token} if self.debug_headers: headers.update({ 'X-Debug-Remote-User': user, 'X-Debug-Groups:': groups, 'X-Debug-Token-Life': self.token_life, 'X-Debug-Token-Expires': ctime(expires) }) resp = Response(request=req, headers=headers) resp.headers['X-Storage-Url'] = \ '%s/v1/%s%s' % (resp.host_url, self.reseller_prefix, account) return resp