Пример #1
0
    def on_post(self, req, resp):
        params = req.media
        try:
            username_attempt = params['username']
            password_attempt = params['password']
        except KeyError:
            raise falcon.HTTPInvalidParam('HTTP param not valid')
        u = User.find_one({'username': username_attempt})
        if not u:
            raise falcon.HTTPUnauthorized('User %(username)s not exists' %
                                          params)
        if not password.verify_password(u.password, password_attempt):
            raise falcon.HTTPUnauthorized('Incorrect password')

        session = req.context['session']
        session.login(u)
        permissions = u.get_permissions()
        resp.media = {
            'title': 'Login Success',
            'user_id': str(u.id),
            'username': str(u.username),
            'permissions': [p.to_json_dict() for p in permissions],
        }
Пример #2
0
    def authenticate(self, req, resp, resource):
        """
        Extract basic auth token from request `authorization` header,  decode the
        token, verifies the username/password and return either a ``user``
        object if successful else raise an `falcon.HTTPUnauthorized exception`
        """
        username, password = self._extract_credentials(req)
        user = self.user_loader(username, password)
        if not user:
            raise falcon.HTTPUnauthorized(
                description='Invalid Username/Password',
                challenges=self.challenges)

        return user
Пример #3
0
    async def process_request(self, req, resp):
        token = req.get_header('Authorization')
        account_id = req.get_header('Account-ID')

        challenges = ['Token type="Fernet"']

        if token is None:
            description = ('Please provide an auth token '
                           'as part of the request.')

            raise falcon.HTTPUnauthorized(title='Auth token required',
                                          description=description,
                                          challenges=challenges,
                                          href='http://docs.example.com/auth')

        if not self._token_is_valid(token, account_id):
            description = ('The provided auth token is not valid. '
                           'Please request a new token and try again.')

            raise falcon.HTTPUnauthorized(title='Authentication required',
                                          description=description,
                                          challenges=challenges,
                                          href='http://docs.example.com/auth')
Пример #4
0
    def authenticate(self, req, resp, resource):
        challenges = []
        for backend in self.backends:
            try:
                user = backend.authenticate(req, resp, resource)
                if user:
                    return user
            except falcon.HTTPUnauthorized as ex:
                www_authenticate = ex.headers.get('WWW-Authenticate')
                if www_authenticate:
                    challenges.append(www_authenticate)

        raise falcon.HTTPUnauthorized(description='Authorization Failed',
                                      challenges=challenges)
Пример #5
0
 def on_patch(self, req: falcon.Request, res: falcon.Response):
     # todo: use salted password
     if self.auth_error:
         raise self.auth_error
     nickname = req.get_param('nickname')
     if not nickname:
         raise falcon.HTTPMethodNotAllowed(ERROR_INVALID_REQUEST)
     if self.user and self.user['nickname'] == nickname:
         result = r.db(DB_NAME).table(DB_TABLE_USERS).update(
             self.data).run(conn)
         res.body = json.dumps(result)
     else:
         raise falcon.HTTPUnauthorized('Unauthorized Error',
                                       ERROR_INVALID_REQUEST)
Пример #6
0
def user_belongs_to_organization(req, resp, resource, params):
    session = req.context['session']
    user = req.context['user']

    organization_id = params['organization_id']
    has_permissions = session.query(OrganizationMember).\
            filter_by(user_id=user.id, organization_id=organization_id).\
            one_or_none()

    if has_permissions == None:
        resp.context['type'] = FAIL_RESPONSE
        resp.context['result'] = {'unauthorized': 'no permission to perform'}
        resp.status = falcon.HTTP_UNAUTHORIZED
        raise falcon.HTTPUnauthorized()
