Esempio n. 1
0
def send_email(subject='', to_address=[], from_address=from_addr, content=''):
    """Send an email to a specified user or users.

    This is a basic wrapper around python's STMPLIB library that allows us to
    send emails to the users in case it's necessary. Any failure of this
    script is considered fatal.
    """
    try:
        msg = MIMEText(content)
        msg['Subject'] = "[{0}] {1} {2}".format(
            site_domain, subject,
            date.today().strftime("%Y%m%d"))
        msg['To'] = EMAIL_SPACE.join(to_address)
        msg['From'] = from_address
        logger.debug("All parameters set")
        mail = smtplib.SMTP(settings.SMTP_SERVER, settings.SMTP_PORT)
        logger.debug("Instantiated the SMTP")
        if settings.SMTP_TLS:
            mail.starttls()
            logger.debug("Started SMTP TLS connection")
        mail.login(settings.SMTP_USER, settings.SMTP_PASSWORD)
        logger.debug("Login success")
        mail.sendmail(from_addr, to_address, msg.as_string())
        logger.debug("Sent email")
        mail.quit()
    except Exception as e:
        logger.error("Email send failed. Error: {0}".format(e))
Esempio n. 2
0
File: headers.py Progetto: gnef/sikr
    def process_request(self, req, res):

        """Process the request before entering in the API

        Before we process anything in the API, we reset the Origin header to
        match the address from the request.

        Args:
            Access-Control-Allow-Origin: Change the origin to the URL that made
                the request.

        Raises:
            HTTP Error: An HTTP error in case the Origin header doesn't match
                        the predefined regular expression.

        Return:
            HTTP headers: A modified set of headers.

        """

        origin_domain = req.get_header('Origin')
        logger.debug("Origin domain is: {}, type: {}".format(origin_domain, type(origin_domain)))
        origin_header = origin_domain if settings.CORS_ACTIVE and origin_domain else "*"
        logger.debug("Origin header is: {}, type: {}".format(origin_header, type(origin_header)))

        res.set_headers([
            ('Cache-Control', 'no-store, must-revalidate, no-cache, max-age=0'),
            ('Content-Type', 'application/json; charset=utf-8'),
            ('Access-Control-Allow-Credentials', 'true'),
            ('Access-Control-Allow-Origin', origin_header),
            ('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, x-auth-user, x-auth-password, Authorization'),
            ('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS, DELETE')
        ])
Esempio n. 3
0
    def on_post(self, req, res):
        try:
            # Parse token and get user id
            user_id = parse_token(req)['sub']
            # Get the user
            user = User.get(User.id == int(user_id))
        except Exception as e:
            logger.error("Can't verify user")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            raw_json = req.stream.read()
            logger.debug("Got incoming JSON data")
        except Exception as e:
            logger.error("Can't read incoming data stream")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            result_json = json.loads(raw_json.decode("utf-8"), encoding='utf-8')
            logger.debug(result_json)
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                                   'Malformed JSON',
                                   'Could not decode the request body. The '
                                   'JSON was incorrect.')

        try:
            new_share = ShareToken(user=user, token=generate_token(),
                                   resource=int(result_json.get()))
        except:
            pass
Esempio n. 4
0
def send_email(subject='', to_address=[], from_address=from_addr, content=''):

    """Send an email to a specified user or users

    This is a basic wrapper around python's STMPLIB library that allows us to
    send emails to the users in case it's necessary. Any failure of this
    script is considered fatal.
    """
    try:
        msg = MIMEText(content)
        msg['Subject'] = "[{0}] {1} {2}".format(site_domain, subject, date.today().strftime("%Y%m%d"))
        msg['To'] = EMAIL_SPACE.join(to_address)
        msg['From'] = from_address
        logger.debug("All parameters set")
        mail = smtplib.SMTP(settings.SMTP_SERVER, settings.SMTP_PORT)
        logger.debug("Instantiated the SMTP")
        if settings.SMTP_TLS:
            mail.starttls()
            logger.debug("Started SMTP TLS connection")
        mail.login(settings.SMTP_USER, settings.SMTP_PASSWORD)
        logger.debug("Login success")
        mail.sendmail(from_addr, to_address, msg.as_string())
        logger.debug("Sent email")
        mail.quit()
    except Exception as e:
        logger.error("Email send failed. Error: {0}".format(e))
Esempio n. 5
0
    def on_post(self, req, res):
        try:
            # Parse token and get user id
            user_id = parse_token(req)['sub']
            # Get the user
            user = User.get(User.id == int(user_id))
        except Exception as e:
            logger.error("Can't verify user")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            raw_json = req.stream.read()
            logger.debug("Got incoming JSON data")
        except Exception as e:
            logger.error("Can't read incoming data stream")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            result_json = json.loads(raw_json.decode("utf-8"),
                                     encoding='utf-8')
            logger.debug(result_json)
        except ValueError:
            raise falcon.HTTPError(
                falcon.HTTP_400, 'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')

        try:
            new_service = Service.create(
                name=result_json.get("name"),
                item=result_json.get("item"),
                username=result_json.get("username", ''),
                password=result_json.get("password", ''),
                url=result_json.get("url", ''),
                port=result_json.get("port", 0),
                extra=result_json.get("extra", ''),
                ssh_title=result_json.get("ssh_title", ''),
                ssh_public=result_json.get("ssh_public", ''),
                ssh_private=result_json.get("ssh_private", ''),
                ssl_title=result_json.get("ssl_title", ''),
                ssl_filename=result_json.get("ssh_title", ''),
                other=result_json.get("other", ''))
            new_service.save()
            new_service.allowed_users.add(user)
        except Exception as e:
            raise falcon.HTTPInternalServerError(
                title="Error while saving the item",
                description=e,
                href=settings.__docs__)
