Пример #1
0
def authenticate(rendered_tpl):

    try:
        auth_type = config_get('webui', 'auth_type')

    except:
        auth_type = 'x509'

    session_token = cookies().get('x-rucio-auth-token')
    validate_token = authentication.validate_auth_token(session_token)

    render = template.render(join(dirname(__file__), '../templates'))

    if auth_type == 'x509':
        return check_token(rendered_tpl)

    elif auth_type == 'userpass':
        if validate_token:
            return log_in(None, rendered_tpl)

        return seeother('/login')

    elif auth_type == 'x509_userpass':
        if ctx.env.get('SSL_CLIENT_VERIFY') == 'SUCCESS':
            return check_token(rendered_tpl)

        elif validate_token:
            return log_in(None, rendered_tpl)

        return render.no_certificate()

    return render.problem('Invalid auth type')
Пример #2
0
def before_request():
    if request.environ.get('REQUEST_METHOD') == 'OPTIONS':
        return '', 200

    auth_token = request.environ.get('HTTP_X_RUCIO_AUTH_TOKEN')

    try:
        auth = validate_auth_token(auth_token)
    except RucioException as error:
        return generate_http_error_flask(500, error.__class__.__name__,
                                         error.args[0])
    except Exception as error:
        print(format_exc())
        return error, 500

    if auth is None:
        return generate_http_error_flask(
            401, 'CannotAuthenticate',
            'Cannot authenticate with given credentials')

    request.environ['vo'] = auth.get('vo', 'def')
    request.environ['issuer'] = auth.get('account')
    request.environ['identity'] = auth.get('identity')
    request.environ['request_id'] = generate_uuid()
    request.environ['start_time'] = time()
