|
|
|
|
//
|
|
|
|
|
// user.rs
|
|
|
|
|
// Copyright (C) 2022 veypi <i@veypi.com>
|
|
|
|
|
// 2022-07-09 03:10
|
|
|
|
|
// Distributed under terms of the Apache license.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
use std::fmt::Debug;
|
|
|
|
|
|
|
|
|
|
use crate::{models, Error, Result, CONFIG};
|
|
|
|
|
use actix_web::{delete, get, head, http, post, web, HttpResponse, Responder};
|
|
|
|
|
use base64;
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use tracing::info;
|
|
|
|
|
|
|
|
|
|
#[get("/user/{id}")]
|
|
|
|
|
pub async fn get(id: web::Path<String>) -> Result<models::User> {
|
|
|
|
|
let n = id.into_inner();
|
|
|
|
|
if !n.is_empty() {
|
|
|
|
|
let s = sqlx::query_as::<_, models::User>("select *& from user where id = ?")
|
|
|
|
|
.bind(n)
|
|
|
|
|
.fetch_one(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
info!("{:#?}", s);
|
|
|
|
|
Ok(s)
|
|
|
|
|
} else {
|
|
|
|
|
Err(Error::Missing("id".to_string()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[get("/user/")]
|
|
|
|
|
pub async fn list() -> Result<impl Responder> {
|
|
|
|
|
let result = sqlx::query_as::<_, models::User>("select * from user")
|
|
|
|
|
.fetch_all(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
Ok(web::Json(result))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Serialize)]
|
|
|
|
|
pub struct LoginOpt {
|
|
|
|
|
typ: Option<String>,
|
|
|
|
|
password: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[head("/user/{id}")]
|
|
|
|
|
pub async fn login(q: web::Query<LoginOpt>, id: web::Path<String>) -> Result<HttpResponse> {
|
|
|
|
|
let id = id.into_inner();
|
|
|
|
|
let q = q.into_inner();
|
|
|
|
|
let typ = match q.typ {
|
|
|
|
|
Some(t) => match t.as_str() {
|
|
|
|
|
"phone" => "phone",
|
|
|
|
|
"email" => "email",
|
|
|
|
|
_ => "username",
|
|
|
|
|
},
|
|
|
|
|
_ => "username",
|
|
|
|
|
};
|
|
|
|
|
let p = match base64::decode(q.password.as_bytes()) {
|
|
|
|
|
Err(_) => return Err(Error::ArgInvalid("password".to_string())),
|
|
|
|
|
Ok(p) => p,
|
|
|
|
|
};
|
|
|
|
|
let p = match std::str::from_utf8(&p) {
|
|
|
|
|
Ok(p) => p,
|
|
|
|
|
Err(_) => return Err(Error::ArgInvalid("password".to_string())),
|
|
|
|
|
};
|
|
|
|
|
let sql = format!("select * from user where {} = ?", typ);
|
|
|
|
|
let u = sqlx::query_as::<_, models::User>(&sql)
|
|
|
|
|
.bind(id)
|
|
|
|
|
.fetch_optional(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
let u = match u {
|
|
|
|
|
Some(u) => u,
|
|
|
|
|
None => return Err(Error::NotFound("user".to_string())),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
u.check_pass(p)?;
|
|
|
|
|
let au = sqlx::query_as::<_, models::AppUser>(
|
|
|
|
|
"select * from app_user where app_id = ? and user_id = ?",
|
|
|
|
|
)
|
|
|
|
|
.bind(&CONFIG.uuid)
|
|
|
|
|
.bind(&u.id)
|
|
|
|
|
.fetch_optional(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
let i: i64 = match au {
|
|
|
|
|
Some(au) => match au.status {
|
|
|
|
|
models::AUStatus::OK => 0,
|
|
|
|
|
models::AUStatus::Deny => {
|
|
|
|
|
return Err(Error::BusinessException("apply denied".to_string()))
|
|
|
|
|
}
|
|
|
|
|
models::AUStatus::Disabled => {
|
|
|
|
|
return Err(Error::BusinessException("login disabled".to_string()))
|
|
|
|
|
}
|
|
|
|
|
models::AUStatus::Applying => {
|
|
|
|
|
return Err(Error::BusinessException("applying".to_string()))
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
None => {
|
|
|
|
|
let app = sqlx::query_as::<_, models::App>("select * from app where id = ?")
|
|
|
|
|
.bind(CONFIG.uuid.clone())
|
|
|
|
|
.fetch_one(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
info!("{:#?}", u);
|
|
|
|
|
let s = match app.join_method {
|
|
|
|
|
models::app::AppJoin::Disabled => {
|
|
|
|
|
return Err(Error::BusinessException(
|
|
|
|
|
"this app diabled login".to_string(),
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
models::app::AppJoin::Auto => models::AUStatus::OK,
|
|
|
|
|
models::app::AppJoin::Applying => models::AUStatus::Applying,
|
|
|
|
|
};
|
|
|
|
|
sqlx::query(
|
|
|
|
|
r#"
|
|
|
|
|
insert into app_user (app_id,user_id,status)
|
|
|
|
|
values ( ?, ?, ? )
|
|
|
|
|
"#,
|
|
|
|
|
)
|
|
|
|
|
.bind(&app.id)
|
|
|
|
|
.bind(&u.id)
|
|
|
|
|
.bind(&s)
|
|
|
|
|
.execute(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
match s {
|
|
|
|
|
models::AUStatus::OK => 0,
|
|
|
|
|
_ => 1,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if i == 0 {
|
|
|
|
|
Ok(HttpResponse::build(http::StatusCode::OK)
|
|
|
|
|
.insert_header(("auth_token", u.token().to_string()?))
|
|
|
|
|
.body("".to_string()))
|
|
|
|
|
} else {
|
|
|
|
|
Ok(HttpResponse::build(http::StatusCode::OK)
|
|
|
|
|
.insert_header(("data", "applying"))
|
|
|
|
|
.body("".to_string()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Serialize)]
|
|
|
|
|
pub struct RegisterOpt {
|
|
|
|
|
username: String,
|
|
|
|
|
password: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/user/")]
|
|
|
|
|
pub async fn register(q: web::Json<RegisterOpt>) -> Result<String> {
|
|
|
|
|
let q = q.into_inner();
|
|
|
|
|
// let mut tx = dbtx().await;
|
|
|
|
|
println!("{:#?}", q);
|
|
|
|
|
let u: Option<models::User> =
|
|
|
|
|
sqlx::query_as::<_, models::User>("select * from user where username = ?")
|
|
|
|
|
.bind(q.username.clone())
|
|
|
|
|
.fetch_optional(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
let u: models::User = match u {
|
|
|
|
|
Some(_) => return Err(Error::ArgDuplicated(format!("username: {}", q.username))),
|
|
|
|
|
None => {
|
|
|
|
|
let mut u = models::User::default();
|
|
|
|
|
u.username = q.username.clone();
|
|
|
|
|
let p = match base64::decode(q.password.as_bytes()) {
|
|
|
|
|
Err(_) => return Err(Error::ArgInvalid("password".to_string())),
|
|
|
|
|
Ok(p) => p,
|
|
|
|
|
};
|
|
|
|
|
let p = match std::str::from_utf8(&p) {
|
|
|
|
|
Ok(p) => p,
|
|
|
|
|
Err(_) => return Err(Error::ArgInvalid("password".to_string())),
|
|
|
|
|
};
|
|
|
|
|
info!("{}", p);
|
|
|
|
|
u.update_pass(&p)?;
|
|
|
|
|
u
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
let oa: models::App = sqlx::query_as::<_, models::App>("select * from app where id = ?")
|
|
|
|
|
.bind(CONFIG.uuid.clone())
|
|
|
|
|
.fetch_one(CONFIG.db())
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
let mut au = models::AppUser::new();
|
|
|
|
|
au.app_id = oa.id;
|
|
|
|
|
au.user_id = u.id.clone();
|
|
|
|
|
match oa.join_method {
|
|
|
|
|
models::app::AppJoin::Disabled => return Err(Error::AppDisabledRegister),
|
|
|
|
|
models::app::AppJoin::Auto => au.status = models::app::AUStatus::OK,
|
|
|
|
|
models::app::AppJoin::Applying => au.status = models::app::AUStatus::Applying,
|
|
|
|
|
}
|
|
|
|
|
let mut c = CONFIG.db().begin().await?;
|
|
|
|
|
sqlx::query!(
|
|
|
|
|
r#"
|
|
|
|
|
insert into user (id,username,real_code,check_code)
|
|
|
|
|
values ( ?, ?, ?, ?)
|
|
|
|
|
"#,
|
|
|
|
|
u.id,
|
|
|
|
|
u.username,
|
|
|
|
|
u.real_code,
|
|
|
|
|
u.check_code,
|
|
|
|
|
)
|
|
|
|
|
.execute(&mut c)
|
|
|
|
|
.await?;
|
|
|
|
|
sqlx::query!(
|
|
|
|
|
r#"
|
|
|
|
|
insert into app_user ( app_id, user_id, status)
|
|
|
|
|
values (?, ?, ? )
|
|
|
|
|
"#,
|
|
|
|
|
au.app_id,
|
|
|
|
|
au.user_id,
|
|
|
|
|
au.status,
|
|
|
|
|
)
|
|
|
|
|
.execute(&mut c)
|
|
|
|
|
.await?;
|
|
|
|
|
c.commit().await?;
|
|
|
|
|
Ok("ok".to_string())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/user/")]
|
|
|
|
|
pub async fn delete() -> impl Responder {
|
|
|
|
|
""
|
|
|
|
|
}
|