Esempio n. 6
0
    def on_post(self, req, res):
        try:
            # Parse token and get user id
            user_id = parse_token(req)['sub']
            # Get the user
            user = User.get(User.id == int(user_id))
        except Exception as e:
            logger.error("Can't verify user")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            raw_json = req.stream.read()
            logger.debug("Got incoming JSON data")
        except Exception as e:
            logger.error("Can't read incoming data stream")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            result_json = json.loads(raw_json.decode("utf-8"), encoding='utf-8')
            logger.debug(result_json)
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                                   'Malformed JSON',
                                   'Could not decode the request body. The '
                                   'JSON was incorrect.')

        try:
            new_service = Service.create(name=result_json.get("name"),
                                         item=result_json.get("item"),
                                         username=result_json.get("username", ''),
                                         password=result_json.get("password", ''),
                                         url=result_json.get("url", ''),
                                         port=result_json.get("port", 0),
                                         extra=result_json.get("extra", ''),
                                         ssh_title=result_json.get("ssh_title", ''),
                                         ssh_public=result_json.get("ssh_public", ''),
                                         ssh_private=result_json.get("ssh_private", ''),
                                         ssl_title=result_json.get("ssl_title", ''),
                                         ssl_filename=result_json.get("ssh_title", ''),
                                         other=result_json.get("other", ''))
            new_service.save()
            new_service.allowed_users.add(user)
        except Exception as e:
            raise falcon.HTTPInternalServerError(title="Error while saving the item",
                                                 description=e,
                                                 href=settings.__docs__)
Esempio n. 7
0
    def process_response(self, req, res, resource):
        """Process the response before returning it to the client.

        In the reutrning reponse we change some values to be able to overcome
        the CORS protection and mask the origin server. The CORS interaction
        is protected by a check agains a regular expression to make sure the
        origin is a website-like URL.

        Warning:
            If you are really concerned about security, you can deactivate
            the CORS allowance by turning CORS_ACTIVE to `False` in your settings
            file. That will force the application to answer to the SITE_DOMAIN
            domain.

        Args:
            Server (string): Changes the server name sent to the browser in the
                response to avoid exposure of name and version of the same.
            Access-Control-Allow-Origin (string): Change the origin name to
                match the one that made the request. That way we can allow CORS
                anywhere.

        Raises:
            HTTP Error: An HTTP error in case the Origin header doesn't match
            the predefined regular expression.

        Returns:
            HTTP headers: A modified set of headers
        """

        origin_domain = req.get_header('Origin')
        logger.debug("Origin domain is: {}, type: {}".format(
            origin_domain, type(origin_domain)))
        origin_header = origin_domain if settings.CORS_ACTIVE and origin_domain else "*"
        logger.debug("Origin header is: {}, type: {}".format(
            origin_header, type(origin_header)))

        res.set_headers([
            ('Cache-Control',
             'no-store, must-revalidate, no-cache, max-age=0'),
            ('Content-Type', 'application/json; charset=utf-8'),
            ('Server', settings.SERVER_NAME),
            ('Access-Control-Allow-Credentials', 'true'),
            ('Access-Control-Allow-Origin', origin_header),
            ('Access-Control-Allow-Headers',
             'Origin, X-Requested-With, Content-Type, Accept, x-auth-user, x-auth-password, Authorization'
             ),
            ('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS, DELETE')
        ])
Esempio n. 8
0
 def on_put(self, req, res, id):
     try:
         # Parse token and get user id
         user_id = parse_token(req)['sub']
         # Get the user
         user = User.get(User.id == int(user_id))
     except Exception as e:
         logger.error("Can't verify user")
         raise falcon.HTTPBadRequest(title="Bad request",
                                     description=e,
                                     href=settings.__docs__)
     try:
         raw_json = req.stream.read()
         logger.debug("Got incoming JSON data")
     except Exception as e:
         logger.error("Can't read incoming data stream")
         raise falcon.HTTPBadRequest(title="Bad request",
                                     description=e,
                                     href=settings.__docs__)
     try:
         result_json = json.loads(raw_json.decode("utf-8"), encoding='utf-8')
     except ValueError:
         raise falcon.HTTPError(falcon.HTTP_400,
                                'Malformed JSON',
                                'Could not decode the request body. The '
                                'JSON was incorrect.')
     try:
         item = Item.get(Item.id == int(id))
         if user not in item.allowed_users:
             raise falcon.HTTPForbidden(title="Permission denied",
                                        description="You don't have access to this resource",
                                        href=settings.__docs__)
         item.name = result_json.get("name", item.name)
         item.description = result_json.get("description", item.description)
         item.category = result_json.get("category", item.category)
         item.tags = result_json.get("tags", item.tags)
         item.save()
         res.status = falcon.HTTP_200
         res.body = json.dumps({"message": "Item updated"})
     except Exception as e:
         print(e)
         error_msg = ("Unable to get the item. Please try again later.")
         raise falcon.HTTPServiceUnavailable(req.method + " failed",
                                             description=error_msg,
                                             retry_after=30,
                                             href=settings.__docs__)
Esempio n. 9
0
 def on_put(self, req, res, id):
     try:
         # Parse token and get user id
         user_id = parse_token(req)['sub']
         # Get the user
         user = User.get(User.id == int(user_id))
     except Exception as e:
         logger.error("Can't verify user")
         raise falcon.HTTPBadRequest(title="Bad request",
                                     description=e,
                                     href=settings.__docs__)
     try:
         raw_json = req.stream.read()
         logger.debug("Got incoming JSON data")
     except Exception as e:
         logger.error("Can't read incoming data stream")
         raise falcon.HTTPBadRequest(title="Bad request",
                                     description=e,
                                     href=settings.__docs__)
     try:
         result_json = json.loads(raw_json.decode("utf-8"), encoding='utf-8')
     except ValueError:
         raise falcon.HTTPError(falcon.HTTP_400,
                                'Malformed JSON',
                                'Could not decode the request body. The '
                                'JSON was incorrect.')
     try:
         item = Item.get(Item.id == int(id))
         if user not in item.allowed_users:
             raise falcon.HTTPForbidden(title="Permission denied",
                                        description="You don't have access to this resource",
                                        href=settings.__docs__)
         item.name = result_json.get("name", item.name)
         item.description = result_json.get("description", item.description)
         item.category = result_json.get("category", item.category)
         item.tags = result_json.get("tags", item.tags)
         item.save()
         res.status = falcon.HTTP_200
         res.body = json.dumps({"message": "Item updated"})
     except Exception as e:
         print(e)
         error_msg = ("Unable to get the item. Please try again later.")
         raise falcon.HTTPServiceUnavailable(req.method + " failed",
                                             description=error_msg,
                                             retry_after=30,
                                             href=settings.__docs__)