Пример #3
0
    def GET(self):
        """
        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized

        :param Rucio-Auth-Token: as a variable-length string.
        :returns: Tuple(account name, token lifetime).
        """

        header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
        header('Access-Control-Allow-Headers',
               ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        header('Access-Control-Allow-Methods', '*')
        header('Access-Control-Allow-Credentials', 'true')
        header('Access-Control-Expose-Headers', 'X-Rucio-Auth-Token')

        header('Content-Type', 'application/octet-stream')
        header('Cache-Control',
               'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')

        token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')

        result = validate_auth_token(token)
        if not result:
            raise generate_http_error(
                401, 'CannotAuthenticate',
                'Cannot authenticate to account %(account)s with given credentials'
                % locals())

        return result
Пример #4
0
    def get(self):
        """
        Validate a Rucio Auth Token.

        .. :quickref: Validate; Validate a Rucio Auth Token.

        :reqheader Rucio-Auth-Token: as a variable-length string.
        :status 406: Not Acceptable.
        :returns: Tuple(account name, token lifetime).
        """

        headers = self.get_headers()

        headers['Content-Type'] = 'application/octet-stream'
        headers[
            'Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
        headers.add('Cache-Control', 'post-check=0, pre-check=0')
        headers['Pragma'] = 'no-cache'

        token = request.headers.get('X-Rucio-Auth-Token', default=None)

        result = validate_auth_token(token)
        if not result:
            return generate_http_error_flask(
                status_code=401,
                exc=CannotAuthenticate.__name__,
                exc_msg='Cannot authenticate with given credentials',
                headers=headers)

        return str(result), 200, headers
Пример #5
0
    def get(self):
        """
        Validate a Rucio Auth Token.

        .. :quickref: Validate; Validate a Rucio Auth Token.

        :reqheader Rucio-Auth-Token: as a variable-length string.
        :status 406: Not Acceptable.
        :returns: Tuple(account name, token lifetime).
        """

        headers = Headers()
        headers['Access-Control-Allow-Origin'] = request.environ.get('HTTP_ORIGIN')
        headers['Access-Control-Allow-Headers'] = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
        headers['Access-Control-Allow-Methods'] = '*'
        headers['Access-Control-Allow-Credentials'] = 'true'
        headers['Access-Control-Expose-Headers'] = 'X-Rucio-Auth-Token'

        headers['Content-Type'] = 'application/octet-stream'
        headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
        headers.add('Cache-Control', 'post-check=0, pre-check=0')
        headers['Pragma'] = 'no-cache'

        token = request.headers.get('X-Rucio-Auth-Token', default=None)

        result = validate_auth_token(token)
        if not result:
            return generate_http_error_flask(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals(), headers=headers)

        return str(result), 200, headers
Пример #6
0
def rucio_loadhook():
    """ Rucio load Hook to authenticate, timing, etc. """

    # Allow cross-site scripting
    header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
    header('Access-Control-Allow-Headers',
           ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
    header('Access-Control-Allow-Methods', '*')
    header('Access-Control-Allow-Credentials', 'true')

    if ctx.env.get('REQUEST_METHOD') == 'OPTIONS':
        raise OK

    if ctx.env.get('REQUEST_METHOD') == 'GET':
        header('Cache-Control',
               'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')
    else:
        header('Content-Type', 'application/octet-stream')

    auth_token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')
    try:
        auth = validate_auth_token(auth_token)
    except RucioException, e:
        raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Пример #7
0
def request_auth_env():
    if flask.request.environ.get('REQUEST_METHOD') == 'OPTIONS':
        return '', 200

    auth_token = flask.request.headers.get('X-Rucio-Auth-Token', default=None)

    try:
        auth = validate_auth_token(auth_token)
    except RucioException as error:
        return generate_http_error_flask(500, error.__class__.__name__,
                                         error.args[0])
    except Exception:
        logging.exception('Internal error in validate_auth_token')
        return 'Internal Error', 500

    if auth is None:
        return generate_http_error_flask(
            401, CannotAuthenticate.__name__,
            'Cannot authenticate with given credentials')

    flask.request.environ['vo'] = auth.get('vo', 'def')
    flask.request.environ['issuer'] = auth.get('account')
    flask.request.environ['identity'] = auth.get('identity')
    flask.request.environ['request_id'] = generate_uuid()
    flask.request.environ['start_time'] = time()
Пример #8
0
    def GET(self):
        """
        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized

        :param Rucio-Auth-Token: as a variable-length string.
        :returns: Tuple(account name, token lifetime).
        """

        header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
        header('Access-Control-Allow-Headers', ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        header('Access-Control-Allow-Methods', '*')
        header('Access-Control-Allow-Credentials', 'true')
        header('Access-Control-Expose-Headers', 'X-Rucio-Auth-Token')

        header('Content-Type', 'application/octet-stream')
        header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')

        token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')

        result = validate_auth_token(token)
        if not result:
            raise generate_http_error(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals())

        return result
Пример #9
0
def rucio_loadhook():
    """ Rucio load Hook to authenticate, timing, etc. """

    # Allow cross-site scripting
    header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
    header('Access-Control-Allow-Headers',
           ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
    header('Access-Control-Allow-Methods', '*')
    header('Access-Control-Allow-Credentials', 'true')

    if ctx.env.get('REQUEST_METHOD') == 'OPTIONS':
        raise OK

    if ctx.env.get('REQUEST_METHOD') == 'GET':
        header('Cache-Control',
               'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')
    else:
        header('Content-Type', 'application/octet-stream')

    auth_token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')
    try:
        auth = validate_auth_token(auth_token)
    except RucioException, e:
        raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
Пример #10
0
    def get(self):
        """
        Validate a Rucio Auth Token.

        .. :quickref: Validate; Validate a Rucio Auth Token.

        :reqheader Rucio-Auth-Token: as a variable-length string.
        :returns: Tuple(account name, token lifetime).
        """

        response = Response()
        response.headers['Access-Control-Allow-Origin'] = request.environ.get('HTTP_ORIGIN')
        response.headers['Access-Control-Allow-Headers'] = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
        response.headers['Access-Control-Allow-Methods'] = '*'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        response.headers['Access-Control-Expose-Headers'] = 'X-Rucio-Auth-Token'

        response.headers['Content-Type'] = 'application/octet-stream'
        response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
        response.headers['Cache-Control'] = 'post-check=0, pre-check=0'
        response.headers['Pragma'] = 'no-cache'

        token = request.environ.get('HTTP_X_RUCIO_AUTH_TOKEN')

        result = validate_auth_token(token)
        if not result:
            return generate_http_error_flask(401, 'CannotAuthenticate', 'Cannot authenticate to account %(account)s with given credentials' % locals())

        response.set_data(result)
        return response
Пример #11
0
def authenticate(rendered_tpl):
    """ Select the auth type defined in config """

    session_token = cookies().get('x-rucio-auth-token')
    validate_token = authentication.validate_auth_token(session_token)

    render = template.render(join(dirname(__file__), '../templates'))

    if AUTH_TYPE == 'x509':
        return check_token(rendered_tpl)

    elif AUTH_TYPE == 'userpass':
        if validate_token:
            return log_in(None, rendered_tpl)

        return seeother('/login')

    elif AUTH_TYPE == 'x509_userpass':
        if ctx.env.get('SSL_CLIENT_VERIFY') == 'SUCCESS':
            return check_token(rendered_tpl)

        elif validate_token:
            return log_in(None, rendered_tpl)

        return render.no_certificate()

    elif AUTH_TYPE == 'saml':
        return saml_authentication("GET", rendered_tpl)

    return render.problem('Invalid auth type')
Пример #12
0
def before_request():
    if request.environ.get('REQUEST_METHOD') == 'OPTIONS':
        raise "", 200

    auth_token = request.environ.get('HTTP_X_RUCIO_AUTH_TOKEN')

    try:
        auth = validate_auth_token(auth_token)
    except RucioException, e:
        return generate_http_error_flask(500, e.__class__.__name__, e.args[0][0])
Пример #13
0
def check_token(rendered_tpl):
    token = None
    js_token = ""
    js_account = ""
    def_account = None
    accounts = None
    cookie_accounts = None
    rucio_ui_version = version.version_string()

    render = template.render(join(dirname(__file__), '../templates'))
    if ctx.env.get('SSL_CLIENT_VERIFY') != 'SUCCESS':
        return render.problem("No certificate provided. Please authenticate with a cerficate registered in Rucio.")

    dn = ctx.env.get('SSL_CLIENT_S_DN')

    # try to get and check the rucio session token from cookie
    session_token = cookies().get('x-rucio-auth-token')
    validate_token = authentication.validate_auth_token(session_token)

    # if there is no session token or if invalid: get a new one.
    if validate_token is None:
        # get all accounts for an identity. Needed for account switcher in UI.
        accounts = identity.list_accounts_for_identity(dn, 'x509')
        cookie_accounts = accounts
        try:
            try:
                # try to get the default account for the identity.
                def_account = identity.get_default_account(dn, 'x509')
            except IdentityError:
                # if there is no default account used the first from the list off accounts.
                def_account = accounts[0]

            token = authentication.get_auth_token_x509(def_account,
                                                       dn,
                                                       'webui',
                                                       ctx.env.get('REMOTE_ADDR'))
        except:
            return render.problem("Your certificate (%s) is not registered in Rucio. Please contact <a href=\"mailto:[email protected]\">Rucio Support</a>" % dn)

        # write the token and account to javascript variables, that will be used in the HTML templates.
        js_token = __to_js('token', token)
        js_account = __to_js('account', def_account)

    # if there was no valid session token write the new token to a cookie.
    if token:
        setcookie('x-rucio-auth-token', value=token, expires=3600, path='/')

    if cookie_accounts:
        values = ""
        for acc in cookie_accounts:
            values += acc + " "
        setcookie('rucio-available-accounts', value=values[:-1], path='/')

    return render.base(js_token, js_account, rucio_ui_version, rendered_tpl)
Пример #14
0
def validate_webui_token(from_cookie=True, session_token=None):
    """
    Validates token and returns token validation dictionary.
    :param from_cookie: Token is looked up in cookies if True, otherwise session_token must be provided
    :param session_token:  token string
    :returns: None or token validation dictionary
    """
    if from_cookie:
        session_token = cookies().get('x-rucio-auth-token')
    valid_token_dict = auth.validate_auth_token(session_token)
    if not valid_token_dict or not session_token:
        return None
    else:
        valid_token_dict['token'] = session_token
        return valid_token_dict
Пример #15
0
def rucio_loadhook():
    """ Rucio load Hook to authenticate, timing, etc. """

    # Allow cross-site scripting
    header('Access-Control-Allow-Origin', ctx.env.get('HTTP_ORIGIN'))
    header('Access-Control-Allow-Headers',
           ctx.env.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
    header('Access-Control-Allow-Methods', '*')
    header('Access-Control-Allow-Credentials', 'true')

    if ctx.env.get('REQUEST_METHOD') == 'OPTIONS':
        raise OK

    if ctx.env.get('REQUEST_METHOD') == 'GET':
        header('Cache-Control',
               'no-cache, no-store, max-age=0, must-revalidate')
        header('Cache-Control', 'post-check=0, pre-check=0', False)
        header('Pragma', 'no-cache')
    else:
        header('Content-Type', 'application/octet-stream')

    auth_token = ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN')
    try:
        auth = validate_auth_token(auth_token)
    except RucioException as error:
        raise generate_http_error(500, error.__class__.__name__, error.args[0])
    except Exception as error:
        print(format_exc())
        raise InternalError(error)

    if auth is None:
        raise generate_http_error(
            401, 'CannotAuthenticate',
            'Cannot authenticate with given credentials')

    # Propagate the issuer, request_id and start_time to the controller
    ctx.env['vo'] = auth.get('vo')
    ctx.env['issuer'] = auth.get('account')
    ctx.env['identity'] = auth.get('identity')
    ctx.env['request_id'] = generate_uuid()
    ctx.env['start_time'] = time()
Пример #16
0
def check_token(rendered_tpl):
    attribs = None
    token = None
    js_token = ""
    js_account = ""
    def_account = None
    accounts = None
    cookie_accounts = None
    rucio_ui_version = version.version_string()

    ui_account = None
    if 'ui_account' in input():
        ui_account = input()['ui_account']

    render = template.render(join(dirname(__file__), '../templates'))
    if ctx.env.get('SSL_CLIENT_VERIFY') != 'SUCCESS':
        return render.problem(
            "No certificate provided. Please authenticate with a certificate registered in Rucio."
        )

    dn = ctx.env.get('SSL_CLIENT_S_DN')

    msg = "Your certificate (%s) is not mapped to any rucio account." % dn
    msg += "<br><br><font color=\"red\">First, please make sure it is correctly registered in <a href=\"https://voms2.cern.ch:8443/voms/atlas\">VOMS</a> and be patient until it has been fully propagated through the system.</font>"
    msg += "<br><br>Then, if it is still not working please contact <a href=\"mailto:[email protected]\">DDM Support</a>."

    # try to get and check the rucio session token from cookie
    session_token = cookies().get('x-rucio-auth-token')
    validate_token = authentication.validate_auth_token(session_token)

    # check if ui_account param is set and if yes, force new token
    if ui_account:
        accounts = identity.list_accounts_for_identity(dn, 'x509')

        if len(accounts) == 0:
            return render.problem(msg)

        if ui_account not in accounts:
            return render.problem(
                "The rucio account (%s) you selected is not mapped to your certificate (%s). Please select another account or none at all to automatically use your default account."
                % (ui_account, dn))

        cookie_accounts = accounts
        if (validate_token is None) or (validate_token['account'] !=
                                        ui_account):
            try:
                token = authentication.get_auth_token_x509(
                    ui_account, dn, 'webui', ctx.env.get('REMOTE_ADDR'))
            except:
                return render.problem(msg)

        attribs = list_account_attributes(ui_account)
        js_token = __to_js('token', token)
        js_account = __to_js('account', def_account)
    else:
        # if there is no session token or if invalid: get a new one.
        if validate_token is None:
            # get all accounts for an identity. Needed for account switcher in UI.
            accounts = identity.list_accounts_for_identity(dn, 'x509')
            if len(accounts) == 0:
                return render.problem(msg)

            cookie_accounts = accounts

            # try to set the default account to the user account, if not available take the first account.
            def_account = accounts[0]
            for account in accounts:
                account_info = get_account_info(account)
                if account_info.account_type == AccountType.USER:
                    def_account = account
                    break

            selected_account = cookies().get('rucio-selected-account')
            if (selected_account):
                def_account = selected_account
            try:
                token = authentication.get_auth_token_x509(
                    def_account, dn, 'webui', ctx.env.get('REMOTE_ADDR'))
            except:
                return render.problem(msg)

            attribs = list_account_attributes(def_account)
            # write the token and account to javascript variables, that will be used in the HTML templates.
            js_token = __to_js('token', token)
            js_account = __to_js('account', def_account)

    # if there was no valid session token write the new token to a cookie.
    if token:
        setcookie('x-rucio-auth-token', value=token, path='/')
        setcookie('rucio-auth-token-created-at', value=int(time()), path='/')

    if cookie_accounts:
        values = ""
        for acc in cookie_accounts:
            values += acc + " "
        setcookie('rucio-available-accounts', value=values[:-1], path='/')

    if attribs:
        setcookie('rucio-account-attr', value=dumps(attribs), path='/')

    if ui_account:
        setcookie('rucio-selected-account', value=ui_account, path='/')
    return render.base(js_token, js_account, rucio_ui_version, rendered_tpl)
Пример #17
0
    def get(self):
        """
        Sign a URL for a limited lifetime for a particular service.

        :reqheader X-Rucio-Account: Account identifier as a string.
        :reqheader X-Rucio-AppID: Application identifier as a string.
        :resheader Access-Control-Allow-Origin:
        :resheader Access-Control-Allow-Headers:
        :resheader Access-Control-Allow-Methods:
        :resheader Access-Control-Allow-Credentials:
        :resheader Access-Control-Expose-Headers:
        :resheader X-Rucio-Auth-Token: The authentication token
        :status 200: Successfully signed URL
        :status 400: Bad Request
        :status 401: Unauthorized
        :status 500: Internal Server Error
        """

        response = Response()
        response.headers['Access-Control-Allow-Origin'] = request.environ.get(
            'HTTP_ORIGIN')
        response.headers['Access-Control-Allow-Headers'] = request.environ.get(
            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
        response.headers['Access-Control-Allow-Methods'] = '*'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        response.headers[
            'Access-Control-Expose-Headers'] = 'X-Rucio-Auth-Token'

        response.headers['Content-Type'] = 'application/octet-stream'
        response.headers[
            'Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
        response.headers['Cache-Control'] = 'post-check=0, pre-check=0'
        response.headers['Pragma'] = 'no-cache'

        account = request.environ.get('HTTP_X_RUCIO_ACCOUNT')
        appid = request.environ.get('HTTP_X_RUCIO_APPID')
        if appid is None:
            appid = 'unknown'
        ip = request.environ.get('HTTP_X_FORWARDED_FOR')
        if ip is None:
            ip = request.remote_addr

        try:
            validate_auth_token(request.environ.get('HTTP_X_RUCIO_AUTH_TOKEN'))
        except AccessDenied:
            return generate_http_error_flask(
                401, 'CannotAuthenticate',
                'Cannot authenticate to account %(account)s with given credentials'
                % locals())
        except RucioException as error:
            return generate_http_error_flask(500, error.__class__.__name__,
                                             error.args[0])
        except Exception as error:
            print(format_exc())
            return error, 500

        svc, operation, url = None, None, None
        try:
            params = parse_qs(request.query[1:])
            lifetime = params.get('lifetime', [600])[0]
            service = params.get('svc', ['gcs'])[0]
            operation = params.get('op', ['read'])[0]
            url = params.get('url', [None])[0]
        except ValueError:
            return generate_http_error_flask(
                400, 'ValueError', 'Cannot decode json parameter list')

        if service not in ['gcs']:
            return generate_http_error_flask(
                400, 'ValueError',
                'Parameter "svc" must be either empty(=gcs), or gcs')

        if url is None:
            return generate_http_error_flask(400, 'ValueError',
                                             'Parameter "url" not found')

        if operation not in ['read', 'write', 'delete']:
            return generate_http_error_flask(
                400, 'ValueError',
                'Parameter "op" must be either empty(=read), read, write, or delete.'
            )

        try:
            result = get_signed_url(account,
                                    appid,
                                    ip,
                                    service=service,
                                    operation='read',
                                    url=url,
                                    lifetime=lifetime)
        except RucioException as error:
            return generate_http_error_flask(500, error.__class__.__name__,
                                             error.args[0])
        except Exception as error:
            print(format_exc())
            return error, 500

        if not result:
            return generate_http_error_flask(
                401, 'CannotAuthenticate',
                'Cannot generate signed URL for account %(account)s' %
                locals())

        return response
Пример #18
0
    def GET(self):
        """
        HTTP Success:
            200 OK

        HTTP Error:
            400 Bad Request
            401 Unauthorized
            406 Not Acceptable
            500 Internal Server Error

        :param Rucio-VO: VO name as a string (Multi-VO only).
        :param Rucio-Account: Account identifier as a string.
        :param Rucio-AppID: Application identifier as a string.

        :returns: Signed URL.
        """

        vo = ctx.env.get('HTTP_X_RUCIO_VO')
        account = ctx.env.get('HTTP_X_RUCIO_ACCOUNT')
        appid = ctx.env.get('HTTP_X_RUCIO_APPID')
        if appid is None:
            appid = 'unknown'
        ip = ctx.env.get('HTTP_X_FORWARDED_FOR')
        if ip is None:
            ip = ctx.ip

        try:
            validate_auth_token(ctx.env.get('HTTP_X_RUCIO_AUTH_TOKEN'))
        except RucioException as e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0][0])
        except Exception as e:
            print(format_exc())
            raise InternalError(e)

        svc, operation, url = None, None, None
        try:
            params = parse_qs(ctx.query[1:])
            lifetime = params.get('lifetime', [600])[0]
            service = params.get('svc', ['gcs'])[0]
            operation = params.get('op', ['read'])[0]
            url = params.get('url', [None])[0]
        except ValueError:
            raise generate_http_error(400, 'ValueError',
                                      'Cannot decode json parameter list')

        if service not in ['gcs', 's3', 'swift']:
            raise generate_http_error(
                400, 'ValueError',
                'Parameter "svc" must be either empty(=gcs), gcs, s3 or swift')

        if url is None:
            raise generate_http_error(400, 'ValueError',
                                      'Parameter "url" not found')

        if operation not in ['read', 'write', 'delete']:
            raise generate_http_error(
                400, 'ValueError',
                'Parameter "op" must be either empty(=read), read, write, or delete.'
            )

        try:
            result = get_signed_url(account,
                                    appid,
                                    ip,
                                    service=service,
                                    operation=operation,
                                    url=url,
                                    lifetime=lifetime,
                                    vo=vo)
        except RucioException as e:
            raise generate_http_error(500, e.__class__.__name__, e.args[0])
        except Exception as e:
            print(format_exc())
            raise InternalError(e)

        if not result:
            raise generate_http_error(
                401, 'CannotAuthenticate',
                'Cannot generate signed URL for account %(account)s' %
                locals())

        return result
Пример #19
0
def saml_authentication(method, rendered_tpl):
    """
    Login with SAML

    :param method: method type, GET or POST
    :param rendered_tpl: page to be rendered
    """

    attribs = None
    token = None
    js_token = ""
    js_account = ""
    def_account = None
    accounts = None
    cookie_accounts = None
    rucio_ui_version = version.version_string()
    policy = config_get('policy', 'permission')

    # Initialize variables for sending SAML request
    SAML_PATH = join(dirname(__file__), 'saml/')
    request = ctx.env
    data = dict(input())
    req = prepare_webpy_request(request, data)
    auth = OneLogin_Saml2_Auth(req, custom_base_path=SAML_PATH)

    saml_user_data = cookies().get('saml-user-data')

    render = template.render(join(dirname(__file__), '../templates'))

    session_token = cookies().get('x-rucio-auth-token')
    validate_token = authentication.validate_auth_token(session_token)

    if method == "GET":
        # If user data is not present, redirect to IdP for authentication
        if not saml_user_data:
            return seeother(auth.login())

        # If user data is present and token is valid, render the required page
        elif validate_token:
            js_token = __to_js('token', session_token)
            js_account = __to_js('account', def_account)

            return render.base(js_token, js_account, rucio_ui_version, policy,
                               rendered_tpl)

        # If user data is present but token is not valid, create a new one
        saml_nameid = cookies().get('saml-nameid')
        accounts = identity.list_accounts_for_identity(saml_nameid, 'saml')

        cookie_accounts = accounts
        try:
            token = authentication.get_auth_token_saml(
                def_account, saml_nameid, 'webui',
                ctx.env.get('REMOTE_ADDR')).token

        except:
            return render.problem('Cannot get auth token')

        attribs = list_account_attributes(def_account)
        # write the token and account to javascript variables, that will be used in the HTML templates.
        js_token = __to_js('token', token)
        js_account = __to_js('account', def_account)

        set_cookies(token, cookie_accounts, attribs)

        return render.base(js_token, js_account, rucio_ui_version, policy,
                           rendered_tpl)

    # If method is POST, check the received SAML response and redirect to home if valid
    auth.process_response()
    errors = auth.get_errors()
    if not errors:
        if auth.is_authenticated():
            setcookie('saml-user-data', value=auth.get_attributes(), path='/')
            setcookie('saml-session-index',
                      value=auth.get_session_index(),
                      path='/')
            setcookie('saml-nameid', value=auth.get_nameid(), path='/')
            saml_nameid = auth.get_nameid()

            accounts = identity.list_accounts_for_identity(saml_nameid, 'saml')
            cookie_accounts = accounts
            # try to set the default account to the user account, if not available take the first account.
            def_account = accounts[0]
            for account in accounts:
                account_info = get_account_info(account)
                if account_info.account_type == AccountType.USER:
                    def_account = account
                    break

            selected_account = cookies().get('rucio-selected-account')
            if (selected_account):
                def_account = selected_account

            try:
                token = authentication.get_auth_token_saml(
                    def_account, saml_nameid, 'webui',
                    ctx.env.get('REMOTE_ADDR')).token

            except:
                return render.problem('Cannot get auth token')

            attribs = list_account_attributes(def_account)
            # write the token and account to javascript variables, that will be used in the HTML templates.
            js_token = __to_js('token', token)
            js_account = __to_js('account', def_account)

            set_cookies(token, cookie_accounts, attribs)

            return seeother("/")

        return render.problem("Not authenticated")

    return render.problem("Error while processing SAML")
Пример #20
0
def log_in(data, rendered_tpl):
    attribs = None
    token = None
    js_token = ""
    js_account = ""
    def_account = None
    accounts = None
    cookie_accounts = None
    rucio_ui_version = version.version_string()
    policy = config_get('policy', 'permission')

    render = template.render(join(dirname(__file__), '../templates'))

    # # try to get and check the rucio session token from cookie
    session_token = cookies().get('x-rucio-auth-token')
    validate_token = authentication.validate_auth_token(session_token)

    # if token is valid, render the requested page.
    if validate_token and not data:
        token = session_token
        js_token = __to_js('token', token)
        js_account = __to_js('account', def_account)

        return render.base(js_token, js_account, rucio_ui_version, policy,
                           rendered_tpl)

    else:
        # if there is no session token or if invalid: get a new one.
        # if user tries to access a page through URL without logging in, then redirect to login page.
        if rendered_tpl:
            return render.login()

        # get all accounts for an identity. Needed for account switcher in UI.
        accounts = identity.list_accounts_for_identity(data.username,
                                                       'userpass')
        if len(accounts) == 0:
            return render.problem('No accounts for the given identity.')

        cookie_accounts = accounts
        # try to set the default account to the user account, if not available take the first account.
        def_account = accounts[0]
        for account in accounts:
            account_info = get_account_info(account)
            if account_info.account_type == AccountType.USER:
                def_account = account
                break

        selected_account = cookies().get('rucio-selected-account')
        if (selected_account):
            def_account = selected_account

        try:
            token = authentication.get_auth_token_user_pass(
                def_account, data.username, data.password.encode("ascii"),
                'webui', ctx.env.get('REMOTE_ADDR')).token

        except:
            return render.problem('Cannot get auth token')

        attribs = list_account_attributes(def_account)
        # write the token and account to javascript variables, that will be used in the HTML templates.
        js_token = __to_js('token', token)
        js_account = __to_js('account', def_account)

    set_cookies(token, cookie_accounts, attribs)

    return seeother('/')