Пример #7
0
 def _check_authorization(self, request, segments):
     # We have to do this here instead of in a @falcon.before() handler
     # because those handlers are not compatible with our custom traversal
     # logic.  Specifically, falcon's before/after handlers will call the
     # responder, but the method we're wrapping isn't a responder, it's a
     # child traversal method.  There's no way to cause the thing that
     # calls the before hook to follow through with the child traversal in
     # the case where no error is raised.
     if request.auth is None:
         raise falcon.HTTPUnauthorized(
             '401 Unauthorized',
             'The REST API requires authentication')
     if request.auth.startswith('Basic '):
         # b64decode() returns bytes, but we require a str.
         credentials = b64decode(request.auth[6:]).decode('utf-8')
         username, password = credentials.split(':', 1)
         if (username != config.webservice.admin_user or
             password != config.webservice.admin_pass):
             # Not authorized.
             raise falcon.HTTPUnauthorized(
                 '401 Unauthorized',
                 'User is not authorized for the REST API')
     return TopLevel()
Пример #8
0
    def on_patch(self, req, resp, service_slug):
        try:
            service = self.db.query(Service).filter(
                Service.slug == service_slug).one()
        except NoResultFound:
            self.db.rollback()
            resp.status = falcon.HTTP_BAD_REQUEST
            resp.media = {
                "title": _(f"No service with slug '{service_slug}' exists."),
                "description": _("You can see all services at /services"),
            }
            return

        # If the user is not a site admin
        if req.user['username'] not in SITE_ADMINS:
            # Only let site admins and service admins modify services
            try:
                self.db.query(Permission)\
                    .join(Service, Service.id == Permission.service_id)\
                    .filter(Service.slug == service_slug,
                            Permission.type == 'service-admin',
                            Permission.username == req.user['username'])\
                    .one()
            except NoResultFound:
                logger.audit(
                    f"Unauthorized: user {req.user['username']} attempted to update the "
                    f"'{service.name}' service but is not a site admin or a service "
                    "admin for it")

                title = _(f"You cannot modify the metadata of this service.")
                description = _(
                    f"Only site administrators and service administrators are allowed "
                    "to modify service metadata.")
                raise falcon.HTTPUnauthorized(title, description)

        if req.media.get('name') is not None:
            service.name = req.media.get('name')

        if req.media.get('description') is not None:
            service.description = req.media.get('description')

        self.db.add(service)

        try:
            self.db.commit()
        except IntegrityError:
            self.db.rollback()
            raise
        else:
            resp.media = service_to_dict(service)
Пример #9
0
    def _extract_credentials(self, req):
        auth = req.get_header('Authorization')
        token = self.parse_auth_token_from_request(auth_header=auth)
        try:
            token = base64.b64decode(token).decode('utf-8')

        except Exception as ex:
            raise falcon.HTTPUnauthorized(
                title='401 Unauthorized',
                description=
                'Invalid Authorization Header: Unable to decode credentials',
                challenges=None)

        try:
            username, password = token.split(':')
        except ValueError:
            raise falcon.HTTPUnauthorized(
                title='401 Unauthorized',
                description=
                'Invalid Authorization: Unable to decode credentials',
                challenges=None)

        return username, password
Пример #10
0
    def on_post(self, req, res):
        unauthorized_title = 'Unauthorized'
        unauthorized_description = 'Invalid credentials'

        email = req.context['data']['email']
        password = req.context['data']['password']

        self.cursor.callproc('sp_lookup_user_by_email', [email, ])

        result = self.cursor.fetchone()
        if result is None:
            raise falcon.HTTPUnauthorized(unauthorized_title, unauthorized_description)

        result = result[0]

        valid_password = verify_password(password, result.pop('password'))
        if not valid_password:
            raise falcon.HTTPUnauthorized(unauthorized_title, unauthorized_description)

        res.status = falcon.HTTP_200
        res.body = json.dumps({
            'token': generate_token(result)
        })