Esempio n. 10
0
File: headers.py Progetto: gnef/sikr
    def process_response(self, req, res, resource):

        """Process the response before returning it to the client.

        In the reutrning reponse we change some values to be able to overcome
        the CORS protection and mask the origin server. The CORS interaction
        is protected by a check agains a regular expression to make sure the
        origin is a website-like URL.

        Warning:
            If you are really concerned about security, you can deactivate
            the CORS allowance by turning CORS_ACTIVE to `False` in your settings
            file. That will force the application to answer to the SITE_DOMAIN
            domain.

        Args:
            Server (string): Changes the server name sent to the browser in the
                response to avoid exposure of name and version of the same.
            Access-Control-Allow-Origin (string): Change the origin name to
                match the one that made the request. That way we can allow CORS
                anywhere.

        Raises:
            HTTP Error: An HTTP error in case the Origin header doesn't match
            the predefined regular expression.

        Returns:
            HTTP headers: A modified set of headers
        """

        origin_domain = req.get_header('Origin')
        logger.debug("Origin domain is: {}, type: {}".format(origin_domain, type(origin_domain)))
        origin_header = origin_domain if settings.CORS_ACTIVE and origin_domain else "*"
        logger.debug("Origin header is: {}, type: {}".format(origin_header, type(origin_header)))

        res.set_headers([
            ('Cache-Control', 'no-store, must-revalidate, no-cache, max-age=0'),
            ('Content-Type', 'application/json; charset=utf-8'),
            ('Server', settings.SERVER_NAME),
            ('Access-Control-Allow-Credentials', 'true'),
            ('Access-Control-Allow-Origin', origin_header),
            ('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, x-auth-user, x-auth-password, Authorization'),
            ('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS, DELETE')
        ])
Esempio n. 11
0
 def on_get(self, req, res, id):
     user_id = parse_token(req)['sub']
     try:
         user = User.get(User.id == int(user_id))
         item = Item.get(Item.id == int(id))
         if user not in item.allowed_users:
             raise falcon.HTTPForbidden(title="Permission denied",
                                        description="You don't have access to this resource",
                                        href=settings.__docs__)
         res.status = falcon.HTTP_200
         res.body = json.dumps(item)
         logger.debug("Items request succesful")
     except Exception as e:
         print(e)
         error_msg = ("Unable to get the item. Please try again later.")
         raise falcon.HTTPServiceUnavailable(req.method + " failed",
                                             description=error_msg,
                                             retry_after=30,
                                             href=settings.__docs__)
