summaryrefslogtreecommitdiffstats
path: root/rust/src/auth.rs
blob: 6ded1188d2e27c2b9f49e15264725eff86815b60 (plain)
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
123
124
125
126
127
//! Editor bearer token authentication

use swagger::auth::{AuthData, Authorization, Scopes};
//use macaroon::{Macaroon, Verifier};

use std::collections::BTreeSet;
use database_models::*;
use database_schema::*;
use api_helpers::*;
use chrono;
use diesel;
use iron;
use diesel::prelude::*;
use errors::*;
use serde_json;
use std::str::FromStr;
use uuid::Uuid;

#[derive(Debug)]
pub struct OpenAuthMiddleware;

impl OpenAuthMiddleware {
    /// Create a middleware that authorizes with the configured subject.
    pub fn new() -> OpenAuthMiddleware {
        OpenAuthMiddleware
    }
}
impl iron::middleware::BeforeMiddleware for OpenAuthMiddleware {
    fn before(&self, req: &mut iron::Request) -> iron::IronResult<()> {
        req.extensions.insert::<Authorization>(Authorization {
            subject: "undefined".to_string(),
            scopes: Scopes::All,
            issuer: None,
        });
        Ok(())
    }
}

#[derive(Debug)]
pub struct MacaroonAuthMiddleware;

impl MacaroonAuthMiddleware {

    pub fn new() -> MacaroonAuthMiddleware {
        MacaroonAuthMiddleware
    }
}

impl iron::middleware::BeforeMiddleware for MacaroonAuthMiddleware {
    fn before(&self, req: &mut iron::Request) -> iron::IronResult<()> {

        let res: Option<(String, Vec<String>)> = match req.extensions.get::<AuthData>() {
            Some(AuthData::ApiKey(header)) => {
                let header: Vec<String> = header.split_whitespace().map(|s| s.to_string()).collect();
                // TODO: error types
                assert!(header.len() == 2);
                assert!(header[0] == "Bearer");
                parse_macaroon_token(&header[1]).expect("valid macaroon")
            },
            None => None,
            _ => panic!("valid auth header, or none")
        };
        if let Some((editor_id, scopes)) = res {
            let mut scope_set = BTreeSet::new();
            for s in scopes {
                scope_set.insert(s);
            }
            req.extensions.insert::<Authorization>(Authorization {
                subject: editor_id,
                scopes: Scopes::Some(scope_set),
                issuer: None,
            });
        };
        Ok(())
    }
}

// DUMMY: parse macaroon
/// On success, returns Some((editor_id, scopes)), where `scopes` is a vector of strings.
pub fn parse_macaroon_token(s: &str) -> Result<Option<(String,Vec<String>)>> {
    Ok(Some(("some_editor_id".to_string(), vec![])))
}

pub fn print_editors(conn: &DbConn) -> Result<()>{
    // iterate over all editors. format id, print flags, auth_epoch
    let all_editors: Vec<EditorRow> = editor::table
        .load(conn)?;
    println!("editor_id\t\t\tis_admin/is_bot\tauth_epoch\t\t\tusername\twrangler_id");
    for e in all_editors {
        println!("{}\t{}\t{}\t{}\t{}\t{:?}",
            FatCatId::from_uuid(&e.id).to_string(),
            e.is_admin,
            e.is_bot,
            e.auth_epoch,
            e.username,
            e.wrangler_id,
        );
    }
    Ok(())
}

pub fn create_editor(conn: &DbConn, username: String, is_admin: bool, is_bot: bool) -> Result<EditorRow> {
    let ed: EditorRow = diesel::insert_into(editor::table)
        .values((
            editor::username.eq(username),
            editor::is_admin.eq(is_admin),
            editor::is_bot.eq(is_bot),
        ))
        .get_result(conn)?;
    Ok(ed) 
}

pub fn create_token(conn: &DbConn, editor_id: FatCatId, expires: Option<chrono::NaiveDateTime>) -> Result<String> {
    unimplemented!();
}

pub fn inspect_token(token: &str) -> Result<()> {
    unimplemented!();
}

pub fn revoke_tokens(conn: &DbConn, editor_id: FatCatId) -> Result<()>{
    unimplemented!();
}

pub fn revoke_tokens_everyone(conn: &DbConn) -> Result<u64> {
    unimplemented!();
}