Example #1
0
    def get_session(self):
        try:
            # Get session based on OAuth token
            auth_hdr = request.headers.get("authorization", None)
            if auth_hdr:
                valid, req = self.oauth.verify_request([self.oauth_scope])
                if valid:
                    actor_id = flask.g.oauth_user.get("actor_id", "")
                    actor_user = self.idm_client.read_actor_identity(actor_id)
                    session_attrs = dict(is_logged_in=True, is_registered=True, attributes={"roles":actor_user.details.contact.roles}, roles={})
                    if actor_user.session:
                        session_attrs.update(actor_user.session)

                    return build_json_response(session_attrs)

            # Support quick reload
            access_token = flask.session.get("access_token", None)
            actor_id = flask.session.get("actor_id", None)
            if access_token and actor_id:
                actor_user = self.idm_client.read_actor_identity(actor_id)
                session_attrs = dict(access_token=access_token, is_logged_in=True, is_registered=True, attributes={"roles":actor_user.details.contact.roles}, roles={})
                if actor_user.session:
                    session_attrs.update(actor_user.session)

                return build_json_response(session_attrs)

            # Get session from Flask session and cookie
            user_info = get_auth()
            if 0 < int(user_info.get("valid_until", 0)) * 1000 < current_time_millis():
                clear_auth()
                user_info = get_auth()
            return build_json_response(user_info)
        except Exception:
            return build_json_error()
Example #2
0
    def get_governance_info_from_request(self, json_params=None):
        # Default values for governance headers.
        actor_id = DEFAULT_ACTOR_ID
        expiry = DEFAULT_EXPIRY
        authtoken = ""
        user_session = get_auth()
        if user_session.get("actor_id", None) and user_session.get("valid_until", 0):
            # Get info from current server session
            # NOTE: Actor id may be inside server session
            actor_id = user_session["actor_id"]
            expiry = str(int(user_session.get("valid_until", 0)) * 1000)
            log.info("Request associated with session actor_id=%s, expiry=%s", actor_id, expiry)

        # Developer access using api_key
        if self.develop_mode and "api_key" in request.args and request.args["api_key"]:
            actor_id = str(request.args["api_key"])
            expiry = str(int(user_session.get("valid_until", 0)) * 1000)
            if 0 < int(expiry) < current_time_millis():
                expiry = str(current_time_millis() + 10000)
                # flask.session["valid_until"] = int(expiry / 1000)
            log.info("Request associated with actor_id=%s, expiry=%s from developer api_key", actor_id, expiry)

        # Check in headers for OAuth2 bearer token
        auth_hdr = request.headers.get("authorization", None)
        if auth_hdr:
            valid, req = self.process.oauth.verify_request([self.process.oauth_scope])
            if valid:
                actor_id = flask.g.oauth_user.get("actor_id", "")
                if actor_id:
                    log.info("Request associated with actor_id=%s, expiry=%s from OAuth token", actor_id, expiry)
                    return actor_id, DEFAULT_EXPIRY

        # Try to find auth token override
        if not authtoken:
            if json_params:
                if "authtoken" in json_params:
                    authtoken = json_params["authtoken"]
            else:
                if "authtoken" in request.args:
                    authtoken = str(request.args["authtoken"])

        # Enable temporary authentication tokens to resolve to actor ids
        if authtoken:
            try:
                token_info = self.idm_client.check_authentication_token(authtoken, headers=self._get_gateway_headers())
                actor_id = token_info.get("actor_id", actor_id)
                expiry = token_info.get("expiry", expiry)
                log.info("Resolved token %s into actor_id=%s expiry=%s", authtoken, actor_id, expiry)
            except NotFound:
                log.info("Provided authentication token not found: %s", authtoken)
            except Unauthorized:
                log.info("Authentication token expired or invalid: %s", authtoken)
            except Exception as ex:
                log.exception("Problem resolving authentication token")

        return actor_id, expiry