Esempio n. 12
0
    def on_post(self, req, res):

        """Save a new item
        """
        try:
            # Parse token and get user id
            user_id = parse_token(req)['sub']
            # Get the user
            user = User.get(User.id == int(user_id))
        except Exception as e:
            logger.error("Can't verify user")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            raw_json = req.stream.read()
            logger.debug("Got incoming JSON data")
        except Exception as e:
            logger.error("Can't read incoming data stream")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            result_json = json.loads(raw_json.decode("utf-8"), encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(falcon.HTTP_400,
                                   'Malformed JSON',
                                   'Could not decode the request body. The '
                                   'JSON was incorrect.')

        try:
            new_item = Item.create(name=result_json.get('name'),
                                   description=result_json.get("description", ''),
                                   category=result_json.get("category"),
                                   tags=result_json.get("tags", ''))
            new_item.save()
            new_item.allowed_users.add(user)
        except Exception as e:
            raise falcon.HTTPInternalServerError(title="Error while saving the item",
                                                 description=e,
                                                 href=settings.__docs__)
Esempio n. 13
0
 def on_get(self, req, res, id):
     user_id = parse_token(req)['sub']
     try:
         user = User.get(User.id == int(user_id))
         group = Category.get(Category.id == int(id))
         if user not in group.allowed_users:
             raise falcon.HTTPForbidden(title="Permission denied",
                                        description="You don't have access to this resource",
                                        href=settings.__docs__)
         res.status = falcon.HTTP_200
         res.body = json.dumps(group)
         logger.debug("Items request succesful")
     except Exception as e:
         print(e)
         error_msg = ("Unable to get the group. Please try again later.")
         raise falcon.HTTPServiceUnavailable(req.method + " failed",
                                             description=error_msg,
                                             retry_after=30,
                                             href=settings.__docs__)
Esempio n. 14
0
    def on_get(self, req, res):

        """Create Twitter JWT token
        """
        request_token_url = 'https://api.twitter.com/oauth/request_token'
        access_token_url = 'https://api.twitter.com/oauth/access_token'
        authenticate_url = 'https://api.twitter.com/oauth/authenticate'

        if req.get_param('oauth_token') and req.get_param('oauth_verifier'):
            auth = OAuth1(settings.TWITTER_KEY,
                          client_secret=settings.TWITTER_SECRET,
                          resource_owner_key=req.get_param('oauth_token'),
                          verifier=req.get_param('oauth_verifier'))
            logger.debug("Twitter OAuth: Got auth session.")
            r = requests.post(access_token_url, auth=auth)
            profile = dict(parse_qsl(r.text))
            logger.debug("Twitter OAuth: User profile retrieved")

            try:
                user = User.select().where(User.twitter == profile['user_id'] |
                                           User.username == profile['screen_name']).get()
            except:
                user = User.create(twitter=profile['user_id'],
                                   username=profile['screen_name'])
                user.save()

            token = utils.create_jwt_token(user)
            res.body = json.dumps({"token": token})
            res.status = falcon.HTTP_200
        else:
            oauth = OAuth1(settings.TWITTER_KEY,
                           client_secret=settings.TWITTER_SECRET,
                           callback_uri=settings.TWITTER_CALLBACK_URI)
            logger.debug("Twitter OAuth: Got auth session.")
            r = requests.post(request_token_url, auth=oauth)
            oauth_token = dict(parse_qsl(r.text))
            logger.debug("Twitter OAuth: User profile retrieved")
            qs = urlencode(dict(oauth_token=oauth_token['oauth_token']))

            # Falcon doesn't support redirects, so we have to fake it
            # this implementation has been taken from werkzeug
            final_url = authenticate_url + '?' + qs
            res.body = (
                '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
                '<title>Redirecting...</title>\n'
                '<h1>Redirecting...</h1>\n'
                '<p>You should be redirected automatically to target URL: '
                '<a href="{0}">{0}</a>.  If not click the link.'.format(final_url)
            )
            res.location = final_url
            res.status = falcon.HTTP_301
Esempio n. 15
0
    def on_get(self, req, res):
        """
        """
        # Parse token and get user id
        user_id = parse_token(req)['sub']
        # See if we have to filter by item
        filter_item = req.get_param("item", required=False)

        try:
            # Get the user
            user = User.get(User.id == int(user_id))
            if filter_item:
                services = list(user.allowed_services
                                    .select(Service.id, Service.name,
                                            Service.username, Service.password,
                                            Service.url, Service.port, Service.extra,
                                            Service.ssh_title, Service.ssh_public,
                                            Service.ssh_private, Service.ssl_title,
                                            Service.ssl_filename, Service.other)
                                    .where(Service.item == int(filter_item))
                                    .dicts())
                logger.debug("Got services filtered by item")
            else:
                services = list(user.allowed_services
                                    .select(Service.id, Service.name,
                                            Service.username, Service.password,
                                            Service.url, Service.port, Service.extra,
                                            Service.ssh_title, Service.ssh_public,
                                            Service.ssh_private, Service.ssl_title,
                                            Service.ssl_filename, Service.other)
                                    .dicts())
                logger.debug("Got all the items")
            res.status = falcon.HTTP_200
            res.body = json.dumps(services)
        except Exception as e:
            logger.error(e)
            error_msg = ("Unable to get the services. Please try again later")
            raise falcon.HTTPServiceUnavailable(title=req.method + " failed",
                                                description=error_msg,
                                                retry_after=30,
                                                href=settings.__docs__)
Esempio n. 16
0
    def on_get(self, req, res):
        """Create Twitter JWT token
        """
        request_token_url = 'https://api.twitter.com/oauth/request_token'
        access_token_url = 'https://api.twitter.com/oauth/access_token'
        authenticate_url = 'https://api.twitter.com/oauth/authenticate'

        if req.get_param('oauth_token') and req.get_param('oauth_verifier'):
            auth = OAuth1(settings.TWITTER_KEY,
                          client_secret=settings.TWITTER_SECRET,
                          resource_owner_key=req.get_param('oauth_token'),
                          verifier=req.get_param('oauth_verifier'))
            logger.debug("Twitter OAuth: Got auth session.")
            r = requests.post(access_token_url, auth=auth)
            profile = dict(parse_qsl(r.text))
            logger.debug("Twitter OAuth: User profile retrieved")

            try:
                user = User.select().where(
                    User.twitter == profile['user_id']
                    | User.username == profile['screen_name']).get()
            except:
                user = User.create(twitter=profile['user_id'],
                                   username=profile['screen_name'])
                user.save()

            token = utils.create_jwt_token(user)
            res.body = json.dumps({"token": token})
            res.status = falcon.HTTP_200
        else:
            oauth = OAuth1(settings.TWITTER_KEY,
                           client_secret=settings.TWITTER_SECRET,
                           callback_uri=settings.TWITTER_CALLBACK_URI)
            logger.debug("Twitter OAuth: Got auth session.")
            r = requests.post(request_token_url, auth=oauth)
            oauth_token = dict(parse_qsl(r.text))
            logger.debug("Twitter OAuth: User profile retrieved")
            qs = urlencode(dict(oauth_token=oauth_token['oauth_token']))

            # Falcon doesn't support redirects, so we have to fake it
            # this implementation has been taken from werkzeug
            final_url = authenticate_url + '?' + qs
            res.body = (
                '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
                '<title>Redirecting...</title>\n'
                '<h1>Redirecting...</h1>\n'
                '<p>You should be redirected automatically to target URL: '
                '<a href="{0}">{0}</a>.  If not click the link.'.format(
                    final_url))
            res.location = final_url
            res.status = falcon.HTTP_301
Esempio n. 17
0
def login_required(req, res, resource, params):

    """Check the token to validate login state
    Check the JWT token sent by the frontend to see if the following conditions
    are NOT met:
        - Issuer host doesn't match the one specified in the settings file
        - Expiry timestamp is lower than the current timestamp
        - Issued timestamp is lower than the current timestamp minus SESSION_EXPIRES
    :returns: Redirect to the LOGIN_URL or HTTP 200
    """
    if req.auth:
        logger.debug("The user has a token in the header")
        payload = utils.parse_token(req)
        current_time = datetime.datetime.now()
        issue_time = current_time - datetime.timedelta(hours=settings.SESSION_EXPIRES)
        if payload['iss'] != settings.SITE_DOMAIN or \
           payload['exp'] <= int(current_time.timestamp()) or \
           payload['iat'] <= int(issue_time.timestamp()):

            logger.debug("JWT token expired or malformed")
            raise falcon.HTTPError(falcon.HTTP_401, title="Credentials expired",
                                   description="Your crendentials have expired. Please login again.")

        else:
            res.status = falcon.HTTP_200
    else:
        logger.debug("No JWT token found")
        raise falcon.HTTPError(falcon.HTTP_401, title="Credentials not found",
                               description="You don't have the credentials to access this resource")
Esempio n. 18
0
def login_required(req, res, resource, params):
    """Check the token to validate login state
    Check the JWT token sent by the frontend to see if the following conditions
    are NOT met:
        - Issuer host doesn't match the one specified in the settings file
        - Expiry timestamp is lower than the current timestamp
        - Issued timestamp is lower than the current timestamp minus SESSION_EXPIRES
    :returns: Redirect to the LOGIN_URL or HTTP 200
    """
    if req.auth:
        logger.debug("The user has a token in the header")
        payload = utils.parse_token(req)
        current_time = datetime.datetime.now()
        issue_time = current_time - datetime.timedelta(
            hours=settings.SESSION_EXPIRES)
        if payload['iss'] != settings.SITE_DOMAIN or \
           payload['exp'] <= int(current_time.timestamp()) or \
           payload['iat'] <= int(issue_time.timestamp()):

            logger.debug("JWT token expired or malformed")
            raise falcon.HTTPError(
                falcon.HTTP_401,
                title="Credentials expired",
                description=
                "Your crendentials have expired. Please login again.")

        else:
            res.status = falcon.HTTP_200
    else:
        logger.debug("No JWT token found")
        raise falcon.HTTPError(
            falcon.HTTP_401,
            title="Credentials not found",
            description="You don't have the credentials to access this resource"
        )
Esempio n. 19
0
    def on_post(self, req, res):
        try:
            # Parse token and get user id
            user_id = parse_token(req)['sub']
            # Get the user
            user = User.get(User.id == int(user_id))
        except Exception as e:
            logger.error("Can't verify user")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            raw_json = req.stream.read()
            logger.debug("Got incoming JSON data")
        except Exception as e:
            logger.error("Can't read incoming data stream")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            result_json = json.loads(raw_json.decode("utf-8"),
                                     encoding='utf-8')
        except ValueError:
            raise falcon.HTTPError(
                falcon.HTTP_400, 'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')

        try:
            new_category = Category.create(name=result_json['name'] or '')
            new_category.save()
            new_category.allowed_users.add(user)
        except Exception as e:
            raise falcon.HTTPInternalServerError(
                title="Error while saving the group",
                description=e,
                href=settings.__docs__)
Esempio n. 20
0
    def on_get(self, req, res):
        """
        """
        # Parse token and get user id
        user_id = parse_token(req)['sub']
        # See if we have to filter by item
        filter_item = req.get_param("item", required=False)

        try:
            # Get the user
            user = User.get(User.id == int(user_id))
            if filter_item:
                services = list(
                    user.allowed_services.select(
                        Service.id, Service.name, Service.username,
                        Service.password, Service.url, Service.port,
                        Service.extra, Service.ssh_title, Service.ssh_public,
                        Service.ssh_private, Service.ssl_title,
                        Service.ssl_filename, Service.other).where(
                            Service.item == int(filter_item)).dicts())
                logger.debug("Got services filtered by item")
            else:
                services = list(
                    user.allowed_services.select(
                        Service.id, Service.name, Service.username,
                        Service.password, Service.url, Service.port,
                        Service.extra, Service.ssh_title, Service.ssh_public,
                        Service.ssh_private, Service.ssl_title,
                        Service.ssl_filename, Service.other).dicts())
                logger.debug("Got all the items")
            res.status = falcon.HTTP_200
            res.body = json.dumps(services)
        except Exception as e:
            logger.error(e)
            error_msg = ("Unable to get the services. Please try again later")
            raise falcon.HTTPServiceUnavailable(title=req.method + " failed",
                                                description=error_msg,
                                                retry_after=30,
                                                href=settings.__docs__)
Esempio n. 21
0
    def on_get(self, req, res):
        """Get the items that belong to that user.

        This method contains two behaviours, one returns
        Handle the GET request, returning a list of the items that the user
        has access to.

        First we create an empty dictionary and query the database to get
        all the item objects. After that, we iterate over the objects to
        populate the dictionary. In the end we return a 200 code to the browser
        and return the results dictionary wrapped in a list like the REsT
        standard says.
        """
        payload = {}
        # Parse token and get user id
        user_id = parse_token(req)['sub']

        try:
            # Get the user
            user = User.get(User.id == int(user_id))
            # See if we have to filter by category
            filter_category = req.get_param("category", required=False)
            if filter_category:
                # Get the category
                category = (Category.select(Category.name, Category.id)
                                  .where(Category.id == int(filter_category))
                                  .get())
                payload["category_name"] = str(category.name)
                payload["category_id"] = int(category.id)
                items = list(user.allowed_items
                                 .select(Item.name, Item.description, Item.id)
                                 .where(Item.category == int(filter_category))
                                 .dicts())
                logger.debug("Got items filtered by category and user")
            else:
                payload["category_name"] = "All"
                items = list(user.allowed_items
                             .select(Item.name, Item.description, Item.id)
                             .dicts())
                logger.debug("Got all items")
            for item in items:
                services = list(user.allowed_services
                                    .select(Service.id, Service.name)
                                    .where(Service.item == item["id"])
                                    .dicts())
                item["services"] = services
            payload["items"] = items
            res.status = falcon.HTTP_200
            res.body = json.dumps(payload)
            logger.debug("Items request succesful")
        except Exception as e:
            print(e)
            logger.error(e)
            error_msg = ("Unable to get the items. Please try again later")
            raise falcon.HTTPServiceUnavailable(title=req.method + " failed",
                                                description=error_msg,
                                                retry_after=30,
                                                href=settings.__docs__)
Esempio n. 22
0
    def on_get(self, req, res):
        """Get the items that belong to that user.

        This method contains two behaviours, one returns
        Handle the GET request, returning a list of the items that the user
        has access to.

        First we create an empty dictionary and query the database to get
        all the item objects. After that, we iterate over the objects to
        populate the dictionary. In the end we return a 200 code to the browser
        and return the results dictionary wrapped in a list like the REsT
        standard says.
        """
        payload = {}
        # Parse token and get user id
        user_id = parse_token(req)['sub']

        try:
            # Get the user
            user = User.get(User.id == int(user_id))
            # See if we have to filter by category
            filter_category = req.get_param("category", required=False)
            if filter_category:
                # Get the category
                category = (Category.select(Category.name, Category.id)
                                  .where(Category.id == int(filter_category))
                                  .get())
                payload["category_name"] = str(category.name)
                payload["category_id"] = int(category.id)
                items = list(user.allowed_items
                                 .select(Item.name, Item.description, Item.id)
                                 .where(Item.category == int(filter_category))
                                 .dicts())
                logger.debug("Got items filtered by category and user")
            else:
                payload["category_name"] = "All"
                items = list(user.allowed_items
                             .select(Item.name, Item.description, Item.id)
                             .dicts())
                logger.debug("Got all items")
            for item in items:
                services = list(user.allowed_services
                                    .select(Service.id, Service.name)
                                    .where(Service.item == item["id"])
                                    .dicts())
                item["services"] = services
            payload["items"] = items
            res.status = falcon.HTTP_200
            res.body = json.dumps(payload)
            logger.debug("Items request succesful")
        except Exception as e:
            print(e)
            logger.error(e)
            error_msg = ("Unable to get the items. Please try again later")
            raise falcon.HTTPServiceUnavailable(title=req.method + " failed",
                                                description=error_msg,
                                                retry_after=30,
                                                href=settings.__docs__)
Esempio n. 23
0
    def on_post(self, req, res):
        try:
            # Parse token and get user id
            user_id = parse_token(req)['sub']
            # Get the user
            user = User.get(User.id == int(user_id))
        except Exception as e:
            logger.error("Can't verify user")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            raw_json = req.stream.read()
            logger.debug("Got incoming JSON data")
        except Exception as e:
            logger.error("Can't read incoming data stream")
            raise falcon.HTTPBadRequest(title="Bad request",
                                        description=e,
                                        href=settings.__docs__)

        try:
            result_json = json.loads(raw_json.decode("utf-8"),
                                     encoding='utf-8')
            logger.debug(result_json)
        except ValueError:
            raise falcon.HTTPError(
                falcon.HTTP_400, 'Malformed JSON',
                'Could not decode the request body. The '
                'JSON was incorrect.')

        try:
            new_share = ShareToken(user=user,
                                   token=generate_token(),
                                   resource=int(result_json.get()))
        except:
            pass
Esempio n. 24
0
    def process_request(self, req, res):
        """Process the request before entering in the API

        Before we process anything in the API, we reset the Origin header to
        match the address from the request.

        Args:
            Access-Control-Allow-Origin: Change the origin to the URL that made
                the request.

        Raises:
            HTTP Error: An HTTP error in case the Origin header doesn't match
                        the predefined regular expression.

        Return:
            HTTP headers: A modified set of headers.

        """

        origin_domain = req.get_header('Origin')
        logger.debug("Origin domain is: {}, type: {}".format(
            origin_domain, type(origin_domain)))
        origin_header = origin_domain if settings.CORS_ACTIVE and origin_domain else "*"
        logger.debug("Origin header is: {}, type: {}".format(
            origin_header, type(origin_header)))

        res.set_headers([
            ('Cache-Control',
             'no-store, must-revalidate, no-cache, max-age=0'),
            ('Content-Type', 'application/json; charset=utf-8'),
            ('Access-Control-Allow-Credentials', 'true'),
            ('Access-Control-Allow-Origin', origin_header),
            ('Access-Control-Allow-Headers',
             'Origin, X-Requested-With, Content-Type, Accept, x-auth-user, x-auth-password, Authorization'
             ),
            ('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS, DELETE')
        ])
Esempio n. 25
0
from sikre import settings
from sikre.utils.logs import logger

try:
    db_conf = settings.DATABASE
    # Set the defaults in case something happens
    db_user = settings.DATABASE.get("USER", 'root')
    db_host = settings.DATABASE.get("HOST", 'localhost')
    db_postgres_port = settings.DATABASE.get("PORT", '5432')
    db_mysql_port = settings.DATABASE.get("PORT", '3306')

    if db_conf['ENGINE'] == 'postgres':
        db = orm.PostgresqlDatabase(db_conf['NAME'], user=db_user,
                                    password=db_conf['PASSWORD'],
                                    host=db_host, port=db_postgres_port)
        logger.debug("Connected to the PostgreSQL database")

    elif db_conf['ENGINE'] == 'mysql':
        db = orm.MySQLDatabase(db_conf['NAME'], user=db_user,
                               password=db_conf['PASSWORD'],
                               host=db_host, port=db_mysql_port)
        logger.debug("Connected to the MySQL database")

    else:
        db = orm.SqliteDatabase(settings.DATABASE['NAME'])
        logger.debug("Connected to the SQLite database")
except Exception as e:
    message = ("Couldn't connect to the database. Please check that your "
               "configuration is okay and the database exists.")
    logger.critical(message)
    # This will leave the message in the WSGI logfile in case the other logger
Esempio n. 26
0
    def on_post(self, req, res):
        access_token_url = 'https://accounts.google.com/o/oauth2/token'
        people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect'

        # Read the incoming data
        stream = req.stream.read()
        data = json.loads(stream.decode('utf-8'))
        logger.debug("Google OAuth: Incoming data read successfully")

        # See if the user has a share token
        share_token = req.get_param("share_token", required=False)
        logger.debug("Google OAuth: User carries a share token")

        payload = {
            'client_id': data['clientId'],
            'redirect_uri': data['redirectUri'],
            'client_secret': settings.GOOGLEPLUS_SECRET,
            'code': data['code'],
            'grant_type': 'authorization_code'
        }
        logger.debug("Google OAuth: Built the code response correctly")

        # Step 1. Exchange authorization code for access token.
        r = requests.post(access_token_url, data=payload)
        token = json.loads(r.text)
        headers = {'Authorization': 'Bearer {0}'.format(token['access_token'])}
        logger.debug("Google OAuth: Auth code exchange for token success")

        # Step 2. Retrieve information about the current user.
        r = requests.get(people_api_url, headers=headers)
        profile = json.loads(r.text)
        logger.debug("Google OAuth: Retrieve user information success")

        try:
            user = User.select().where(User.google == profile['sub']).get()
            if user:
                logger.debug("Google OAuth: Account {0} already exists".format(profile["sub"]))
        except User.DoesNotExist:
            logger.debug("Google OAuth: User does not exist")
            user = User.create(google=profile['sub'], username=profile['name'], email=profile['email'])
            user.save()
            logger.debug("Google OAuth: Created user {0}".format(profile["name"]))

        token = utils.create_jwt_token(user)

        # if share_token:
        #     try:
        #         token = ShareToken.get(token=share_token)
        #         if token.is_valid():
        #             if token.resource == 0:

        #     except:
        #         logger.error("Token does not exist")


        res.body = json.dumps({"token": token})
        res.status = falcon.HTTP_200
        return
Esempio n. 27
0
File: app.py Progetto: gnef/sikr
            handle_404.WrongURL()
        ]
    )

    # URLs
    api_version = '/' + settings.DEFAULT_API
    api.add_route(api_version, main.APIInfo())

    # Social Auth
    api.add_route(api_version + '/auth/facebook/login', facebook.FacebookAuth())
    api.add_route(api_version + '/auth/google/login', google.GoogleAuth())
    api.add_route(api_version + '/auth/twitter/login', twitter.TwitterAuth())
    api.add_route(api_version + '/auth/github/login', github.GithubAuth())
    api.add_route(api_version + '/auth/linkedin/login', linkedin.LinkedinAuth())

    # Content
    api.add_route(api_version + '/categories', categories.Categories())
    api.add_route(api_version + '/categories/{id}', categories.DetailCategory())
    api.add_route(api_version + '/items', items.Items())
    api.add_route(api_version + '/items/{id}', items.DetailItem())
    api.add_route(api_version + '/services', services.Services())
    api.add_route(api_version + '/services/{id}', services.DetailService())

    # Sharing
    api.add_route(api_version + '/share', sharing.Share())

    logger.debug("API service started")

    if settings.DEBUG:
        api.add_route('/test_api', tests.TestResource())
