def post_signup(self, id, email, password): """ 注册 $input: id?str: 用户ID email?email&optional: 邮箱 password?str: 密码 $output: @message $error: 400.IDConflict: 用户ID已存在 400.EmailConflict: 邮箱已存在 """ if db.run(r.table("user").get(id)): abort(400, "IDConflict", "%s already exists" % id) if email and db.first(r.table("user").get_all(email, index="email")): abort(400, "EmailConflict", "%s already exists" % email) db.run(r.table("user").insert({ "id": id, "email": email, "pwdhash": gen_pwdhash(password), "role": "normal", "date_create": arrow.utcnow().datetime, "date_modify": arrow.utcnow().datetime, "timestamp": arrow.utcnow().timestamp })) return {"message": "OK"}
def patch(self, id, **kwargs): """ 增量修改文章基本信息 $input: id?str: ID title?str&optional: 标题 summary?str&optional: 摘要 tags: - &optional - str content?str&optional: 内容 $output: @message $error: 400.ArticleNotFound: 文章不存在 403.PermissionDeny: 只能修改自己的文章 """ kwargs = clear_empty(kwargs) q = r.table("article").get(id) art = db.run(q) if not art: abort(400, "ArticleNotFound", "文章不存在") if art["author"] != g.user["id"]: abort(403, "PermissionDeny", "只能修改自己的文章") db.run(q.update({ **kwargs, "date_modify": arrow.utcnow().datetime })) return {"message": "OK"}
def post_login(self, account, password): """ 登录 $input: account?str: 用户ID或邮箱 password?str: 密码 $output: @user $error: 403.UserNotFound: 帐号不存在 403.WrongPassword: 密码错误 """ user = db.run(r.table("user").get(account)) if not user: user = db.first(r.table("user").get_all(account, index="email")) if not user: abort(403, "UserNotFound", "帐号不存在") self.check_password(user, password) db.run( r.table("user") .get(user["id"]) .update({ "lastlogin_date": arrow.utcnow().datetime, "lastlogin_ip": request.remote_addr, "lastlogin_ua": request.headers.get('User-Agent'), "timestamp": arrow.utcnow().timestamp }) ) g.token = {"type": "login", "id": user["id"]} return user
def post_reset(self, token, password): """ 重置密码 $input: token?str: 重置链接中的Token password?str: 密码 $output: @message $error: 403.InvalidToken: Token无效 """ token = auth.decode_token(token) if token is None or token.get("type") != "reset": abort(403, "InvalidToken", "Token无效") user = db.run(r.table("user").get(token["id"])) if ( user is None or "timestamp" not in token or user["timestamp"] != token["timestamp"] ): abort(403, "InvalidToken", "Token无效") db.run( r.table("user") .get(token["id"]) .update({ "pwdhash": gen_pwdhash(password), "timestamp": arrow.utcnow().timestamp }) ) return {"message": "OK"}
def create_root(): if db.run(r.table("user").get("root")): raise ValueError("root already exists") else: if "ROOT_PASSWORD" not in current_app.config: raise ValueError("ROOT_PASSWORD is required") else: pwdhash = gen_pwdhash(current_app.config["ROOT_PASSWORD"]) db.run( r.table("user").insert( {"id": "root", "pwdhash": pwdhash, "role": "root", "email": current_app.config.get("ROOT_EMAIL")} ) )
def delete(self, id): """ 删除帐号 $input: id?str: ID $output: @message """ user = db.run(r.table("user").get(id)) if user and user["role"] == "root": abort(403, "PermissionDeny", "root帐号无法删除") db.run(r.table("user").get(id).delete()) return {"message": "OK"}
def post(self, catalog, name, title, summary, tags, content): """ 创建文章 $input: catalog?str: 目录 title?str: 标题 name?str&optional: 名称 summary?str&optional: 摘要 tags: - str content?str: 内容 $output: id?str: ID """ if not name: name = title[:32] if not summary: summary = content[:160] id = "/".join([g.user["id"], catalog, name]) resp = db.run(r.table("article").insert({ "id": id, "author": g.user["id"], "catalog": catalog, "name": name, "title": title, "summary": summary, "tags": tags, "content": content, "date_create": arrow.utcnow().datetime, "date_modify": arrow.utcnow().datetime })) if resp["errors"]: abort(400, "Conflict", "创建失败: %s" % resp["first_error"]) return {"id": id}
def put_password(self, new_password, password): """ 修改密码 $input: new_password?str: 新密码 password?str: 密码 $output: @message """ self.check_password(g.user, password) db.run(r.table("user").get(g.user["id"]).update({ "pwdhash": gen_pwdhash(new_password), "date_modify": arrow.utcnow().datetime, "timestamp": arrow.utcnow().timestamp })) return {"message": "OK"}
def put_email(self, email, password): """ 修改邮箱地址 $input: email?email: 邮箱 password?str: 密码 $output: @message """ self.check_password(g.user, password) db.run(r.table("user").get(g.user["id"]).update({ "email": email, "date_modify": arrow.utcnow().datetime, "timestamp": arrow.utcnow().timestamp })) return {"message": "OK"}
def create_root(): if db.run(r.table("user").get("root")): raise ValueError("root already exists") else: if "ROOT_PASSWORD" not in current_app.config: raise ValueError("ROOT_PASSWORD is required") else: pwdhash = gen_pwdhash(current_app.config["ROOT_PASSWORD"]) db.run( r.table("user").insert({ "id": "root", "pwdhash": pwdhash, "role": "root", "email": current_app.config.get("ROOT_EMAIL") }))
def put(self, github, avatar): """ 修改个人信息 $input: github?url&optional: Github地址 avatar?url&optional: 头像 $output: @message """ db.run( r.table("user") .get(g.user["id"]) .update({ "github": github, "avatar": avatar, "date_modify": arrow.utcnow().datetime, "timestamp": arrow.utcnow().timestamp }) ) return {"message": "OK"}
def put(self, id, role, email): """ 修改帐号信息 $input: id?str: 用户ID role?str: 角色 email?email: 邮箱 $output: @message """ if role == "root": abort(403, "PermissionDeny", "不能设为root帐号") db.run( r.table("user").get(id).update({ "role": role, "email": email, "date_modify": arrow.utcnow().datetime, "timestamp": arrow.utcnow().timestamp }) ) return {"message": "OK"}
def get(self, id): """ 查看用户信息 $input: id?str: ID $output: @user """ user = db.run(r.table("user").get(id)) if not user: abort(404, "NotFound", "用户不存在") return user
def get(self, account): """ 查找帐号 $input: account?str: 用户名或邮箱 $output: @user $error: 404.NotFound: 用户不存在 """ user = db.run(r.table("user").get(account)) if not user: user = db.first(r.table("user").get_all(account, index="email")) if not user: abort(404, "NotFound", "用户不存在") return user
def get(self, id): """ 获取一篇文章 $input: id?str: ID $output: $self@article: 文章信息 content?str: 内容 $error: 404.NotFound: 文章不存在 """ article = db.run(r.table("article").get(id)) if not article: abort(404, "NotFound", "文章不存在") return article