Example #3
0
    def _get_user_info(self, actor_id, username=None):
        actor_user = self.idm_client.read_identity_details(actor_id)
        if actor_user.type_ != OT.UserIdentityDetails:
            raise BadRequest("Bad identity details")

        full_name = actor_user.contact.individual_names_given + " " + actor_user.contact.individual_name_family

        valid_until = int(get_ion_ts_millis() / 1000 + self.session_timeout)
        set_auth(actor_id, username, full_name, valid_until=valid_until, roles=actor_user.contact.roles)
        user_info = get_auth()
        return user_info
Example #4
0
    def _set_server_session(self, actor_id, username=None):
        """ Sets server session based on user_id and ActorIdentity. """
        actor_user = self.idm_client.read_identity_details(actor_id)
        if actor_user.type_ != OT.UserIdentityDetails:
            raise BadRequest("Bad identity details")

        full_name = actor_user.contact.individual_names_given + " " + actor_user.contact.individual_name_family

        valid_until = int(get_ion_ts_millis() / 1000 + self.session_timeout)
        set_auth(actor_id, username, full_name, valid_until=valid_until, roles=actor_user.contact.roles)
        user_info = get_auth()
        return user_info
Example #5
0
    def validate_request(self, ion_actor_id, expiry, in_whitelist=False):
        # There is no point in looking up an anonymous user - so return default values.
        if ion_actor_id == DEFAULT_ACTOR_ID:
            # Since this is an anonymous request, there really is no expiry associated with it
            if not in_whitelist and self.require_login:
                raise Unauthorized("Anonymous access not permitted")
            else:
                return DEFAULT_ACTOR_ID, DEFAULT_EXPIRY

        try:
            user = self.idm_client.read_actor_identity(
                actor_id=ion_actor_id, headers=self._get_gateway_headers())
        except NotFound as e:
            if not in_whitelist and self.require_login:
                # This could be a restart of the system with a new preload.
                # TODO: Invalidate Flask sessions on relaunch/bootstrap with creating new secret
                user_session = get_auth()
                if user_session.get("actor_id", None) == ion_actor_id:
                    clear_auth()
                raise Unauthorized("Invalid identity", exc_id="01.10")
            else:
                # If the user isn't found default to anonymous
                return DEFAULT_ACTOR_ID, DEFAULT_EXPIRY

        # Need to convert to int first in order to compare against current time.
        try:
            int_expiry = int(expiry)
        except Exception as ex:
            raise Inconsistent(
                "Unable to read the expiry value in the request '%s' as an int"
                % expiry)

        # The user has been validated as being known in the system, so not check the expiry and raise exception if
        # the expiry is not set to 0 and less than the current time.
        if 0 < int_expiry < current_time_millis():
            if not in_whitelist and self.require_login:
                raise Unauthorized("User authentication expired")
            else:
                log.warn("User authentication expired")
                return DEFAULT_ACTOR_ID, DEFAULT_EXPIRY

        return ion_actor_id, expiry
Example #6
0
    def validate_request(self, ion_actor_id, expiry, in_whitelist=False):
        # There is no point in looking up an anonymous user - so return default values.
        if ion_actor_id == DEFAULT_ACTOR_ID:
            # Since this is an anonymous request, there really is no expiry associated with it
            if not in_whitelist and self.require_login:
                raise Unauthorized("Anonymous access not permitted")
            else:
                return DEFAULT_ACTOR_ID, DEFAULT_EXPIRY

        try:
            user = self.idm_client.read_actor_identity(actor_id=ion_actor_id, headers=self._get_gateway_headers())
        except NotFound as e:
            if not in_whitelist and self.require_login:
                # This could be a restart of the system with a new preload.
                # TODO: Invalidate Flask sessions on relaunch/bootstrap with creating new secret
                user_session = get_auth()
                if user_session.get("actor_id", None) == ion_actor_id:
                    clear_auth()
                raise Unauthorized("Invalid identity", exc_id="01.10")
            else:
                # If the user isn't found default to anonymous
                return DEFAULT_ACTOR_ID, DEFAULT_EXPIRY

        # Need to convert to int first in order to compare against current time.
        try:
            int_expiry = int(expiry)
        except Exception as ex:
            raise Inconsistent("Unable to read the expiry value in the request '%s' as an int" % expiry)

        # The user has been validated as being known in the system, so not check the expiry and raise exception if
        # the expiry is not set to 0 and less than the current time.
        if 0 < int_expiry < current_time_millis():
            if not in_whitelist and self.require_login:
                raise Unauthorized("User authentication expired")
            else:
                log.warn("User authentication expired")
                return DEFAULT_ACTOR_ID, DEFAULT_EXPIRY

        return ion_actor_id, expiry