Esempio n. 28
0
    def on_post(self, req, res):
        """Create the JWT token for the user
        """
        access_token_url = 'https://graph.facebook.com/oauth/access_token'
        graph_api_url = 'https://graph.facebook.com/me'

        # Read the incoming data
        stream = req.stream.read()
        data = json.loads(stream.decode('utf-8'))
        logger.debug("Facebook OAuth: Incoming data read successfully")

        params = {
            'client_id': data['clientId'],
            'redirect_uri': data['redirectUri'] + '/',
            'client_secret': settings.FACEBOOK_SECRET,
            'code': data['code']
        }
        logger.debug("Facebook OAuth: Built the code response correctly")

        # Step 1. Exchange authorization code for access token.
        r = requests.get(access_token_url, params=params)
        access_token = dict(parse_qsl(r.text))
        logger.debug("Facebook OAuth: Auth code exchange for token success")

        # Step 2. Retrieve information about the current user.
        r = requests.get(graph_api_url, params=access_token)
        profile = json.loads(r.text)
        logger.debug("Facebook OAuth: Retrieve user information success")

        # Step 3. (optional) Link accounts.
        if req.auth:
            payload = utils.parse_token(req)
            try:
                user = User.select().where(
                    (User.facebook == profile['id'])
                    | (User.id == payload['sub'])
                    | (User.email == profile['email'])).get()
                # Set the facebook code again. This is a failsafe.
                user.facebook = profile['id']
                user.save()
                logger.debug(
                    "Facebook OAuth: Account {0} already exists".format(
                        profile["id"]))
            except User.DoesNotExist:
                logger.debug("Facebook OAuth: User does not exist")
                user = User.create(facebook=profile['id'],
                                   username=profile['name'],
                                   email=profile["email"])
                user.save()
                logger.debug("Facebook OAuth: Created user {0}".format(
                    profile["name"]))
        else:
            try:
                user = User.select().where((User.facebook == profile['id']) | (
                    User.email == profile['email'])).get()
                # Set the github code again. This is a failsafe.
                user.facebook = profile['id']
                user.save()
            except User.DoesNotExist:
                logger.debug("Facebook OAuth: User does not exist")
                user = User.create(facebook=profile['id'],
                                   username=profile['name'],
                                   email=profile["email"])
                user.save()
                logger.debug("Facebook OAuth: Created user {0}".format(
                    profile["name"]))
        token = utils.create_jwt_token(user)
        res.body = json.dumps({"token": token})
        res.status = falcon.HTTP_200
