Example #1
0
 def validate(self):
     if not self.authenticated:
         raise AccessDeniedError("Credentials token missing") from None
     elif 'expire' in self._credentials:
         utc_expire = utc(self._credentials['expire'])
         if now() > utc_expire:
             self.clear()
             raise AccessDeniedError('Credentials token expired') from None
Example #2
0
def validate_access(req, obj_dict):
    if ('domain' in obj_dict and req.credentials.domain
            and req.credentials.domain != obj_dict['domain']):
        raise AccessDeniedError('object not in context domain "%s"' %
                                req.credentials.domain)

    if ('tenant_id' in obj_dict and req.credentials.tenant_id
            and (req.credentials.tenant_id != obj_dict['tenant_id']
                 and req.credentials.tenant_id != obj_dict['id'])):
        raise AccessDeniedError('object not in context tenant "%s"' %
                                req.credentials.tenant_id)

    return True
Example #3
0
    def json(self):
        # Return json token.
        if not self.authenticated:
            raise AccessDeniedError("Credentials token missing")

        utc_expire = utc(self._credentials['expire'])
        if now() > utc_expire:
            raise AccessDeniedError('Auth Token Expired')

        credentials = {}
        credentials['token'] = self.token
        credentials.update(self._credentials)
        return js.dumps(credentials)
Example #4
0
def check_context_auth(conn, user_id, domain, tenant_id):
    """Verify if users has jurisdiction over requested domain/tenant.

    The default Root user can assign any role to any user.

    Only users with Admin or Root roles are allowed to assign roles to
    users. This function will raise an error if the requesting user is
    not an admin user on the requested domain/tenant.

    Args:
        conn (obj): DB connection object.
        user_id (str): UUID of user.
        domain (str): Name of the domain.
        tenant_id (str): UUID of the tenant.
    """
    req_user_id = g.current_request.token.user_id
    if req_user_id != '00000000-0000-0000-0000-000000000000':
        cur = conn.execute("SELECT id FROM luxon_role WHERE name=?",
                           ('Administrator', ))
        admin_id = cur.fetchone()['id']

        query, vals = build_where(user_id=req_user_id,
                                  domain=domain,
                                  tenant_id=tenant_id)
        query += " AND ('role_id'='00000000-0000-0000-0000-000000000000'"
        query += " OR role_id=?)"
        vals.append(admin_id)

        sql = "SELECT id FROM luxon_user_role WHERE " + query
        cur = conn.execute(sql, vals)
        if not cur.fetchone():
            raise AccessDeniedError(
                "User %s not authorized in requested context "
                ": domain '%s', tenant_id '%s'" %
                (req_user_id, domain, tenant_id))
Example #5
0
    def token(self, token):
        # Load exisiting token
        token = if_unicode_to_bytes(token)
        signature, b64_token = token.split(b'!!!!')

        try:
            self._rsakey.verify(signature, b64_token)
        except ValueError as e:
            raise AccessDeniedError('Invalid Auth Token. %s' % e)

        decoded = js.loads(base64.b64decode(b64_token))
        utc_expire = utc(decoded['expire'])

        if now() > utc_expire:
            raise AccessDeniedError('Auth Token Expired')

        self._credentials = decoded
Example #6
0
    def domain(self, value):
        self.validate()

        if ('domain' in self._credentials
                and self._credentials['domain'] is not None):
            if self._credentials['domain'] != value:
                raise AccessDeniedError("Token already scoped in 'domain'")

        self._credentials['domain'] = value
Example #7
0
    def tenant_id(self, value):
        self.validate()

        if ('tenant_id' in self._credentials
                and self._credentials['tenant_id'] is not None):
            if self._credentials['tenant_id'] != value:
                raise AccessDeniedError("Token already scoped in 'tenant'")

        self._credentials['tenant_id'] = value
Example #8
0
    def token(self):
        # Return serialized token.
        if not self.authenticated:
            raise AccessDeniedError("Credentials token missing")

        utc_expire = utc(self._credentials['expire'])
        if now() > utc_expire:
            raise AccessDeniedError('Auth Token Expired')

        bytes_token = if_unicode_to_bytes(
            js.dumps(self._credentials, indent=None))
        b64_token = base64.b64encode(bytes_token)
        token_sig = if_unicode_to_bytes(self._rsakey.sign(b64_token))
        token = if_bytes_to_unicode(token_sig + b'!!!!' + b64_token)
        if len(token) > 1280:
            raise ValueError("Auth Token exceeded 10KB" +
                             " - Revise Assignments for credentials")

        return token
