Esempio n. 1
0
 def user_is_registered(self, args, database, user, **kwargs):
     """
     Returns boolean `true` or `false` of whether the given target is
     registered on the server.
     """
     validate(args, ["target_user"])
     return bool(db.user_resolve(database, args["target_user"]))
Esempio n. 2
0
 def user_get(self, args, database, user, **kwargs):
     """
     Returns a user object for the given target.
     """
     validate(args, ["target_user"])
     return db.user_resolve(
         database, args["target_user"], return_false=False, externalize=True)
Esempio n. 3
0
def user_name_to_id(json):
    """
    Returns a string of the target_user's ID when it is
    part of the database: a non-existent user will return
    a boolean false.
    """
    return db.user_resolve(json["target_user"])
Esempio n. 4
0
 def is_admin(self, args, database, user, **kwargs):
     """
     Requires the argument `target_user`. Returns a boolean
     of whether that user is an admin.
     """
     validate(args, ["target_user"])
     user = db.user_resolve(
         database, args["target_user"], return_false=False)
     return user["is_admin"]
Esempio n. 5
0
 def check_auth(self, args, database, user, **kwargs):
     """
     Returns boolean `true` or `false` of whether the hash given
     is correct for the given user.
     """
     validate(args, ["target_user", "target_hash"])
     user = db.user_resolve(
         database, args["target_user"], return_false=False)
     return args["target_hash"].lower() == user["auth_hash"].lower()
Esempio n. 6
0
def user_get(json):
    """
    On success, returns an external user object for target_user (ID or name).
    If the user isn't in the system, returns false.
    """
    user = db.user_resolve(json["target_user"])
    if not user:
        return False
    return db.user_get(user)
Esempio n. 7
0
def is_admin(json):
    """
    Returns true or false whether target_user is a system
    administrator. Takes a username or user ID. Nonexistent
    users return false.
    """
    user = db.user_resolve(json["target_user"])
    if user:
        return db.user_is_admin(user)
    return False
Esempio n. 8
0
def run():
    # user anonymity is achieved in the laziest possible way: a literal user
    # named anonymous. may god have mercy on my soul.
    _c = sqlite3.connect(dbname)
    try:
        db.anon = db.user_resolve(_c, "anonymous")
        if not db.anon:
            db.anon = db.user_register(
                _c,
                "anonymous",  # this is the hash for "anon"
                "5430eeed859cad61d925097ec4f53246"
                "1ccf1ab6b9802b09a313be1478a4d614")
    finally:
        _c.close()
    cherrypy.quickstart(API(), "/api", API_CONFIG)
Esempio n. 9
0
    def handle(self):
        try:
            request = json.loads(str(self.rfile.read(), "utf8"))
            endpoint = request.get("method")

            if endpoint not in endpoints.endpoints:
                return self.reply(schema.error(2, "Invalid endpoint"))

            # check to make sure all the arguments for endpoint are provided
            elif any(
                [key not in request for key in endpoints.endpoints[endpoint]]):
                return self.reply(
                    schema.error(
                        3, "{} requires: {}".format(
                            endpoint,
                            ", ".join(endpoints.endpoints[endpoint]))))

            elif endpoint not in endpoints.authless:
                if not request.get("user"):
                    return self.reply(schema.error(4, "No username provided."))

                user = db.user_resolve(request["user"])
                request["user"] = user

                if not user:
                    return self.reply(schema.error(5, "User not registered"))

                elif endpoint != "check_auth" and not \
                     db.user_auth(user, request.get("auth_hash")):
                    return self.reply(schema.error(6, "Authorization failed."))

            # post_ids are always returned as integers, but for callers who
            # provide them as something else, try to convert them.
            if isinstance(request.get("post_id"), (float, str)):
                try:
                    request["post_id"] = int(request["post_id"])
                except Exception:
                    return schema.error(3, "Non-numeric post_id")

            # exception handling is now passed to the endpoints;
            # anything unhandled beyond here is a code 1
            self.reply(eval("endpoints." + endpoint)(request))

        except json.decoder.JSONDecodeError as E:
            return self.reply(schema.error(0, str(E)))

        except Exception as E:
            return self.reply(schema.error(1, str(E)))
Esempio n. 10
0
def create_usermap(connection, obj, index=False):
    """
    Creates a mapping of all the user_ids that occur in OBJ to
    their full user objects (names, profile info, etc). Can
    be a thread_index or a messages object from one.
    """
    user_set = {item["author"] for item in obj}
    if index:
        [user_set.add(item["last_author"]) for item in obj]
    return {
        user_id: db.user_resolve(connection,
                                 user_id,
                                 externalize=True,
                                 return_false=False)
        for user_id in user_set
    }
Esempio n. 11
0
 def user_map(self, args, database, user, **kwargs):
     """
     Returns an array with all registered user_ids, with the usermap
     object populated by their full objects. This method is _NEVER_
     neccesary when using other endpoints, as the usermap returned
     on those requests already contains all the information you will
     need. This endpoint is useful for statistic purposes only.
     """
     users = {
         user[0]
         for user in database.execute("SELECT user_id FROM users")
     }
     cherrypy.thread_data.usermap = {
         user: db.user_resolve(database,
                               user,
                               externalize=True,
                               return_false=False)
         for user in users
     }
     return list(users)
Esempio n. 12
0
    def wrapper(self, *args, **kwargs):
        response = None
        debug = app_config["debug"]
        try:
            connection = sqlite3.connect(dbname)
            # read in the body from the request to a string...
            if cherrypy.request.method == "POST":
                read_in = str(cherrypy.request.body.read(), "utf8")
                if not read_in:
                    # the body may be empty, not all methods require input
                    body = {}
                else:
                    body = json.loads(read_in)
                    if not isinstance(body, dict):
                        raise BBJParameterError("Non-JSONObject input")
                    # lowercase all of its top-level keys
                    body = {key.lower(): value for key, value in body.items()}
            else:
                body = {}

            username = cherrypy.request.headers.get("User")
            auth = cherrypy.request.headers.get("Auth")

            if (username and not auth) or (auth and not username):
                raise BBJParameterError(
                    "User or Auth was given without the other.")

            elif not username and not auth:
                user = db.anon

            else:
                user = db.user_resolve(connection, username)
                if not user:
                    raise BBJUserError("User %s is not registered" % username)

                elif auth.lower() != user["auth_hash"].lower():
                    raise BBJException(5,
                                       "Invalid authorization key for user.")

            # api_methods may choose to bind a usermap into the thread_data
            # which will send it off with the response
            cherrypy.thread_data.usermap = {}
            value = function(self, body, connection, user)
            response = schema.response(value, cherrypy.thread_data.usermap)

        except BBJException as e:
            response = e.schema

        except json.JSONDecodeError as e:
            response = schema.error(0, str(e))

        except Exception as e:
            error_id = uuid1().hex
            response = schema.error(
                1,
                "Internal server error: code {} {}".format(error_id, repr(e)))
            with open("logs/exceptions/" + error_id, "a") as log:
                traceback.print_tb(e.__traceback__, file=log)
                log.write(repr(e))
            print("logged code 1 exception " + error_id)

        finally:
            connection.close()
            return json.dumps(response)