Skip to content
Snippets Groups Projects
db.py 2.36 KiB
Newer Older
Mark's avatar
Mark committed
from os import environ
from hydra_client import HydraAdmin
from flask_login import UserMixin
from graphqlclient import GraphQLClient
Mark's avatar
Mark committed
import urllib
Mark's avatar
Mark committed
import json
Mark's avatar
Mark committed

GRAPHQL_URL = environ['GRAPHQL_URL']
graphql_client = GraphQLClient(GRAPHQL_URL)

Mark's avatar
Mark committed

Mark's avatar
Mark committed
class User(UserMixin):
    def __init__(self, username):
        self.id = username
        self.username = username
        self.active = False
Mark's avatar
Mark committed
        try:
            self._load_remote_user_info()
        except urllib.error.HTTPError as error:
            raise BackendConnectionError(
                error.code,
                error.headers,
                ("Error during retrieval of userdata - " + error.reason))
Mark's avatar
Mark committed

    def _load_remote_user_info(self):
Mark's avatar
Mark committed
        """Loads userdata from remote GraphQL API"""
Mark's avatar
Mark committed
        querystring = '''{{
        getUser(username: "{0}"){{
            email,
            active
            }}}}'''.format(self.username)
Mark's avatar
Mark committed
        result = json.loads(graphql_client.execute(querystring))
Mark's avatar
Mark committed
        if "data" in result and result["data"]["getUser"] is not None:
Mark's avatar
Mark committed
            self.active = result["data"]["getUser"]["active"]
            self.email = result["data"]["getUser"]["email"]

    def _verify_password(self, password):
Mark's avatar
Mark committed
        """Verifies cleartext password

Mark's avatar
Mark committed
        Sends the cleartext `password` to the GraphQL API
Mark's avatar
Mark committed
        which verifies the password by hashing it and comparing it to a stored password
        hash.

        Args:
            password: cleartext password

        Returns:
            Boolean result of password verification
        """
Mark's avatar
Mark committed
        password = password.replace('"', '\\"')
Mark's avatar
Mark committed
        querystring = '''{{
        verifyPassword(
            username: "{0}",
            password: "{1}")
Mark's avatar
Mark committed
            }}'''.format(self.username, password)
Mark's avatar
Mark committed
        result = json.loads(graphql_client.execute(querystring))
Mark's avatar
Mark committed
        verified = False
        if "data" in result:
            verified = result["data"]["verifyPassword"]
        return verified

    def authenticate(self, password):
        return self.active and self._verify_password(password)
Mark's avatar
Mark committed

class BackendConnectionError(Exception):
    """Raised when requests to the backend server fail

    Attributes:
        code -- http response code
        headers -- http response headers
        reason -- reson for the error
    """
    def __init__(self, code, headers, reason):
        self.code = code
        self.headers = headers
        self.reason = reason