Пример #11
0
    def on_post(self, req, resp, *args, **kwargs):
        super(ResourceCreateUserToken, self).on_post(req, resp, *args,
                                                     **kwargs)

        basic_auth_raw = req.get_header("Authorization")
        if basic_auth_raw is not None:
            basic_auth = basic_auth_raw.split()[1]
            auth_username, auth_password = (
                base64.b64decode(basic_auth).decode("utf-8").split(":"))
            if (auth_username is None) or (auth_password is None) or (
                    auth_username == "") or (auth_password == ""):
                raise falcon.HTTPUnauthorized(
                    description=messages.username_and_password_required)
        else:
            raise falcon.HTTPUnauthorized(
                description=messages.authorization_header_required)

        current_user = self.db_session.query(User).filter(
            User.email == auth_username).one_or_none()
        if current_user is None:
            current_user = self.db_session.query(User).filter(
                User.username == auth_username).one_or_none()

        if (current_user
                is not None) and (current_user.check_password(auth_password)):
            current_token = current_user.create_token()
            try:
                self.db_session.commit()
                resp.media = {"token": current_token.token}
                resp.status = falcon.HTTP_200
            except Exception as e:
                mylogger.critical("{}:{}".format(
                    messages.error_saving_user_token, e))
                self.db_session.rollback()
                raise falcon.HTTPInternalServerError()
        else:
            raise falcon.HTTPUnauthorized(description=messages.user_not_found)
Пример #12
0
    def process_request(self, req, resp):

        # TODO: Review security of allowing un auth-ed OPTIONS
        if req.path == '/auth' or req.method == 'OPTIONS':
            # print('in excepted ep')
            return
        else:
            pass
            # print('required auth')
            # print(req.path)

        token = req.get_header('Authorization')

        # parse out token from bearer
        try:
            token = token.split(' ')[1]
        except:
            pass

        challenges = ['Token type="JWT"']

        # Check to see the user has provided a token
        if token is None:
            description = ('Please provide an auth token '
                           'as part of the request.')
            raise falcon.HTTPUnauthorized('Auth token required',
                                          description,
                                          challenges,
                                          href='http://docs.example.com/auth')
        # Check the validity of the JWT
        if not self._token_is_valid(token):
            description = ('The provided auth token is not valid. '
                           'Please request a new token and try again.')
            raise falcon.HTTPUnauthorized('Authentication required',
                                          description,
                                          challenges,
                                          href='http://docs.example.com/auth')
Пример #13
0
    def process_request(self, req, resp):
        # Do not require auth to access index
        if req.relative_uri == '/':
            return

        auth = req.get_header("Authorization")
        if auth is None or not auth.startswith('Basic '):
            raise falcon.HTTPUnauthorized(
                'Authorization token required',
                'Provide a Basic Authentication header',
                ['Basic realm="FreeNAS"'],
            )
        try:
            username, password = base64.b64decode(
                auth[6:]).decode('utf8').split(':', 1)
        except binascii.Error:
            raise falcon.HTTPUnauthorized(
                'Invalid Authorization token',
                'Provide a valid Basic Authentication header',
                ['Basic realm="FreeNAS"'],
            )

        try:
            client = Client()
            client.connect('unix:')
            client.login_user(username, password, check_password=True)
            req.context['client'] = client
        except RpcException as e:
            if e.code == errno.EACCES:
                raise falcon.HTTPUnauthorized(
                    'Invalid credentials',
                    'Verify your credentials and try again.',
                    ['Basic realm="FreeNAS"'],
                )
            raise falcon.HTTPUnauthorized('Unknown authentication error',
                                          str(e), ['Basic realm="FreeNAS"'])
Пример #14
0
    def process_request(self, req, resp):
        """
        Processes an authentification request.

        @param  req     request
        @param  resp    unused
        """
        if req.scheme.lower() != 'https':
            raise falcon.HTTPBadRequest(
                title='HTTPS Required',
                description=(
                    'All requests must be performed via the HTTPS protocol. '
                    'Please switch to HTTPS and try again.'))

        auth = req.get_header('Authorization')
        token = self.parse_auth_token_from_request(auth_header=auth)
        try:
            token = base64.b64decode(token).decode('utf-8')
        except Exception:
            raise falcon.HTTPUnauthorized(
                title='401 Unauthorized',
                description=
                'Invalid Authorization Header: Unable to decode credentials (1)'
            )

        try:
            username, password = token.split(':', 1)
        except ValueError:
            raise falcon.HTTPUnauthorized(
                title='401 Unauthorized',
                description=
                'Invalid Authorization: Unable to decode credentials (2)')

        if not self._token_is_valid(username, password):
            raise falcon.HTTPUnauthorized(
                "Authentication failed for '{0}'".format(username))