Esempio n. 29
0
from sikre import settings
from sikre.utils.logs import logger

try:
    db_conf = settings.DATABASE
    # Set the defaults in case something happens
    db_user = settings.DATABASE.get("USER", 'root')
    db_host = settings.DATABASE.get("HOST", 'localhost')
    db_postgres_port = settings.DATABASE.get("PORT", '5432')
    db_mysql_port = settings.DATABASE.get("PORT", '3306')

    if db_conf['ENGINE'] == 'postgres':
        db = orm.PostgresqlDatabase(db_conf['NAME'], user=db_user,
                                    password=db_conf['PASSWORD'],
                                    host=db_host, port=db_postgres_port)
        logger.debug("Connected to the PostgreSQL database")

    elif db_conf['ENGINE'] == 'mysql':
        db = orm.MySQLDatabase(db_conf['NAME'], user=db_user,
                               password=db_conf['PASSWORD'],
                               host=db_host, port=db_mysql_port)
        logger.debug("Connected to the MySQL database")

    else:
        db = orm.SqliteDatabase(settings.DATABASE['NAME'])
        logger.debug("Connected to the SQLite database")
except Exception as e:
    message = ("Couldn't connect to the database. Please check that your "
               "configuration is okay and the database exists.")
    logger.critical(message)
    # This will leave the message in the WSGI logfile in case the other logger