Example #9
0
    def password(self, username, domain, credentials):
        try:
            password = credentials['password']
        except KeyError:
            raise ValueError("No 'password' provided in 'credentials'")

        if domain is None and username == 'root' and password == 'password':
            return True
        else:
            raise AccessDeniedError('Invalid credentials provided')
Example #10
0
def validate_set_scope(req, obj_dict):
    if 'domain' in obj_dict:
        if (req.credentials.domain == req.context_domain
                or req.credentials.domain is None):
            if obj_dict['domain'] is None:
                if req.context_domain is not None:
                    obj_dict.update({"domain": req.context_domain})
        else:
            raise AccessDeniedError("Token not scoped for domain '%s'" %
                                    req.context_domain)

    if 'tenant_id' in obj_dict:
        if (req.credentials.tenant_id == req.context_tenant_id
                or req.credentials.tenant_id is None):
            if obj_dict['tenant_id'] is None:
                if req.context_tenant_id is not None:
                    obj_dict.update({"tenant_id": req.context_tenant_id})
        else:
            raise AccessDeniedError("Token not scoped for Tenant '%s'" %
                                    req.context_tenant_id)
Example #11
0
 def __setattr__(self, attr, value):
     if attr in self.__slots__:
         return object.__setattr__(self, attr, value)
     try:
         return object.__setattr__(self, attr, value)
     except AttributeError:
         self.validate()
         if (attr in self._credentials
                 and self._credentials[attr] is not None):
             raise AccessDeniedError("Token scope '%s'" % attr +
                                     " not allowed") from None
         self._credentials[attr] = value
Example #12
0
def auth(username, password):
    github = GitHub((
        username,
        password,
    ))
    teams = github.teams('TachyonicProject')
    roles = []
    for team in teams:
        id = team['id']
        role = team['name']
        members = github.team_members(id)
        for member in members:
            if member['login'] == username:
                roles.append(role)
    if len(roles) == 0:
        raise AccessDeniedError('Not member of any Tachyonic Project teams')
    return roles
Example #13
0
def authorize(tag, username=None, password=None, domain=None):
    with db() as conn:
        values = [
            tag,
            username,
        ]
        sql = 'SELECT username, password FROM luxon_user'
        sql += ' WHERE'
        sql += ' tag = %s'
        sql += ' AND username = %s'
        if domain is not None:
            sql += ' AND domain = %s'
            values.append(domain)
        else:
            sql += ' AND domain IS NULL'

        crsr = conn.execute(sql, values)
        result = crsr.fetchone()
        if result is not None:
            # Validate Password againts stored HASHED Value.
            if is_valid_password(password, result['password']):
                return True

        raise AccessDeniedError('Invalid credentials provided')
Example #14
0
    def proc(self, method, route):
        try:
            with Timer() as elapsed:
                # Request Object.
                request = g.current_request = Request(method, route)

                # Response Object.
                response = Response()

                # Set Response object for request.
                request.response = response

                # Debug output
                if g.app.debug is True:
                    log.info('Request %s' % request.route +
                             ' Method %s\n' % request.method)

                # Process the middleware 'pre' method before routing it
                for middleware in register._middleware_pre:
                    middleware(request, response)

                # Route Object.
                resource, method, r_kwargs, target, tag, cache = router.find(
                    request.method, request.route)

                # Route Kwargs in requests.
                request.route_kwargs = r_kwargs

                # Set route tag in requests.
                request.tag = tag

                # If route tagged validate with policy
                if tag is not None:
                    if not request.policy.validate(tag):
                        raise AccessDeniedError("Access Denied by" +
                                                " policy '%s'" % tag)

                # Execute Routed View.
                try:
                    # Process the middleware 'resource' after routing it
                    for middleware in register._middleware_resource:
                        middleware(request, response)
                    # Run View method.
                    if resource is not None:
                        view = resource(request, response, **r_kwargs)
                        if view is not None:
                            response.write(view)
                    else:
                        raise NotFoundError("Route not found" +
                                            " Method '%s'" % request.method +
                                            " Route '%s'" % request.route)
                finally:
                    # Process the middleware 'post' at the end
                    for middleware in register._middleware_post:
                        middleware(request, response)
        except KeyboardInterrupt:
            response.write('CTRL-C / KeyboardInterrupt')
        except Exception as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            # Return response object.
        finally:
            # Completed Request
            log.info('Completed CMD', timer=elapsed())