Пример #15
0
def requires_auth(req):
    """Determines if the Access Token is valid
    """
    token = get_token_auth_header(req)

    jsonurl = urlopen("https://" + AUTH0_DOMAIN + "/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)

    rsa_key = {}
    for key in jwks["keys"]:
        if key["kid"] == unverified_header["kid"]:
            rsa_key = {
                "kty": key["kty"],
                "kid": key["kid"],
                "use": key["use"],
                "n": key["n"],
                "e": key["e"]
            }
    if rsa_key:
        try:
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer="https://" + AUTH0_DOMAIN + "/")
        except jwt.ExpiredSignatureError:
            raise falcon.HTTPUnauthorized("token is expired")
        except jwt.JWTClaimsError:
            raise falcon.HTTPUnauthorized(
                "incorrect claims please check the audience and issuer")
        except Exception:
            raise falcon.HTTPUnauthorized(
                "Unable to parse authentication token")

    return payload
Пример #16
0
    def on_post(self, req, resp):
        token = req.context['token']
        session = req.context['session']
        if not Token.getUserId(token):
            raise falcon.HTTPUnauthorized(
                "Unauthorized", "You are not allowed to create tags")

        tag = Tag()
        session.add(tag)
        tag.update(req.params)
        session.commit()
        session.flush()
        session.refresh(tag)

        resp.body = json.dumps(tag.json())
Пример #17
0
    def authenticate(self, req, resp, resource):
        """
        Extract auth token from request `authorization` header,  deocode jwt token,
        verify configured claims and return either a ``user``
        object if successful else raise an `falcon.HTTPUnauthoried exception`
        """
        payload = self._decode_jwt_token(req)
        user = self.user_loader(payload)
        if not user:
            raise falcon.HTTPUnauthorized(
                title='401 Unauthorized',
                description='Invalid JWT Credentials',
                challenges=None)

        return user
Пример #18
0
    def on_get(self, req, resp):
        if not req.auth:
            raise falcon.HTTPUnauthorized("No username or password presented")

        auth = base64.b64decode(req.auth.split()[1]).decode('utf-8').split(':')
        header = {"alg": "HS256", "typ": "JWT"}
        payload = {
            "iss": auth[0],
            "exp": int(time.time()) + settings.TOKEN_TTL,
            "prv": ",".join(self._db.get_usr(auth[0], auth[1]))
        }
        tok = self._generate_token(header, payload)

        resp.body = {"Bearer": tok}
        resp.status = falcon.HTTP_200
Пример #19
0
    def on_get(self, req, resp):
        auth = req.auth

        try:
            if not auth or not auth.startswith('Basic '):
                raise falcon.HTTPUnauthorized()

            dec = base64.b64decode(auth.replace('Basic ', '')).decode('ascii')
            secret = os.getenv("PFT_ADMIN_SECRET")

            if not secret:
                raise falcon.HTTPUnauthorized()

            if not dec == f'admin:{secret}':
                raise falcon.HTTPUnauthorized()

        except binascii.Error:
            raise falcon.HTTPUnauthorized()

        result = {}
        for k, v in os.environ.items():
            result[k] = v

        resp.media = result
Пример #20
0
    def process_request(self, req, resp):
        path = req.path.split("/v1/")

        open_paths = [
            'auth/login', 'auth/create_user', 'auth/verify_token',
            'auth/reset_password'
            'auth/logout'
        ]

        if path[1] == 'auth/get_token':
            key = req.get_header('Authorization')
            if key == GET_RESET_PASSWORD_TOKEN_KEY:
                return
            else:
                raise falcon.HTTPUnauthorized(
                    {'error': 'invalid authorization key'})

        if path[1] in open_paths:
            return

        token = req.get_header('Authorization')
        challenges = ['Token type="Fernet"']

        if token is None:
            description = ('Please provide an auth token '
                           'as part of the request.')

            raise falcon.HTTPUnauthorized('Auth token required', description,
                                          challenges)

        if not self._token_is_valid(token):
            description = ('The provided auth token is not valid. '
                           'Please request a new token and try again.')

            raise falcon.HTTPUnauthorized('Authentication required',
                                          description, challenges)
