def __init__(self, cloud_name, auth_token): self.logger = utils.get_logger() self.logger.debug("cloud_name %s", cloud_name) self.logger.debug("auth_token %s", auth_token) self.init_auth(cloud_name, auth_token)
def decorated(*args, **kwds): try: return fn(*args, **kwds) except (AttributeError, KeyError) as exc: logger = utils.get_logger() logger.warn("Raising TukeyAuthException from %s", exc.message) logger.warn(" %s", traceback.format_exc()) raise TukeyAuthException()
def __init__(self, username, fingerprint, gpg_home_dir, gpg_host_pubkey_filename, gpg_passphrase, host_passphrase, host): self.username = username self.gpg_host_pubkey_filename = gpg_host_pubkey_filename self.host_passphrase = host_passphrase self.fingerprint = fingerprint self.gpg_passphrase = gpg_passphrase self.host = host self.gpg = gnupg.GPG(gnupghome=gpg_home_dir) self.logger = utils.get_logger()
def handle_parameters(params): try: ec2path = params["eucarc_path"] except KeyError: ec2path = None mc_class = utils.get_class(params["memcache_client"]["class"]) mc_params = params["memcache_client"]["params"] mc = mc_class(mc_params[0], mc_params[1]) logger = utils.get_logger() logger.debug(mc) logger.debug("doing lambda now ") return lambda cloud, token: KeystoneProxy( cloud, token, mc, eucarc_path=ec2path)
def handler(**kwargs): # extract response content type resp_type = flask.request.accept_mimetypes type_suffix = kwargs.pop('resp_type', None) if type_suffix: suffix_mime = mimetypes.guess_type("res." + type_suffix)[0] if suffix_mime: resp_type = datastructures.MIMEAccept( [(suffix_mime, 1)]) flask.request.resp_type = resp_type flask.request.file_upload = file_upload # update status code if status: flask.request.status_code = status try: if flask.request.headers["user-agent"] in TENANT_CLIENTS: kwargs.pop("tenant_id") except KeyError: kwargs.pop("tenant_id") try: flask.g.auth_token = flask.request.headers['X-Auth-Token'] except Exception: return flask.abort(401) if flask.request.method in ['POST', 'PUT']: kwargs['data'] = flask.request.data try: return func(**kwargs) except nova_exceptions.ClientException as exc: return json.dumps({"error": {"message": exc.message, "code": exc.http_status}}), exc.http_status except Exception as e: # Something happened that we didn't expect at all this will # likely need to be debugged and fixed. Let's make sure that # people can see this error without having to look too hard. error_message = traceback.format_exc() print error_message logger = utils.get_logger() logger.error(error_message)
def token_request(): ''' Intercept a token request and use that to talk to multiple clouds based on values stored in the database. request data format will be: {"auth": {"passwordCredentials": { "password": "******", "username": "******" }}} tukeyPassword is a password shared between the middleware and the portal to prevent anyone from talking to the middleware and impersonating users. method can be shibboleth or openid. identifier is looked up in the tukey auth db which stores users openstack credentials. Those credentials are used to talk to the Keystone service for each cloud. The auth tokens from each keystone request are stored in memcached with one of the tokens used as the key and returned back to Horizon. ''' token_store = TokenStore(memcache.Client(['127.0.0.1:11211'])) logger = utils.get_logger() try: token_id = flask.request.headers["x-auth-token"] token_info = token_store.get(str(token_id)) return json.dumps(token_info["__tukey_internal"]) except KeyError: pass pw_creds = json.loads(flask.request.data)["auth"]["passwordCredentials"] # string equality in Python is probably a side-channel vector if pw_creds["password"] != settings["shared_password"]: return ("Wrong credentials", 401) method, userid = pw_creds["username"].split() user_info_query = ''' select username, password, cloud_name, display_name, auth_url, login_url, instance_keypairs.cloud_id from login join login_enabled on login.id = login_enabled.login_id join login_identifier on login.userid = login_identifier.userid join login_identifier_enabled on login_identifier.id = login_identifier_enabled.login_identifier_id join login_method on login_method.method_id = login_identifier.method_id join cloud on cloud.cloud_id = login.cloud_id left outer join instance_keypairs on instance_keypairs.cloud_id = cloud.cloud_id where login_method.method_name='%(method)s' and LOWER(login_identifier.identifier)=LOWER('%(id)s'); ''' % {"method": method, "id": userid} engine = sqlalchemy.create_engine(settings["auth_db_str"]) with engine.begin() as connection: results = connection.execute(sqlalchemy.text(user_info_query)) roles = [] info_by_cloud = {} tenant = None endpoints = {} for (_username, password, cloud, display_name, auth_url, login_url, instance_keypairs) in results: if auth_url: try: try: ksc = keystone_client(auth_url=auth_url, username=_username, password=password) except keystoneclient.apiclient.exceptions.Unauthorized: # this should be a valid username so let Horizon know logger.info(("Cloud %s Keystone at %s ", "rejected username password: %s %s"), cloud, auth_url, _username, password) # this is probably not the best or clearest, just different flask.abort(403) tenants = [t for t in ksc.tenants.list() if t.enabled] if len(tenants) < 1: logger.info("Cloud %s username: %s has no tenants", cloud, _username) continue for tenant in tenants: if tenant.name == _username: break token_response = ksc.get_raw_token_from_identity_service( auth_url, username=_username, password=password, tenant_name=tenant.name) try: # this should work if keystoneclient version <= 0.6.0 response, raw_token = token_response response_status = response.status_code except ValueError: # this should work if keystoneclient version >= 0.7.0 raw_token = token_response response_status = 200 # handle changes between 0.6.0 and 0.7.0 if "access" not in raw_token: raw_token = {"access": raw_token} if response_status != 200: logger.info(("Cloud %s Keystone at %s ", "rejected username: %s with status code: %s"), cloud, auth_url, _username, response_status) flask.abort(403) # add enpoints for endpoint in raw_token["access"]["serviceCatalog"]: endpoints[endpoint["type"]] = endpoint["name"] token_id = ksc.auth_token user_id = ksc.user_id username = _username raw_token["cloud"] = display_name if instance_keypairs: raw_token["instance_keypairs"] = True info_by_cloud[cloud] = raw_token info_by_cloud["login" + cloud] = login_url roles += raw_token["access"]["user"]["roles"] raw_token["cloud"] = display_name except AuthorizationFailure: logger.info("Keystone failed for %s", cloud) else: info_by_cloud[cloud] = {"username": _username, "cloud": display_name, "instance_keypairs": True if instance_keypairs else False} info_by_cloud["login" + cloud] = login_url if tenant is None: logger.info("Login failed for %s using method %s", userid, method) flask.abort(401) region = "RegionOne" host, port = "localhost", LOCAL_PORT allowed_services = ['compute', 'image', 'volume', 'object-store'] # glance assumes that it is at /v1 so we will give it that #service_paths = {k: K for k in allowed_services} #service_paths["image"] = "v1" services = [("http://%s:%s/%s/%s" % (host, port, service, tenant.id), service, service_name) for service, service_name in endpoints.items() if service in allowed_services] services += [("http://%s:%s/v2.0" % (host, port), "identity", "keystone")] catalog = { "access": { "token": { "expires": expiration(43200), "id": token_id, "tenant": format_tenant(tenant.name, tenant.id) }, "serviceCatalog": [ service_catalog_entry(url, region, url, url, service_type, name) for url, service_type, name in services] + [ service_catalog_entry( "http://%s:%s/services/Admin" % (host, port), region, "http://%s:%s/services/Cloud" % (host, port), "http://%s:%s/services/Cloud" % (host, port), "ec2", "ec2")], "user": { "username": username, "roles_links": [], "id": user_id, "roles": roles, "name": username }}, "path": "", "host": host, "port": port} info_by_cloud["__tukey_internal"] = catalog # TODO: # see what the shortest expiration is in the set of expirations # then set the returned expiration to that and make sure that # the memcache expiration is greater than that but has a value so # that memcached entries don't fill everything up token_store.set(str(token_id), info_by_cloud, 172800) logger.info("Login succeeded for %s using method %s" % (userid, method)) return json.dumps(catalog)
def __init__(self, settings=None): if settings is None: settings = {} self.settings = settings self.logger = utils.get_logger() self.client_format = None
def __init__(self, username, cloud_name, db_connection_string): self.cloud_name = cloud_name self.username = username self.engine = sqlalchemy.create_engine(db_connection_string) self.logger = utils.get_logger()
def test_logger(self): log_file, name = tempfile.mkstemp() logger = utils.get_logger(log_file_name=name) logger.info("test") log_contents = os.read(log_file, 100) assert log_contents == "test\n"
def set_api_manager(blueprint, registry, logger=utils.get_logger()): blueprint.registry = registry blueprint.api_manager = ApiManager(registry, logger) return blueprint