Example #7
0
    def get_session(self):
        """
        Returns user session information for current authentication.
        This can be polled regularly by client code to detect changes in session state and expiration.
        """
        def call_extend_session_attrs(session_attrs, actor_user):
            """ Call UI extensions to make additions to user session """
            for ext_obj in self.extension_objs:
                func = getattr(ext_obj, "extend_user_session_attributes", None)
                if func:
                    try:
                        func(session_attrs, actor_user)
                    except Exception:
                        log.exception("Error calling UI extension extend_user_session_attributes()")

        try:
            # Get user session from OAuth access token in HTTP Authorization header
            auth_hdr = request.headers.get("authorization", None)
            if auth_hdr:
                valid, req = self.oauth.verify_request([self.oauth_scope])  # Note: Do NOT extend session timeout here!
                if valid:
                    actor_id = flask.g.oauth_user.get("actor_id", "")
                    actor_user = self.idm_client.read_actor_identity(actor_id)
                    session_attrs = dict(is_logged_in=True, is_registered=True,
                                         attributes={"roles": actor_user.details.contact.roles}, roles={})
                    if actor_user.session:
                        session_attrs.update(actor_user.session)
                    call_extend_session_attrs(session_attrs, actor_user)

                    return build_json_response(session_attrs)

            if self.remember_user:
                # Get user session from user_id/access_token placed inside server session (Cookie)
                # This is a feature to allow returning users to resume a session if still valid
                access_token = flask.session.get("access_token", None)
                actor_id = flask.session.get("actor_id", None)
                if access_token and actor_id:
                    actor_user = self.idm_client.read_actor_identity(actor_id)
                    session_attrs = dict(access_token=access_token, is_logged_in=True, is_registered=True,
                                         attributes={"roles": actor_user.details.contact.roles}, roles={})
                    if actor_user.session:
                        # Check validity in persisted user session
                        if 0 < int(actor_user.session.get("valid_until", 0)) * 1000 < current_time_millis():
                            clear_auth()
                            return build_json_response(get_auth())
                        session_attrs.update(actor_user.session)
                    else:
                        # No trace of existing session in user object
                        clear_auth()
                        return build_json_response(get_auth())
                    call_extend_session_attrs(session_attrs, actor_user)

                    return build_json_response(session_attrs)

            # Get user session from Flask session and cookie (non-token mode)
            user_info = get_auth()
            if 0 < int(user_info.get("valid_until", 0)) * 1000 < current_time_millis():
                clear_auth()    # Clear expired session
                user_info = get_auth()
            call_extend_session_attrs(user_info, None)
            return build_json_response(user_info)
        except Exception:
            return build_json_error()