Esempio n. 30
0
    def on_post(self, req, res):
        access_token_url = 'https://accounts.google.com/o/oauth2/token'
        people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect'

        # Read the incoming data
        stream = req.stream.read()
        data = json.loads(stream.decode('utf-8'))
        logger.debug("Google OAuth: Incoming data read successfully")

        # See if the user has a share token
        share_token = req.get_param("share_token", required=False)
        logger.debug("Google OAuth: User carries a share token")

        payload = {
            'client_id': data['clientId'],
            'redirect_uri': data['redirectUri'],
            'client_secret': settings.GOOGLEPLUS_SECRET,
            'code': data['code'],
            'grant_type': 'authorization_code'
        }
        logger.debug("Google OAuth: Built the code response correctly")

        # Step 1. Exchange authorization code for access token.
        r = requests.post(access_token_url, data=payload)
        token = json.loads(r.text)
        headers = {'Authorization': 'Bearer {0}'.format(token['access_token'])}
        logger.debug("Google OAuth: Auth code exchange for token success")

        # Step 2. Retrieve information about the current user.
        r = requests.get(people_api_url, headers=headers)
        profile = json.loads(r.text)
        logger.debug("Google OAuth: Retrieve user information success")

        try:
            user = User.select().where(User.google == profile['sub']).get()
            if user:
                logger.debug("Google OAuth: Account {0} already exists".format(profile["sub"]))
        except User.DoesNotExist:
            logger.debug("Google OAuth: User does not exist")
            user = User.create(google=profile['sub'], username=profile['name'], email=profile['email'])
            user.save()
            logger.debug("Google OAuth: Created user {0}".format(profile["name"]))

        token = utils.create_jwt_token(user)

        # if share_token:
        #     try:
        #         token = ShareToken.get(token=share_token)
        #         if token.is_valid():
        #             if token.resource == 0:

        #     except:
        #         logger.error("Token does not exist")


        res.body = json.dumps({"token": token})
        res.status = falcon.HTTP_200
        return