Пример #21
0
 def on_post(req, resp, *args, **kwargs):
     try:
         current = Current(request=req, response=resp)
         if not (current.is_auth
                 or view_path in settings.ANONYMOUS_WORKFLOWS):
             raise falcon.HTTPUnauthorized("Login required", view_path)
         view(current, *args, **kwargs)
     except HTTPError:
         raise
     except:
         if settings.DEBUG:
             resp.status = falcon.HTTP_500
             resp.body = json.dumps({'error': traceback.format_exc()})
         else:
             raise
Пример #22
0
def login_required(req, resp, resource, params):
    if req.auth == None:
        resp.context['type'] = FAIL_RESPONSE
        resp.context['result'] = {'unauthorized': 'no auth token provided'}
        resp.status = falcon.HTTP_UNAUTHORIZED
        raise falcon.HTTPUnauthorized()

    session = req.context['session']

    token = session.query(Token).filter_by(key=req.auth).one_or_none()
    if token == None:
        resp.context['type'] = FAIL_RESPONSE
        resp.context['result'] = {'unauthorized': 'invalid token'}
        resp.status = falcon.HTTP_UNAUTHORIZED
        raise falcon.HTTPUnauthorized()

    user = session.query(User).get(token.user_id)
    if user == None:
        resp.context['type'] = FAIL_RESPONSE
        resp.context['result'] = {'unauthorized': 'invalid user'}
        resp.status = falcon.HTTP_UNAUTHORIZED
        raise falcon.HTTPUnauthorized()

    req.context['user'] = user
Пример #23
0
    def func_wrapper(*args, **kwargs):
        req = args[1]

        try:
            assert req.context["auth"]["scope"] == "read:devices"
        except:
            logger.warning(
                f"Unauthorized access attemp to the resource: {req.url}"
                f"from the IP: {req.remote_addr}",
                extra={"area": "security"},
            )
            raise falcon.HTTPUnauthorized(
                "Unauthorized",
                "The user is not authorized to retrive this data.")
        return func(*args, **kwargs)
Пример #24
0
    def process_request(self, req, resp):
        project_id = req.get_header('X-Project-Id')

        if not project_id:
            desc = 'Please provide your X-Project-Id in the headers.'
            raise falcon.HTTPUnauthorized('Project id required', desc)

        # Create project if not found
        model = project.ProjectModel.get_by_external_id(
            project_id, self.db.session)
        if not model:
            model = project.ProjectModel(external_id=project_id)
            model.save(self.db.session)

        req.context.update({'project': model.id, 'external_id': project_id})
Пример #25
0
        def decorated(resource, req, resp, *args, **kwargs):

            if req.context.get('oauth'):
                return method(resource, req, resp, *args, **kwargs)

            valid, oauth_req = self.verify_request(req, scopes)

            if not valid:
                if self._on_error:
                    return self._on_error(req, resp)
                challenge = 'Bearer realm="{}"'.format(' '.join(scopes) or '*')
                raise falcon.HTTPUnauthorized('Auth required', 'Auth Required',
                                              [challenge])
            req.context['oauth'] = oauth_req
            return method(resource, req, resp, *args, **kwargs)
Пример #26
0
    def on_post(self, req, resp, *args, **kwargs):
        super(ResourceDeleteUserToken, self).on_post(req, resp, *args,
                                                     **kwargs)
        current_user = req.context["auth_user"]
        selected_token_string = req.media["token"]
        selected_token = self.db_session.query(UserToken).filter(
            UserToken.token == selected_token_string).one_or_none()

        if selected_token is not None:
            if selected_token.user.id == current_user.id:
                try:
                    self.db_session.delete(selected_token)
                    self.db_session.commit()

                    resp.status = falcon.HTTP_200
                except Exception as e:
                    mylogger.critical("{}:{}".format(
                        messages.error_removing_user_token, e))
                    raise falcon.HTTPInternalServerError()
            else:
                raise falcon.HTTPUnauthorized(
                    description=messages.token_doesnt_belongs_current_user)
        else:
            raise falcon.HTTPUnauthorized(description=messages.token_not_found)