Example #8
0
    def get_session(self):
        """
        Returns user session information for current authentication.
        This can be polled regularly by client code to detect changes in session state and expiration.
        """
        def call_extend_session_attrs(session_attrs, actor_user):
            """ Call UI extensions to make additions to user session """
            for ext_obj in self.extension_objs:
                func = getattr(ext_obj, "extend_user_session_attributes", None)
                if func:
                    try:
                        func(session_attrs, actor_user)
                    except Exception:
                        log.exception("Error calling UI extension extend_user_session_attributes()")

        try:
            # Get user session from OAuth access token in HTTP Authorization header
            auth_hdr = request.headers.get("authorization", None)
            if auth_hdr:
                valid, req = self.oauth.verify_request([self.oauth_scope])  # Note: Do NOT extend session timeout here!
                if valid:
                    actor_id = flask.g.oauth_user.get("actor_id", "")
                    actor_user = self.idm_client.read_actor_identity(actor_id)
                    session_attrs = dict(is_logged_in=True, is_registered=True,
                                         attributes={"roles": actor_user.details.contact.roles}, roles={})
                    if actor_user.session:
                        session_attrs.update(actor_user.session)
                    call_extend_session_attrs(session_attrs, actor_user)

                    return build_json_response(session_attrs)

            if self.remember_user:
                # Get user session from user_id/access_token placed inside server session (Cookie)
                # This is a feature to allow returning users to resume a session if still valid
                access_token = flask.session.get("access_token", None)
                actor_id = flask.session.get("actor_id", None)
                if access_token and actor_id:
                    actor_user = self.idm_client.read_actor_identity(actor_id)
                    session_attrs = dict(access_token=access_token, is_logged_in=True, is_registered=True,
                                         attributes={"roles": actor_user.details.contact.roles}, roles={})
                    if actor_user.session:
                        # Check validity in persisted user session
                        if 0 < int(actor_user.session.get("valid_until", 0)) * 1000 < current_time_millis():
                            clear_auth()
                            return build_json_response(get_auth())
                        session_attrs.update(actor_user.session)
                    else:
                        # No trace of existing session in user object
                        clear_auth()
                        return build_json_response(get_auth())
                    call_extend_session_attrs(session_attrs, actor_user)

                    return build_json_response(session_attrs)

            # Get user session from Flask session and cookie (non-token mode)
            user_info = get_auth()
            if 0 < int(user_info.get("valid_until", 0)) * 1000 < current_time_millis():
                clear_auth()    # Clear expired session
                user_info = get_auth()
            call_extend_session_attrs(user_info, None)
            return build_json_response(user_info)
        except Exception:
            return build_json_error()
Example #9
0
    def get_governance_info_from_request(self, json_params=None):
        # Default values for governance headers.
        actor_id = DEFAULT_ACTOR_ID
        expiry = DEFAULT_EXPIRY
        authtoken = ""
        user_session = get_auth()
        #if user_session.get("actor_id", None) and user_session.get("valid_until", 0):
        if user_session.get("actor_id", None):
            # Get info from current server session
            # NOTE: Actor id may be inside server session
            expiry = int(user_session.get("valid_until", 0)) * 1000
            if expiry:
                # This was a proper non-token server session authentication
                expiry = str(expiry)
                actor_id = user_session["actor_id"]
                log.info(
                    "Request associated with session actor_id=%s, expiry=%s",
                    actor_id, expiry)
            else:
                # We are just taking the user_id out of the session
                # TODO: Need to check access token here
                expiry = str(expiry)
                if self.token_from_session:
                    actor_id = user_session["actor_id"]
                    log.info(
                        "Request associated with actor's token from session; actor_id=%s, expiry=%s",
                        actor_id, expiry)

        # Developer access using api_key
        if self.develop_mode and "api_key" in request.args and request.args[
                "api_key"]:
            actor_id = str(request.args["api_key"])
            expiry = str(int(user_session.get("valid_until", 0)) * 1000)
            if 0 < int(expiry) < current_time_millis():
                expiry = str(current_time_millis() + 10000)
                # flask.session["valid_until"] = int(expiry / 1000)
            log.info(
                "Request associated with actor_id=%s, expiry=%s from developer api_key",
                actor_id, expiry)

        # Check in headers for OAuth2 bearer token
        auth_hdr = request.headers.get("authorization", None)
        if auth_hdr:
            valid, req = self.process.oauth.verify_request(
                [self.process.oauth_scope])
            if valid:
                actor_id = flask.g.oauth_user.get("actor_id", "")
                if actor_id:
                    log.info(
                        "Request associated with actor_id=%s, expiry=%s from OAuth token",
                        actor_id, expiry)
                    return actor_id, DEFAULT_EXPIRY

        # Try to find auth token override
        if not authtoken:
            if json_params:
                if "authtoken" in json_params:
                    authtoken = json_params["authtoken"]
            else:
                if "authtoken" in request.args:
                    authtoken = str(request.args["authtoken"])

        # Enable temporary authentication tokens to resolve to actor ids
        if authtoken:
            try:
                token_info = self.idm_client.check_authentication_token(
                    authtoken, headers=self._get_gateway_headers())
                actor_id = token_info.get("actor_id", actor_id)
                expiry = token_info.get("expiry", expiry)
                log.info("Resolved token %s into actor_id=%s expiry=%s",
                         authtoken, actor_id, expiry)
            except NotFound:
                log.info("Provided authentication token not found: %s",
                         authtoken)
            except Unauthorized:
                log.info("Authentication token expired or invalid: %s",
                         authtoken)
            except Exception as ex:
                log.exception("Problem resolving authentication token")

        return actor_id, expiry