Esempio n. 31
0
    def on_post(self, req, res):

        """Create the JWT token for the user
        """
        access_token_url = 'https://graph.facebook.com/oauth/access_token'
        graph_api_url = 'https://graph.facebook.com/me'

        # Read the incoming data
        stream = req.stream.read()
        data = json.loads(stream.decode('utf-8'))
        logger.debug("Facebook OAuth: Incoming data read successfully")

        params = {
            'client_id': data['clientId'],
            'redirect_uri': data['redirectUri'] + '/',
            'client_secret': settings.FACEBOOK_SECRET,
            'code': data['code']
        }
        logger.debug("Facebook OAuth: Built the code response correctly")

        # Step 1. Exchange authorization code for access token.
        r = requests.get(access_token_url, params=params)
        access_token = dict(parse_qsl(r.text))
        logger.debug("Facebook OAuth: Auth code exchange for token success")

        # Step 2. Retrieve information about the current user.
        r = requests.get(graph_api_url, params=access_token)
        profile = json.loads(r.text)
        logger.debug("Facebook OAuth: Retrieve user information success")

        # Step 3. (optional) Link accounts.
        if req.auth:
            payload = utils.parse_token(req)
            try:
                user = User.select().where(
                    (User.facebook == profile['id']) |
                    (User.id == payload['sub']) |
                    (User.email == profile['email'])
                ).get()
                # Set the facebook code again. This is a failsafe.
                user.facebook = profile['id']
                user.save()
                logger.debug("Facebook OAuth: Account {0} already exists".format(profile["id"]))
            except User.DoesNotExist:
                logger.debug("Facebook OAuth: User does not exist")
                user = User.create(facebook=profile['id'], username=profile['name'], email=profile["email"])
                user.save()
                logger.debug("Facebook OAuth: Created user {0}".format(profile["name"]))
        else:
            try:
                user = User.select().where(
                    (User.facebook == profile['id']) |
                    (User.email == profile['email'])
                ).get()
                # Set the github code again. This is a failsafe.
                user.facebook = profile['id']
                user.save()
            except User.DoesNotExist:
                logger.debug("Facebook OAuth: User does not exist")
                user = User.create(facebook=profile['id'], username=profile['name'], email=profile["email"])
                user.save()
                logger.debug("Facebook OAuth: Created user {0}".format(profile["name"]))
        token = utils.create_jwt_token(user)
        res.body = json.dumps({"token": token})
        res.status = falcon.HTTP_200
Esempio n. 32
0
    # URLs
    api_version = '/' + settings.DEFAULT_API
    api.add_route(api_version, main.APIInfo())

    # Social Auth
    api.add_route(api_version + '/auth/facebook/login',
                  facebook.FacebookAuth())
    api.add_route(api_version + '/auth/google/login', google.GoogleAuth())
    api.add_route(api_version + '/auth/twitter/login', twitter.TwitterAuth())
    api.add_route(api_version + '/auth/github/login', github.GithubAuth())
    api.add_route(api_version + '/auth/linkedin/login',
                  linkedin.LinkedinAuth())

    # Content
    api.add_route(api_version + '/categories', categories.Categories())
    api.add_route(api_version + '/categories/{id}',
                  categories.DetailCategory())
    api.add_route(api_version + '/items', items.Items())
    api.add_route(api_version + '/items/{id}', items.DetailItem())
    api.add_route(api_version + '/services', services.Services())
    api.add_route(api_version + '/services/{id}', services.DetailService())

    # Sharing
    api.add_route(api_version + '/share', sharing.Share())

    logger.debug("API service started")

    if settings.DEBUG:
        api.add_route('/test_api', tests.TestResource())