Пример #27
0
 def get_jwt(self, id, email, alias, selected_campaign=None):
     campaigns = self.get_user_campaigns(id)
     if selected_campaign is None:
         selected_campaign = tuple(campaigns.keys())[0]
     if selected_campaign not in campaigns:
         raise falcon.HTTPUnauthorized("You do not belong to that campaign")
     return jwt.encode(
         {
             "id": id,
             "email": email,
             "alias": alias,
             "campaigns": campaigns,
             "selected_campaign": selected_campaign,
             "exp": datetime.datetime.utcnow() + datetime.timedelta(days=3)
         }, JWT_KEY)
Пример #28
0
    def parse_auth_token_from_request(self, auth_header):
        """
        Parses and returns Auth token from the request header. Raises
        `falcon.HTTPUnauthoried exception` with proper error message
        """

        if not auth_header:
            raise falcon.HTTPUnauthorized(description='Missing Authorization Header')

        parts = auth_header.split()

        if parts[0].lower() != self.auth_header_prefix.lower():
            raise falcon.HTTPUnauthorized(description=
                                          'Invalid Authorization Header: '
                                          'Must start with {0}'.format(self.auth_header_prefix))

        elif len(parts) == 1:
            raise falcon.HTTPUnauthorized(
                description='Invalid Authorization Header: Token Missing')
        elif len(parts) > 2:
            raise falcon.HTTPUnauthorized(
                description='Invalid Authorization Header: Contains extra content')

        return parts[1]
Пример #29
0
 def on_post(self, req, resp):
     """
     Accept slack's message from interactive buttons
     """
     try:
         form_post = falcon.uri.parse_query_string(req.context['body'])
         payload = ujson.loads(form_post['payload'])
         if not self.valid_token(payload['token']):
             logger.error('Invalid token sent in the request.')
             raise falcon.HTTPUnauthorized('Access denied',
                                           'Not a valid auth token')
         try:
             msg_id = int(payload['callback_id'])
         except KeyError as e:
             logger.error('callback_id not found in the json payload.')
             raise falcon.HTTPBadRequest('Bad Request',
                                         'Callback id not found')
         except ValueError as e:
             logger.error('Callback ID not an integer: %s',
                          payload['callback_id'])
             raise falcon.HTTPBadRequest('Bad Request',
                                         'Callback id must be int')
         data = {
             'msg_id': msg_id,
             'source': payload['user']['name'],
             'content': payload['actions'][0]['name']
         }
         endpoint = self.config['iris']['hook']['slack']
         try:
             result = self.iclient.post(endpoint, data)
         except MaxRetryError as e:
             logger.error(e.reason)
             return
         if result.status == 400:
             raise falcon.HTTPBadRequest('Bad Request', '')
         elif result.status is not 200:
             raise falcon.HTTPInternalServerError(
                 'Internal Server Error', 'Unknown response from the api')
         else:
             content = process_api_response(result.data)
             self.return_slack_message(resp, content)
         return
     except Exception:
         logger.exception(
             'Unable to read payload from slack. Our post body: %s',
             req.context['body'])
         raise falcon.HTTPBadRequest(
             'Bad Request', 'Unable to read the payload from slack')
Пример #30
0
 def on_post(self, req, resp):
     """
     Accept slack's message from interactive buttons
     """
     try:
         payload = ujson.loads(req.form['payload'])
         if not self.valid_token(payload['token']):
             logger.error('Invalid token sent in the request.')
             raise falcon.HTTPUnauthorized('Access denied',
                                           'Not a valid auth token')
         # TODO: Call Iris API to claim the incident
         self.return_slack_message(resp)
         return
     except Exception as e:
         logger.error('Unable to read payload from slack', e.reason)
         raise falcon.HTTPBadRequest('No Payload')