Example #10
0
    def get_governance_info_from_request(self, json_params=None):
        # Default values for governance headers.
        actor_id = DEFAULT_ACTOR_ID
        expiry = DEFAULT_EXPIRY
        authtoken = ""
        user_session = get_auth()
        #if user_session.get("actor_id", None) and user_session.get("valid_until", 0):
        if user_session.get("actor_id", None):
            # Get info from current server session
            # NOTE: Actor id may be inside server session
            expiry = int(user_session.get("valid_until", 0)) * 1000
            if expiry:
                # This was a proper non-token server session authentication
                expiry = str(expiry)
                actor_id = user_session["actor_id"]
                log.info("Request associated with session actor_id=%s, expiry=%s", actor_id, expiry)
            else:
                # We are just taking the user_id out of the session
                # TODO: Need to check access token here
                expiry = str(expiry)
                if self.token_from_session:
                    actor_id = user_session["actor_id"]
                    log.info("Request associated with actor's token from session; actor_id=%s, expiry=%s", actor_id, expiry)

        # Developer access using api_key
        if self.develop_mode and "api_key" in request.args and request.args["api_key"]:
            actor_id = str(request.args["api_key"])
            expiry = str(int(user_session.get("valid_until", 0)) * 1000)
            if 0 < int(expiry) < current_time_millis():
                expiry = str(current_time_millis() + 10000)
                # flask.session["valid_until"] = int(expiry / 1000)
            log.info("Request associated with actor_id=%s, expiry=%s from developer api_key", actor_id, expiry)

        # Check in headers for OAuth2 bearer token
        auth_hdr = request.headers.get("authorization", None)
        if auth_hdr:
            valid, req = self.process.oauth.verify_request([self.process.oauth_scope])
            if valid:
                actor_id = flask.g.oauth_user.get("actor_id", "")
                if actor_id:
                    log.info("Request associated with actor_id=%s, expiry=%s from OAuth token", actor_id, expiry)
                    return actor_id, DEFAULT_EXPIRY

        # Try to find auth token override
        if not authtoken:
            if json_params:
                if "authtoken" in json_params:
                    authtoken = json_params["authtoken"]
            else:
                if "authtoken" in request.args:
                    authtoken = str(request.args["authtoken"])

        # Enable temporary authentication tokens to resolve to actor ids
        if authtoken:
            try:
                if authtoken.startswith(("Bearer_")):
                    # Backdoor way for OAuth2 access tokens as request args for GET URLs
                    authtoken = authtoken[7:]
                    token_id = "access_token_" + str(authtoken)
                    token_obj = self.process.container.object_store.read(token_id)
                    token = OAuthTokenObj.from_security_token(token_obj)
                    if token.is_valid(check_expiry=True):
                        actor_id = token.user["actor_id"]
                        expiry = str(token._token_obj.expires)
                        log.info("Resolved OAuth2 token %s into actor_id=%s expiry=%s", authtoken, actor_id, expiry)
                else:
                    token_info = self.idm_client.check_authentication_token(authtoken, headers=self._get_gateway_headers())
                    actor_id = token_info.get("actor_id", actor_id)
                    expiry = token_info.get("expiry", expiry)
                    log.info("Resolved token %s into actor_id=%s expiry=%s", authtoken, actor_id, expiry)
            except NotFound:
                log.info("Provided authentication token not found: %s", authtoken)
            except Unauthorized:
                log.info("Authentication token expired or invalid: %s", authtoken)
            except Exception as ex:
                log.exception("Problem resolving authentication token")

        return actor_id, expiry