File size: 3,963 Bytes
c6d0d85
 
 
d94c6df
c6d0d85
f102c60
 
6858ec5
d94c6df
6858ec5
d94c6df
 
 
 
f102c60
6858ec5
 
d94c6df
6ad8d57
f102c60
 
 
6ad8d57
 
d94c6df
 
6858ec5
d94c6df
 
6858ec5
d94c6df
 
 
 
 
 
 
 
6ad8d57
 
f102c60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6858ec5
 
 
 
 
 
 
 
d94c6df
 
 
 
 
6858ec5
d94c6df
f102c60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d94c6df
 
 
 
 
 
 
249b27c
1eb186a
 
d94c6df
 
 
 
 
1eb186a
 
d94c6df
 
 
 
1eb186a
d94c6df
 
1eb186a
 
6858ec5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
mod api;
mod entity;
mod service;
mod errors;

use std::env;
use actix_files::Files;
use actix_identity::{ CookieIdentityPolicy, IdentityService, RequestIdentity };
use actix_session::CookieSession;
use actix_web::{ web, App, HttpServer, middleware, Error };
use actix_web::cookie::time::Duration;
use actix_web::dev::ServiceRequest;
use actix_web::error::ErrorUnauthorized;
use actix_web_httpauth::extractors::bearer::BearerAuth;
use listenfd::ListenFd;
use sea_orm::{ Database, DatabaseConnection };
use migration::{ Migrator, MigratorTrait };
use crate::errors::UserError;

#[derive(Debug, Clone)]
struct AppState {
    conn: DatabaseConnection,
}

pub(crate) async fn validator(
    req: ServiceRequest,
    credentials: BearerAuth
) -> Result<ServiceRequest, Error> {
    if let Some(token) = req.get_identity() {
        println!("{}, {}", credentials.token(), token);
        (credentials.token() == token)
            .then(|| req)
            .ok_or(ErrorUnauthorized(UserError::InvalidToken))
    } else {
        Err(ErrorUnauthorized(UserError::NotLoggedIn))
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    std::env::set_var("RUST_LOG", "debug");
    tracing_subscriber::fmt::init();

    // get env vars
    dotenvy::dotenv().ok();
    let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file");
    let host = env::var("HOST").expect("HOST is not set in .env file");
    let port = env::var("PORT").expect("PORT is not set in .env file");
    let server_url = format!("{host}:{port}");

    // establish connection to database and apply migrations
    // -> create post table if not exists
    let conn = Database::connect(&db_url).await.unwrap();
    Migrator::up(&conn, None).await.unwrap();

    let state = AppState { conn };

    // create server and try to serve over socket if possible
    let mut listenfd = ListenFd::from_env();
    let mut server = HttpServer::new(move || {
        App::new()
            .service(Files::new("/static", "./static"))
            .app_data(web::Data::new(state.clone()))
            .wrap(
                IdentityService::new(
                    CookieIdentityPolicy::new(&[0; 32])
                        .name("auth-cookie")
                        .login_deadline(Duration::seconds(120))
                        .secure(false)
                )
            )
            .wrap(
                CookieSession::signed(&[0; 32])
                    .name("session-cookie")
                    .secure(false)
                    // WARNING(alex): This uses the `time` crate, not `std::time`!
                    .expires_in_time(Duration::seconds(60))
            )
            .wrap(middleware::Logger::default())
            .configure(init)
    });

    server = match listenfd.take_tcp_listener(0)? {
        Some(listener) => server.listen(listener)?,
        None => server.bind(&server_url)?,
    };

    println!("Starting server at {server_url}");
    server.run().await?;

    Ok(())
}

fn init(cfg: &mut web::ServiceConfig) {
    cfg.service(api::tag_info::create);
    cfg.service(api::tag_info::delete);
    cfg.service(api::tag_info::list);

    cfg.service(api::kb_info::create);
    cfg.service(api::kb_info::delete);
    cfg.service(api::kb_info::list);
    cfg.service(api::kb_info::add_docs_to_kb);
    cfg.service(api::kb_info::anti_kb_docs);
    cfg.service(api::kb_info::all_relevents);

    cfg.service(api::doc_info::list);
    cfg.service(api::doc_info::delete);
    cfg.service(api::doc_info::mv);
    cfg.service(api::doc_info::upload);
    cfg.service(api::doc_info::new_folder);
    cfg.service(api::doc_info::rename);

    cfg.service(api::dialog_info::list);
    cfg.service(api::dialog_info::delete);
    cfg.service(api::dialog_info::create);
    cfg.service(api::dialog_info::update_history);

    cfg.service(api::user_info::login);
    cfg.service(api::user_info::register);
    cfg.service(api::user_info::setting);
}