Add token management

This commit is contained in:
Adrian Wozniak 2020-04-16 14:43:13 +02:00
parent d622eba6c3
commit c0b5128777
6 changed files with 306 additions and 238 deletions

View File

@ -0,0 +1 @@
ALTER TABLE tokens DROP COLUMN bind_token;

View File

@ -0,0 +1 @@
ALTER TABLE tokens ADD COLUMN bind_token UUID;

View File

@ -11,6 +11,7 @@ pub mod comments;
pub mod issue_assignees; pub mod issue_assignees;
pub mod issues; pub mod issues;
pub mod projects; pub mod projects;
pub mod tokens;
pub mod users; pub mod users;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]

View File

@ -0,0 +1,58 @@
use actix::{Handler, Message};
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use jirs_data::UserId;
use crate::db::DbExecutor;
use crate::errors::ServiceErrors;
#[derive(Serialize, Deserialize, Debug)]
pub struct FindBindToken {
pub token: Uuid,
}
impl Message for FindBindToken {
type Result = Result<crate::models::Token, ServiceErrors>;
}
impl Handler<FindBindToken> for DbExecutor {
type Result = Result<crate::models::Token, ServiceErrors>;
fn handle(&mut self, msg: FindBindToken, _: &mut Self::Context) -> Self::Result {
use crate::schema::tokens::dsl::{bind_token, tokens};
let conn = &self
.0
.get()
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
let token: crate::models::Token = tokens
.filter(bind_token.eq(msg.token))
.first(conn)
.map_err(|_e| {
ServiceErrors::RecordNotFound(format!("token for {}", msg.access_token))
})?;
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CreateBindToken {
pub user_id: UserId,
}
impl Message for CreateBindToken {
type Result = Result<crate::models::Token, ServiceErrors>;
}
impl Handler<CreateBindToken> for DbExecutor {
type Result = Result<crate::models::Token, ServiceErrors>;
fn handle(&mut self, msg: CreateBindToken, _: &mut Self::Context) -> Self::Result {
use crate::schema::tokens::dsl::{access_token, tokens};
let conn = &self
.0
.get()
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
}
}

View File

@ -1,238 +1,239 @@
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
use jirs_data::{IssuePriority, IssueStatus, IssueType, ProjectCategory}; use jirs_data::{IssuePriority, IssueStatus, IssueType, ProjectCategory};
use crate::schema::*; use crate::schema::*;
#[derive(Debug, Serialize, Deserialize, Queryable)] #[derive(Debug, Serialize, Deserialize, Queryable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Comment { pub struct Comment {
pub id: i32, pub id: i32,
pub body: String, pub body: String,
pub user_id: i32, pub user_id: i32,
pub issue_id: i32, pub issue_id: i32,
pub created_at: NaiveDateTime, pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime, pub updated_at: NaiveDateTime,
} }
impl Into<jirs_data::Comment> for Comment { impl Into<jirs_data::Comment> for Comment {
fn into(self) -> jirs_data::Comment { fn into(self) -> jirs_data::Comment {
jirs_data::Comment { jirs_data::Comment {
id: self.id, id: self.id,
body: self.body, body: self.body,
user_id: self.user_id, user_id: self.user_id,
issue_id: self.issue_id, issue_id: self.issue_id,
created_at: self.created_at, created_at: self.created_at,
updated_at: self.updated_at, updated_at: self.updated_at,
} }
} }
} }
#[derive(Debug, Serialize, Deserialize, Insertable)] #[derive(Debug, Serialize, Deserialize, Insertable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[table_name = "comments"] #[table_name = "comments"]
pub struct CommentForm { pub struct CommentForm {
pub body: String, pub body: String,
pub user_id: i32, pub user_id: i32,
pub issue_id: i32, pub issue_id: i32,
} }
#[derive(Debug, Serialize, Deserialize, Queryable)] #[derive(Debug, Serialize, Deserialize, Queryable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Issue { pub struct Issue {
pub id: i32, pub id: i32,
pub title: String, pub title: String,
#[serde(rename = "type")] #[serde(rename = "type")]
pub issue_type: IssueType, pub issue_type: IssueType,
pub status: IssueStatus, pub status: IssueStatus,
pub priority: IssuePriority, pub priority: IssuePriority,
pub list_position: i32, pub list_position: i32,
pub description: Option<String>, pub description: Option<String>,
pub description_text: Option<String>, pub description_text: Option<String>,
pub estimate: Option<i32>, pub estimate: Option<i32>,
pub time_spent: Option<i32>, pub time_spent: Option<i32>,
pub time_remaining: Option<i32>, pub time_remaining: Option<i32>,
pub reporter_id: i32, pub reporter_id: i32,
pub project_id: i32, pub project_id: i32,
pub created_at: NaiveDateTime, pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime, pub updated_at: NaiveDateTime,
} }
impl Into<jirs_data::Issue> for Issue { impl Into<jirs_data::Issue> for Issue {
fn into(self) -> jirs_data::Issue { fn into(self) -> jirs_data::Issue {
jirs_data::Issue { jirs_data::Issue {
id: self.id, id: self.id,
title: self.title, title: self.title,
issue_type: self.issue_type, issue_type: self.issue_type,
status: self.status, status: self.status,
priority: self.priority, priority: self.priority,
list_position: self.list_position, list_position: self.list_position,
description: self.description, description: self.description,
description_text: self.description_text, description_text: self.description_text,
estimate: self.estimate, estimate: self.estimate,
time_spent: self.time_spent, time_spent: self.time_spent,
time_remaining: self.time_remaining, time_remaining: self.time_remaining,
reporter_id: self.reporter_id, reporter_id: self.reporter_id,
project_id: self.project_id, project_id: self.project_id,
created_at: self.created_at, created_at: self.created_at,
updated_at: self.updated_at, updated_at: self.updated_at,
user_ids: vec![], user_ids: vec![],
} }
} }
} }
#[derive(Debug, Serialize, Deserialize, Insertable)] #[derive(Debug, Serialize, Deserialize, Insertable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[table_name = "issues"] #[table_name = "issues"]
pub struct CreateIssueForm { pub struct CreateIssueForm {
pub title: String, pub title: String,
#[serde(rename = "type")] #[serde(rename = "type")]
pub issue_type: IssueType, pub issue_type: IssueType,
pub status: IssueStatus, pub status: IssueStatus,
pub priority: IssuePriority, pub priority: IssuePriority,
pub list_position: i32, pub list_position: i32,
pub description: Option<String>, pub description: Option<String>,
pub description_text: Option<String>, pub description_text: Option<String>,
pub estimate: Option<i32>, pub estimate: Option<i32>,
pub time_spent: Option<i32>, pub time_spent: Option<i32>,
pub time_remaining: Option<i32>, pub time_remaining: Option<i32>,
pub reporter_id: i32, pub reporter_id: i32,
pub project_id: i32, pub project_id: i32,
} }
#[derive(Debug, Serialize, Deserialize, Queryable)] #[derive(Debug, Serialize, Deserialize, Queryable)]
pub struct IssueAssignee { pub struct IssueAssignee {
pub id: i32, pub id: i32,
pub issue_id: i32, pub issue_id: i32,
pub user_id: i32, pub user_id: i32,
pub created_at: NaiveDateTime, pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime, pub updated_at: NaiveDateTime,
} }
#[derive(Debug, Serialize, Deserialize, Insertable)] #[derive(Debug, Serialize, Deserialize, Insertable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[table_name = "issue_assignees"] #[table_name = "issue_assignees"]
pub struct CreateIssueAssigneeForm { pub struct CreateIssueAssigneeForm {
pub issue_id: i32, pub issue_id: i32,
pub user_id: i32, pub user_id: i32,
} }
#[derive(Debug, Serialize, Deserialize, Queryable)] #[derive(Debug, Serialize, Deserialize, Queryable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Project { pub struct Project {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub url: String, pub url: String,
pub description: String, pub description: String,
pub category: ProjectCategory, pub category: ProjectCategory,
pub created_at: NaiveDateTime, pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime, pub updated_at: NaiveDateTime,
} }
impl Into<jirs_data::Project> for Project { impl Into<jirs_data::Project> for Project {
fn into(self) -> jirs_data::Project { fn into(self) -> jirs_data::Project {
jirs_data::Project { jirs_data::Project {
id: self.id, id: self.id,
name: self.name, name: self.name,
url: self.url, url: self.url,
description: self.description, description: self.description,
category: self.category, category: self.category,
created_at: self.created_at, created_at: self.created_at,
updated_at: self.updated_at, updated_at: self.updated_at,
} }
} }
} }
#[derive(Debug, Serialize, Deserialize, Insertable)] #[derive(Debug, Serialize, Deserialize, Insertable)]
#[table_name = "projects"] #[table_name = "projects"]
pub struct UpdateProjectForm { pub struct UpdateProjectForm {
pub name: Option<String>, pub name: Option<String>,
pub url: Option<String>, pub url: Option<String>,
pub description: Option<String>, pub description: Option<String>,
pub category: Option<ProjectCategory>, pub category: Option<ProjectCategory>,
} }
#[derive(Debug, Serialize, Deserialize, Queryable)] #[derive(Debug, Serialize, Deserialize, Queryable)]
pub struct User { pub struct User {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub email: String, pub email: String,
pub avatar_url: Option<String>, pub avatar_url: Option<String>,
pub project_id: i32, pub project_id: i32,
pub created_at: NaiveDateTime, pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime, pub updated_at: NaiveDateTime,
} }
impl Into<jirs_data::User> for User { impl Into<jirs_data::User> for User {
fn into(self) -> jirs_data::User { fn into(self) -> jirs_data::User {
jirs_data::User { jirs_data::User {
id: self.id, id: self.id,
name: self.name, name: self.name,
email: self.email, email: self.email,
avatar_url: self.avatar_url, avatar_url: self.avatar_url,
project_id: self.project_id, project_id: self.project_id,
created_at: self.created_at, created_at: self.created_at,
updated_at: self.updated_at, updated_at: self.updated_at,
} }
} }
} }
impl Into<jirs_data::User> for &User { impl Into<jirs_data::User> for &User {
fn into(self) -> jirs_data::User { fn into(self) -> jirs_data::User {
jirs_data::User { jirs_data::User {
id: self.id, id: self.id,
name: self.name.clone(), name: self.name.clone(),
email: self.email.clone(), email: self.email.clone(),
avatar_url: self.avatar_url.clone(), avatar_url: self.avatar_url.clone(),
project_id: self.project_id, project_id: self.project_id,
created_at: self.created_at, created_at: self.created_at,
updated_at: self.updated_at, updated_at: self.updated_at,
} }
} }
} }
#[derive(Debug, Serialize, Deserialize, Insertable)] #[derive(Debug, Serialize, Deserialize, Insertable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[table_name = "users"] #[table_name = "users"]
pub struct UserForm { pub struct UserForm {
pub name: String, pub name: String,
pub email: String, pub email: String,
pub avatar_url: Option<String>, pub avatar_url: Option<String>,
pub project_id: Option<i32>, pub project_id: Option<i32>,
} }
#[derive(Debug, Serialize, Deserialize, Queryable)] #[derive(Debug, Serialize, Deserialize, Queryable)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Token { pub struct Token {
pub id: i32, pub id: i32,
pub user_id: i32, pub user_id: i32,
pub access_token: Uuid, pub access_token: Uuid,
pub refresh_token: Uuid, pub refresh_token: Uuid,
pub created_at: NaiveDateTime, pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime, pub updated_at: NaiveDateTime,
} pub bind_token: Option<Uuid>,
}
impl Into<jirs_data::Token> for Token {
fn into(self) -> jirs_data::Token { impl Into<jirs_data::Token> for Token {
jirs_data::Token { fn into(self) -> jirs_data::Token {
id: self.id, jirs_data::Token {
user_id: self.user_id, id: self.id,
access_token: self.access_token, user_id: self.user_id,
refresh_token: self.refresh_token, access_token: self.access_token,
created_at: self.created_at, refresh_token: self.refresh_token,
updated_at: self.updated_at, created_at: self.created_at,
} updated_at: self.updated_at,
} }
} }
}
#[derive(Debug, Serialize, Deserialize, Insertable)]
#[serde(rename_all = "camelCase")] #[derive(Debug, Serialize, Deserialize, Insertable)]
#[table_name = "tokens"] #[serde(rename_all = "camelCase")]
pub struct TokenForm { #[table_name = "tokens"]
pub user_id: i32, pub struct TokenForm {
pub access_token: Uuid, pub user_id: i32,
pub refresh_token: Uuid, pub access_token: Uuid,
} pub refresh_token: Uuid,
}

View File

@ -286,6 +286,12 @@ table! {
/// ///
/// (Automatically generated by Diesel.) /// (Automatically generated by Diesel.)
updated_at -> Timestamp, updated_at -> Timestamp,
/// The `bind_token` column of the `tokens` table.
///
/// Its SQL type is `Nullable<Uuid>`.
///
/// (Automatically generated by Diesel.)
bind_token -> Nullable<Uuid>,
} }
} }