1
use axum::{
2
    extract::{Request, State},
3
    http::{header, StatusCode},
4
    response::IntoResponse,
5
    Extension,
6
};
7
use axum_extra::headers::authorization::{Bearer, Credentials};
8
use log::error;
9

            
10
use sylvia_iot_corelib::{err::ErrResp, http::Json};
11

            
12
use super::{super::super::State as AppState, response};
13
use crate::models::{access_token::QueryCond as AccessTokenQueryCond, client::Client, user::User};
14

            
15
/// `GET /{base}/api/v1/auth/tokeninfo`
16
8
pub async fn get_tokeninfo(
17
8
    Extension(user): Extension<User>,
18
8
    Extension(client): Extension<Client>,
19
8
) -> impl IntoResponse {
20
8
    Json(response::GetTokenInfo {
21
8
        data: response::GetTokenInfoData {
22
8
            user_id: user.user_id,
23
8
            account: user.account,
24
8
            name: user.name,
25
8
            roles: user.roles,
26
8
            client_id: client.client_id,
27
8
            scopes: client.scopes,
28
8
        },
29
8
    })
30
8
}
31

            
32
/// `POST /{base}/api/v1/auth/logout`
33
2
pub async fn post_logout(state: State<AppState>, req: Request) -> impl IntoResponse {
34
    const FN_NAME: &'static str = "post_logout";
35

            
36
2
    let token = match req.headers().get(header::AUTHORIZATION) {
37
        None => {
38
            return Err(ErrResp::ErrUnknown(Some(
39
                "no Authorization header".to_string(),
40
            )))
41
        }
42
2
        Some(auth) => match Bearer::decode(auth) {
43
            None => return Err(ErrResp::ErrUnknown(Some("no Bearer token".to_string()))),
44
2
            Some(token) => token.token().to_string(),
45
2
        },
46
2
    };
47
2

            
48
2
    let cond = AccessTokenQueryCond {
49
2
        access_token: Some(token.as_str()),
50
2
        ..Default::default()
51
2
    };
52
4
    if let Err(e) = state.model.access_token().del(&cond).await {
53
        error!("[{}] clear access token error: {}", FN_NAME, e);
54
        let e = ErrResp::ErrDb(Some(format!("clear access token error: {}", e)));
55
        return Err(e);
56
2
    }
57
2

            
58
2
    Ok(StatusCode::NO_CONTENT)
59
2
}