Skip to content

Commit

Permalink
Openidconnect implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
xerbalind committed Oct 26, 2023
1 parent f3da85c commit 86c9926
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
60 changes: 55 additions & 5 deletions src/controllers/oauth_controller.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use chrono::Utc;
use rocket::form::Form;
use rocket::http::{Cookie, CookieJar};
use rocket::response::{Redirect, Responder};
Expand Down Expand Up @@ -161,6 +162,7 @@ pub struct UserToken {
pub client_id: i32,
pub client_name: String,
pub redirect_uri: String,
pub scope: Option<String>,
}

#[get("/oauth/grant")]
Expand Down Expand Up @@ -215,6 +217,7 @@ async fn authorization_granted(
let authorization_code = token_store
.create_token(UserToken {
user_id: user.id,
scope: state.scope.clone(),
username: user.username.clone(),
client_id: state.client_id.clone(),
client_name: state.client_name.clone(),
Expand All @@ -236,10 +239,22 @@ fn authorization_denied(state: AuthState) -> Redirect {
))
}

#[derive(Serialize, Debug)]
pub struct IDToken {
sub: String,
iss: String,
aud: String,
exp: i64,
iat: i64,
nickname: String,
email: String,
}

#[derive(Serialize, Debug)]
pub struct TokenSuccess {
access_token: String,
token_type: String,
id_token: Option<String>,
expires_in: i64,
}

Expand All @@ -252,6 +267,15 @@ pub struct TokenFormData {
client_secret: Option<String>,
}

fn create_jwt(id_token: IDToken) -> String {
let header = base64::encode("{\"alg\": \"none\"}");
let payload = base64::encode_config(
serde_json::to_string(&id_token).unwrap(),
base64::URL_SAFE_NO_PAD,
);
format!("{}.{}.", header, payload)
}

#[post("/oauth/token", data = "<form>")]
pub async fn token(
auth: Option<BasicAuthentication>,
Expand Down Expand Up @@ -306,13 +330,39 @@ pub async fn token(
)))
} else {
let user = User::find(token.user_id, &db).await?;
let session =
Session::create_client_session(&user, &client, &config, &db)
.await?;
let id_token = token
.scope
.as_ref()
.map(|scope| -> Option<String> {
match scope.contains("openid") {
true => Some(create_jwt(IDToken {
sub: user.id.to_string(),
iss: config.base_url().to_string(),
aud: client.name.clone(),
iat: Utc::now().timestamp(),
exp: Utc::now().timestamp()
+ config.client_session_seconds,
nickname: user.username.clone(),
email: user.email.clone(),
})),
false => None,
}
})
.flatten();

let session = Session::create_client_session(
&user,
&client,
token.scope,
&config,
&db,
)
.await?;
Ok(Json(TokenSuccess {
access_token: session.key.unwrap().clone(),
token_type: String::from("bearer"),
expires_in: config.client_session_seconds,
token_type: String::from("bearer"),
id_token,
expires_in: config.client_session_seconds,
}))
}
}
4 changes: 4 additions & 0 deletions src/models/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct NewSession {
pub client_id: Option<i32>,
pub created_at: NaiveDateTime,
pub expires_at: NaiveDateTime,
pub scope: Option<String>,
}

impl Session {
Expand All @@ -64,6 +65,7 @@ impl Session {
key: None,
created_at,
expires_at,
scope: None,
};
db.run(move |conn| {
conn.transaction(|conn| {
Expand All @@ -82,6 +84,7 @@ impl Session {
pub async fn create_client_session(
user: &User,
client: &Client,
scope: Option<String>,
conf: &Config,
db: &DbConn,
) -> Result<Session> {
Expand All @@ -94,6 +97,7 @@ impl Session {
key: Some(key),
created_at,
expires_at,
scope,
};
db.run(move |conn| {
conn.transaction(|conn| {
Expand Down
2 changes: 2 additions & 0 deletions tests/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ fn get_param(param_name: &str, query: &String) -> Option<String> {
async fn normal_flow() {
common::as_visitor(async move |http_client, db| {
let redirect_uri = "https://example.com/redirect/me/here";
let scope = None;
let client_id = "test";
let client_state = "anarchy (╯°□°)╯ ┻━┻";
let user_username = "batman";
Expand Down Expand Up @@ -219,6 +220,7 @@ async fn normal_flow() {

let authorization_code = token_store
.create_token(UserToken {
scope,
user_id: user.id,
username: user.username.clone(),
client_id: client.id,
Expand Down

0 comments on commit 86c9926

Please sign in to comment.