You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-28 11:02:02 +03:00
Basic Webfinger support
This commit is contained in:
@ -61,6 +61,7 @@ where
|
||||
"/.well-known/openid-configuration",
|
||||
get(self::oauth2::discovery::get),
|
||||
)
|
||||
.route("/.well-known/webfinger", get(self::oauth2::webfinger::get))
|
||||
.route("/oauth2/keys.json", get(self::oauth2::keys::get))
|
||||
.route(
|
||||
"/oauth2/userinfo",
|
||||
|
@ -18,5 +18,6 @@ pub mod introspection;
|
||||
pub mod keys;
|
||||
pub mod token;
|
||||
pub mod userinfo;
|
||||
pub mod webfinger;
|
||||
|
||||
pub(crate) use authorization::ContinueAuthorizationGrant;
|
||||
|
53
crates/handlers/src/oauth2/webfinger.rs
Normal file
53
crates/handlers/src/oauth2/webfinger.rs
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use axum::{extract::Query, response::IntoResponse, Extension, Json, TypedHeader};
|
||||
use headers::ContentType;
|
||||
use mas_axum_utils::UrlBuilder;
|
||||
use oauth2_types::webfinger::WebFingerResponse;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct Params {
|
||||
resource: String,
|
||||
|
||||
// TODO: handle multiple rel=
|
||||
#[serde(default)]
|
||||
rel: Option<String>,
|
||||
}
|
||||
|
||||
fn jrd() -> mime::Mime {
|
||||
"application/jrd+json".parse().unwrap()
|
||||
}
|
||||
|
||||
pub(crate) async fn get(
|
||||
Query(params): Query<Params>,
|
||||
Extension(url_builder): Extension<UrlBuilder>,
|
||||
) -> impl IntoResponse {
|
||||
// TODO: should we validate the subject?
|
||||
let subject = params.resource;
|
||||
|
||||
let wants_issuer = params
|
||||
.rel
|
||||
.iter()
|
||||
.any(|i| i == "http://openid.net/specs/connect/1.0/issuer");
|
||||
|
||||
let res = if wants_issuer {
|
||||
WebFingerResponse::new(subject).with_issuer(url_builder.oidc_issuer())
|
||||
} else {
|
||||
WebFingerResponse::new(subject)
|
||||
};
|
||||
|
||||
(TypedHeader(ContentType::from(jrd())), Json(res))
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
// Copyright 2021, 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -52,6 +52,7 @@ pub mod oidc;
|
||||
pub mod pkce;
|
||||
pub mod requests;
|
||||
pub mod scope;
|
||||
pub mod webfinger;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{pkce::CodeChallengeMethodExt, ResponseTypeExt};
|
||||
|
83
crates/oauth2-types/src/webfinger.rs
Normal file
83
crates/oauth2-types/src/webfinger.rs
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
pub struct WebFingerResponse {
|
||||
subject: String,
|
||||
links: Vec<WebFingerLink>,
|
||||
}
|
||||
|
||||
impl WebFingerResponse {
|
||||
#[must_use]
|
||||
pub const fn new(subject: String) -> Self {
|
||||
Self {
|
||||
subject,
|
||||
links: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_link(mut self, link: WebFingerLink) -> Self {
|
||||
self.links.push(link);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_issuer(self, issuer: Url) -> Self {
|
||||
self.with_link(WebFingerLink::issuer(issuer))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
#[serde(tag = "rel")]
|
||||
pub enum WebFingerLink {
|
||||
#[serde(rename = "http://openid.net/specs/connect/1.0/issuer")]
|
||||
OidcIssuer { href: Url },
|
||||
}
|
||||
|
||||
impl WebFingerLink {
|
||||
#[must_use]
|
||||
pub const fn issuer(href: Url) -> Self {
|
||||
Self::OidcIssuer { href }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_webfinger_response_test() {
|
||||
let res = WebFingerResponse::new("acct:john@example.com".to_string())
|
||||
.with_issuer(Url::parse("https://account.example.com/").unwrap());
|
||||
|
||||
let res = serde_json::to_value(&res).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
res,
|
||||
json!({
|
||||
"subject": "acct:john@example.com",
|
||||
"links": [{
|
||||
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||
"href": "https://account.example.com/",
|
||||
}]
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user