feat(tokens): implemented token validation
This commit is contained in:
parent
d3c721fb78
commit
e3ea93f4ae
|
@ -15,13 +15,13 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE IF NOT EXISTS Accounts (
|
CREATE TABLE IF NOT EXISTS Accounts (
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT8 UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
username VARCHAR(32) NOT NULL,
|
username VARCHAR(32) NOT NULL,
|
||||||
email TEXT NOT NULL,
|
email TEXT NOT NULL,
|
||||||
salt VARCHAR(22) NOT NULL,
|
salt VARCHAR(22) NOT NULL,
|
||||||
password VARCHAR(96) NOT NULL,
|
password VARCHAR(96) NOT NULL,
|
||||||
joined DATETIME NOT NULL,
|
joined DATETIME NOT NULL,
|
||||||
verified BOOLEAN NOT NULL,
|
verified BOOLEAN NOT NULL,
|
||||||
PRIMARY KEY(id)
|
PRIMARY KEY(id)
|
||||||
);
|
);
|
||||||
"#
|
"#
|
||||||
|
@ -32,9 +32,9 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE IF NOT EXISTS AuthTokens (
|
CREATE TABLE IF NOT EXISTS AuthTokens (
|
||||||
token VARCHAR(32) NOT NULL,
|
token VARCHAR(32) NOT NULL,
|
||||||
account INT NOT NULL,
|
account INT8 UNSIGNED NOT NULL,
|
||||||
expire DATETIME NOT NULL
|
expire DATETIME NOT NULL
|
||||||
);
|
);
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
|
@ -44,9 +44,9 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE IF NOT EXISTS VerificationTokens (
|
CREATE TABLE IF NOT EXISTS VerificationTokens (
|
||||||
token VARCHAR(32) NOT NULL,
|
token VARCHAR(32) NOT NULL,
|
||||||
account INT NOT NULL,
|
account INT8 UNSIGNED NOT NULL,
|
||||||
expire DATETIME NOT NULL
|
expire DATETIME NOT NULL
|
||||||
);
|
);
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{Error, Result};
|
||||||
use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono};
|
use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct AuthToken {
|
pub struct AuthToken {
|
||||||
token: String,
|
token: String,
|
||||||
account: i64,
|
account: u64,
|
||||||
expire: sqlx_chrono::DateTime<chrono::Utc>,
|
expire: sqlx_chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuthToken {
|
impl AuthToken {
|
||||||
|
@ -13,7 +14,10 @@ impl AuthToken {
|
||||||
account_id: usize,
|
account_id: usize,
|
||||||
lifetime: chrono::Duration,
|
lifetime: chrono::Duration,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let expire = match sqlx_chrono::Utc::now().checked_add_signed(lifetime) {
|
let expire = match sqlx_chrono::Utc::now()
|
||||||
|
.naive_utc()
|
||||||
|
.checked_add_signed(lifetime)
|
||||||
|
{
|
||||||
Some(e) => e,
|
Some(e) => e,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::msg(
|
return Err(Error::msg(
|
||||||
|
@ -24,7 +28,7 @@ impl AuthToken {
|
||||||
|
|
||||||
let token = Self {
|
let token = Self {
|
||||||
token: uuid::Uuid::new_v4().simple().to_string(),
|
token: uuid::Uuid::new_v4().simple().to_string(),
|
||||||
account: account_id as i64,
|
account: account_id as u64,
|
||||||
expire,
|
expire,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,12 +45,29 @@ impl AuthToken {
|
||||||
|
|
||||||
Ok(token)
|
Ok(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn check(pool: &MySqlPool, token: String) -> Result<Option<Self>> {
|
||||||
|
let query_result = sqlx::query!(r#"SELECT * FROM AuthTokens WHERE token = ?;"#, token)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match query_result {
|
||||||
|
Ok(row) => Ok(Some(Self {
|
||||||
|
token: row.token,
|
||||||
|
account: row.account,
|
||||||
|
expire: row.expire,
|
||||||
|
})),
|
||||||
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
|
Err(e) => Err(Error::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct VerificationToken {
|
pub struct VerificationToken {
|
||||||
token: String,
|
token: String,
|
||||||
account: i64,
|
account: u64,
|
||||||
expire: sqlx_chrono::DateTime<chrono::Utc>,
|
expire: sqlx_chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VerificationToken {
|
impl VerificationToken {
|
||||||
|
@ -55,7 +76,10 @@ impl VerificationToken {
|
||||||
account_id: usize,
|
account_id: usize,
|
||||||
lifetime: chrono::Duration,
|
lifetime: chrono::Duration,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let expire = match sqlx_chrono::Utc::now().checked_add_signed(lifetime) {
|
let expire = match sqlx_chrono::Utc::now()
|
||||||
|
.naive_utc()
|
||||||
|
.checked_add_signed(lifetime)
|
||||||
|
{
|
||||||
Some(e) => e,
|
Some(e) => e,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::msg(
|
return Err(Error::msg(
|
||||||
|
@ -66,7 +90,7 @@ impl VerificationToken {
|
||||||
|
|
||||||
let token = Self {
|
let token = Self {
|
||||||
token: uuid::Uuid::new_v4().simple().to_string(),
|
token: uuid::Uuid::new_v4().simple().to_string(),
|
||||||
account: account_id as i64,
|
account: account_id as u64,
|
||||||
expire,
|
expire,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,4 +107,20 @@ impl VerificationToken {
|
||||||
|
|
||||||
Ok(token)
|
Ok(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn check(pool: &MySqlPool, token: String) -> Result<Option<Self>> {
|
||||||
|
let query_result = sqlx::query!(r#"SELECT * FROM VerificationTokens WHERE token = ?;"#, token)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match query_result {
|
||||||
|
Ok(row) => Ok(Some(Self {
|
||||||
|
token: row.token,
|
||||||
|
account: row.account,
|
||||||
|
expire: row.expire,
|
||||||
|
})),
|
||||||
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
|
Err(e) => Err(Error::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue