Exemplo n.º 1
0
Arquivo: db.py Projeto: tildetown/bbj
def edit_handler(json, thread=None):
    try:
        target_id = json["post_id"]
        if not thread:
            thread = thread_load(json["thread_id"])
            if not thread:
                return False, schema.error(7,
                                           "Requested thread does not exist.")

        if target_id == 1:
            target = thread
        else:
            target = thread["replies"][index_reply(thread["replies"],
                                                   target_id)]

        if not user_is_admin(json["user"]):
            if json["user"] != target["author"]:
                return False, schema.error(
                    10, "non-admin attempt to edit another user's message")

            elif (time() - target["created"]) > 86400:
                return False, schema.error(
                    9, "message is too old to edit (24hr limit)")

        return True, target

    except IndexError:
        return False, schema.error(
            3, "post_id out of bounds for requested thread")
Exemplo n.º 2
0
Arquivo: db.py Projeto: tildetown/bbj
def user_authcheck(auth_hash):
    if not auth_hash:
        return False, schema.error(3, "auth_hash may not be empty")

    elif len(auth_hash) != 64:
        return False, schema.error(4, "Client error: invalid SHA-256 hash.")

    return True, True
Exemplo n.º 3
0
Arquivo: db.py Projeto: tildetown/bbj
def user_quipcheck(quip):
    if not quip:
        return True, True

    elif contains_nonspaces(quip):
        return False, schema.error(
            4, "Quip cannot contain whitespace chars besides spaces.")

    elif len(quip) > 120:
        return False, schema.error(4, "Quip is too long (max 120 chars)")

    return True, True
Exemplo n.º 4
0
Arquivo: db.py Projeto: tildetown/bbj
def user_namecheck(name):
    if not name:
        return False, schema.error(4, "Username may not be empty.")

    elif contains_nonspaces(name):
        return False, schema.error(
            4, "Username cannot contain whitespace chars besides spaces.")

    elif not name.strip():
        return False, schema.error(
            4, "Username must contain at least one non-space character")

    elif len(name) > 24:
        return False, schema.error(4, "Username is too long (max 24 chars)")

    return True, True
Exemplo n.º 5
0
Arquivo: db.py Projeto: tildetown/bbj
def user_biocheck(bio):
    if not bio:
        return True, True

    elif len(bio) > 4096:
        return False, schema.error(4, "Bio is too long (max 4096 chars)")

    return True, True
Exemplo n.º 6
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)))
Exemplo n.º 7
0
Arquivo: db.py Projeto: tildetown/bbj
def thread_reply(ID, author, body):
    thread = thread_load(ID)
    if not thread:
        return schema.error(7, "Requested thread does not exist.")

    thread["reply_count"] += 1
    thread["lastmod"] = time()

    if thread["replies"]:
        lastpost = thread["replies"][-1]["post_id"]
    else:
        lastpost = 1

    reply = schema.reply(lastpost + 1, author, body)
    thread["replies"].append(reply)
    thread_dump(ID, thread)
    return reply
Exemplo n.º 8
0
Arquivo: db.py Projeto: tildetown/bbj
def user_register(auth_hash, name, quip, bio):
    if USERDB["namemap"].get(name):
        return schema.error(4, "Username taken.")

    for ok, error in [
            user_namecheck(name),
            user_authcheck(auth_hash),
            user_quipcheck(quip),
            user_biocheck(bio)
    ]:

        if not ok:
            return error

    ID = uuid1().hex
    scheme = schema.user_internal(ID, auth_hash, name, quip, bio, False)
    USERDB.update({ID: scheme})
    USERDB["namemap"].update({name: ID})
    user_dbdump(USERDB)
    return scheme
Exemplo n.º 9
0
def api_http_error(status, message, traceback, version):
    return json.dumps(
        schema.error(2, "HTTP error {}: {}".format(status, message)))
Exemplo n.º 10
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)
Exemplo n.º 11
0
def thread_load(json):
    thread = db.thread_load(json["thread_id"], not json.get("nomarkup"))
    if not thread:
        return schema.error(7, "Requested thread does not exist")
    return schema.response(thread, create_usermap(thread))
Exemplo n.º 12
0
 def __init__(self, code, description):
     self.schema = error(code, description)
     self.description = description
     self.code = code