Example #15
0
    def __call__(self, *args, **kwargs):
        """Application Request Interface.

        A clean request and response object is provided to the interface that
        is unique this to this thread.

        It passes any args and kwargs to the interface.

        Response object is returned.
        """
        try:
            with Timer() as elapsed:
                # Request Object.
                request = g.current_request = Request(*args, **kwargs)
                request.env['SCRIPT_NAME'] = g.app.config.get(
                    'application',
                    'script',
                    fallback=request.env['SCRIPT_NAME'])

                script_name = request.get_header('X-Script-Name')
                if script_name:
                    request.env['SCRIPT_NAME'] = script_name

                # Response Object.
                response = Response(*args, **kwargs)

                # Set Response object for request.
                request.response = response

                # Debug output
                if g.app.debug is True:
                    log.info('Request %s' % request.route +
                             ' Method %s\n' % request.method)

                # Process the middleware 'pre' method before routing it
                for middleware in register._middleware_pre:
                    middleware(request, response)

                # Route Object.
                resource, method, r_kwargs, target, tag, cache = router.find(
                    request.method, request.route)

                # Route Kwargs in requests.
                request.route_kwargs = r_kwargs

                # Set route tag in requests.
                request.tag = tag

                # If route tagged validate with policy
                if tag is not None:
                    if not request.policy.validate(tag,
                                                   access_denied_raise=True):
                        raise AccessDeniedError("Access Denied by" +
                                                " policy '%s'" % tag)

                # Execute Routed View.
                try:
                    # Process the middleware 'resource' after routing it
                    for middleware in register._middleware_resource:
                        middleware(request, response)
                    # Run View method.
                    if resource is not None:
                        view = resource(request, response, **r_kwargs)
                        if view is not None:
                            response.body(view)
                    else:
                        raise NotFoundError("Route not found" +
                                            " Method '%s'" % request.method +
                                            " Route '%s'" % request.route)
                finally:
                    # Process the middleware 'post' at the end
                    self.post_middleware(request, response, False)

            # Cache GET Response.
            # Only cache for GET responses!
            if cache > 0 and request.method == 'GET':
                # Get session_id if any for Caching
                session_id = request.cookies.get(request.host)

                # NOTE(cfrademan): Instruct to use cache but revalidate on,
                # stale cache entry. Expire remote cache in same duration
                # as internal cache.
                if session_id:
                    response.set_header(
                        "cache-control",
                        "must-revalidate, private, max-age=" + str(cache))
                else:
                    response.set_header(
                        "cache-control",
                        "must-revalidate, max-age=" + str(cache))

                # Set Vary Header
                # NOTE(cfrademan): Client should uniquely cache
                # based these request headers.
                response.set_header(
                    'Vary', 'Cookie, Accept-Encoding' + ', Content-Type')

                # Set Etag
                # NOTE(cfrademan): Needed Encoding for Different Etag.
                if isinstance(response._stream, bytes):
                    encoding = request.get_header('Accept-Encoding')
                    response.etag.set(etagger(response._stream, encoding))

                # If Etag matches do not return full body use
                # external/user-agent cache.
                if (len(request.if_none_match) > 0
                        and request.if_none_match in response.etag):
                    # Etag matches do not return full body.
                    response.not_modified()

                # NOTE(cfrademan): Use last_modified as last resort for
                # external/user-agent cache.
                elif (request.if_modified_since and response.last_modified
                      and request.if_modified_since <= response.last_modified):
                    # Last-Modified matches do not return full body.
                    response.not_modified()
            else:
                response.set_header("cache-control",
                                    "no-store, no-cache, max-age=0")

            # Return response object.
            return response()

        except HTTPError as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            self.post_middleware(request, response, True)
            # Return response object.
            return response()
        except Error as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            self.post_middleware(request, response, True)
            # Return response object.
            return response()
        except Exception as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            self.post_middleware(request, response, True)
            # Return response object.
            return response()
        finally:
            # Completed Request
            log.info('Completed Request', timer=elapsed())