feat: basic user token check
This commit is contained in:
2
migrations/2022-03-15-061041_create_users/down.sql
Normal file
2
migrations/2022-03-15-061041_create_users/down.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE users
|
||||||
9
migrations/2022-03-15-061041_create_users/up.sql
Normal file
9
migrations/2022-03-15-061041_create_users/up.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
|
||||||
|
CREATE TABLE users (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL UNIQUE,
|
||||||
|
token VARCHAR NOT NULL UNIQUE,
|
||||||
|
is_admin BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
|
);
|
||||||
|
CREATE INDEX users_toekn_idx ON users (`token`);
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
use crate::models::*;
|
||||||
use crate::random_hasher::RandomHasher;
|
use crate::random_hasher::RandomHasher;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::request::{self, FromRequest, Request};
|
use rocket::request::{self, FromRequest, Request};
|
||||||
use rocket::serde::json::{Value, json};
|
|
||||||
use rocket::response::{self, Responder};
|
use rocket::response::{self, Responder};
|
||||||
|
use rocket::serde::json::{json, Value};
|
||||||
|
|
||||||
#[catch(401)]
|
#[catch(401)]
|
||||||
pub fn catch_401_error() -> Value {
|
pub fn catch_401_error() -> Value {
|
||||||
@@ -21,31 +22,32 @@ pub struct CurrentUser {
|
|||||||
impl<'r> FromRequest<'r> for CurrentUser {
|
impl<'r> FromRequest<'r> for CurrentUser {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
let token = request.headers().get_one("User-Token");
|
if let Some(token) = request.headers().get_one("User-Token") {
|
||||||
match token {
|
let conn = establish_connection();
|
||||||
Some(t) => request::Outcome::Success(CurrentUser {
|
if let Some(user) = User::get_by_token(&conn, token) {
|
||||||
namehash: request
|
return request::Outcome::Success(CurrentUser {
|
||||||
.rocket()
|
namehash: request
|
||||||
.state::<RandomHasher>()
|
.rocket()
|
||||||
.unwrap()
|
.state::<RandomHasher>()
|
||||||
.hash_with_salt(t),
|
.unwrap()
|
||||||
is_admin: t == "admin", // TODO
|
.hash_with_salt(&user.name),
|
||||||
}),
|
is_admin: user.is_admin,
|
||||||
None => request::Outcome::Failure((Status::Unauthorized, ())),
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
request::Outcome::Failure((Status::Unauthorized, ()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum PolicyError {
|
pub enum PolicyError {
|
||||||
IsReported,
|
IsReported,
|
||||||
IsDeleted,
|
IsDeleted,
|
||||||
NotAllowed
|
NotAllowed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub enum APIError {
|
pub enum APIError {
|
||||||
DbError(diesel::result::Error),
|
DbError(diesel::result::Error),
|
||||||
PcError(PolicyError)
|
PcError(PolicyError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl APIError {
|
impl APIError {
|
||||||
@@ -57,20 +59,20 @@ impl APIError {
|
|||||||
impl<'r> Responder<'r, 'static> for APIError {
|
impl<'r> Responder<'r, 'static> for APIError {
|
||||||
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
|
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
|
||||||
match self {
|
match self {
|
||||||
APIError::DbError(e) =>
|
APIError::DbError(e) => json!({
|
||||||
json!({
|
"code": -1,
|
||||||
"code": -1,
|
"msg": e.to_string()
|
||||||
"msg": e.to_string()
|
})
|
||||||
}).respond_to(req),
|
.respond_to(req),
|
||||||
APIError::PcError(e) =>
|
APIError::PcError(e) => json!({
|
||||||
json!({
|
"code": -1,
|
||||||
"code": -1,
|
"msg": match e {
|
||||||
"msg": match e {
|
PolicyError::IsReported => "内容被举报,处理中",
|
||||||
PolicyError::IsReported => "内容被举报,处理中",
|
PolicyError::IsDeleted => "内容被删除",
|
||||||
PolicyError::IsDeleted => "内容被删除",
|
PolicyError::NotAllowed => "不允许的操作",
|
||||||
PolicyError::NotAllowed => "不允许的操作",
|
}
|
||||||
}
|
})
|
||||||
}).respond_to(req),
|
.respond_to(req),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use chrono::NaiveDateTime;
|
|||||||
use diesel::{insert_into, Connection, ExpressionMethods, QueryDsl, RunQueryDsl, SqliteConnection};
|
use diesel::{insert_into, Connection, ExpressionMethods, QueryDsl, RunQueryDsl, SqliteConnection};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use crate::schema::posts;
|
use crate::schema::*;
|
||||||
|
|
||||||
type MR<T> = Result<T, diesel::result::Error>;
|
type MR<T> = Result<T, diesel::result::Error>;
|
||||||
|
|
||||||
@@ -80,3 +80,17 @@ impl Post {
|
|||||||
insert_into(posts::table).values(&new_post).execute(conn)
|
insert_into(posts::table).values(&new_post).execute(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Debug)]
|
||||||
|
pub struct User {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub token: String,
|
||||||
|
pub is_admin: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl User {
|
||||||
|
pub fn get_by_token(conn: &SqliteConnection, token: &str) -> Option<Self> {
|
||||||
|
users::table.filter(users::token.eq(token)).first(conn).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,3 +15,17 @@ table! {
|
|||||||
allow_search -> Bool,
|
allow_search -> Bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
users (id) {
|
||||||
|
id -> Integer,
|
||||||
|
name -> Text,
|
||||||
|
token -> Text,
|
||||||
|
is_admin -> Bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allow_tables_to_appear_in_same_query!(
|
||||||
|
posts,
|
||||||
|
users,
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
def mig_post(db_old, db_new):
|
db_old = sqlite3.connect('hole.db')
|
||||||
c_old = db_old.cursor()
|
db_new = sqlite3.connect('hole_v2.db')
|
||||||
c_new = db_new.cursor()
|
c_old = db_old.cursor()
|
||||||
|
c_new = db_new.cursor()
|
||||||
|
|
||||||
|
|
||||||
|
def mig_post():
|
||||||
rs = c_old.execute(
|
rs = c_old.execute(
|
||||||
'SELECT id, name_hash, content, cw, author_title, '
|
'SELECT id, name_hash, content, cw, author_title, '
|
||||||
'likenum, n_comments, timestamp, comment_timestamp, '
|
'likenum, n_comments, timestamp, comment_timestamp, '
|
||||||
@@ -25,13 +29,22 @@ def mig_post(db_old, db_new):
|
|||||||
)
|
)
|
||||||
db_new.commit()
|
db_new.commit()
|
||||||
|
|
||||||
c_old.close()
|
|
||||||
c_new.close()
|
def mig_user():
|
||||||
|
rs = c_old.execute('SELECT name, token FROM user')
|
||||||
|
|
||||||
|
for r in rs:
|
||||||
|
c_new.execute(
|
||||||
|
'INSERT OR REPLACE INTO users(name, token) VALUES(?, ?)',
|
||||||
|
r
|
||||||
|
)
|
||||||
|
db_new.commit()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
db_old = sqlite3.connect('hole.db')
|
# mig_post()
|
||||||
db_new = sqlite3.connect('hole_v2.db')
|
mig_user()
|
||||||
|
|
||||||
mig_post(db_old, db_new)
|
c_old.close()
|
||||||
|
c_new.close()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user