Use associated type for resolver state
This commit is contained in:
parent
5e48aa725d
commit
33fd061a8a
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-webfinger"
|
name = "actix-webfinger"
|
||||||
description = "Types and helpers to create and fetch Webfinger resources"
|
description = "Types and helpers to create and fetch Webfinger resources"
|
||||||
version = "0.3.0-alpha.4"
|
version = "0.3.0-alpha.5"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["asonix <asonix@asonix.dog>"]
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
repository = "https://git.asonix.dog/Aardwolf/actix-webfinger"
|
repository = "https://git.asonix.dog/Aardwolf/actix-webfinger"
|
||||||
|
@ -19,4 +19,5 @@ thiserror = "1.0"
|
||||||
actix = "0.10.0-alpha.1"
|
actix = "0.10.0-alpha.1"
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
actix-web = { version = "3.0.0-alpha.1", features = ["openssl"] }
|
actix-web = { version = "3.0.0-alpha.1", features = ["openssl"] }
|
||||||
|
pretty_env_logger = "0.4"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
|
@ -15,7 +15,7 @@ First, add Actix Webfinger as a dependency
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix = "0.10.0-alpha.1"
|
actix = "0.10.0-alpha.1"
|
||||||
actix-web = "3.0.0-alpha.1"
|
actix-web = "3.0.0-alpha.1"
|
||||||
actix-webfinger = "0.3.0-alpha.4"
|
actix-webfinger = "0.3.0-alpha.5"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then use it in your application
|
Then use it in your application
|
||||||
|
@ -49,7 +49,8 @@ pub struct MyState {
|
||||||
|
|
||||||
pub struct MyResolver;
|
pub struct MyResolver;
|
||||||
|
|
||||||
impl Resolver<Data<MyState>> for MyResolver {
|
impl Resolver for MyResolver {
|
||||||
|
type State = Data<MyState>;
|
||||||
type Error = actix_web::error::JsonPayloadError;
|
type Error = actix_web::error::JsonPayloadError;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::error::Error;
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let client = Client::default();
|
let client = Client::default();
|
||||||
let wf = Webfinger::fetch(&client, "asonix@asonix.dog", "localhost:8000", false).await?;
|
let wf = Webfinger::fetch(&client, "asonix@localhost:8000", "localhost:8000", false).await?;
|
||||||
|
|
||||||
println!("asonix's webfinger:\n{:#?}", wf);
|
println!("asonix's webfinger:\n{:#?}", wf);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use actix_web::{web::Data, App, HttpServer};
|
use actix_web::{middleware::Logger, web::Data, App, HttpServer};
|
||||||
use actix_webfinger::{Resolver, Webfinger};
|
use actix_webfinger::{Resolver, Webfinger};
|
||||||
use std::{error::Error, future::Future, pin::Pin};
|
use std::{error::Error, future::Future, pin::Pin};
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ pub struct MyState {
|
||||||
|
|
||||||
pub struct MyResolver;
|
pub struct MyResolver;
|
||||||
|
|
||||||
impl Resolver<Data<MyState>> for MyResolver {
|
impl Resolver for MyResolver {
|
||||||
|
type State = Data<MyState>;
|
||||||
type Error = actix_web::error::JsonPayloadError;
|
type Error = actix_web::error::JsonPayloadError;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
|
@ -29,12 +30,15 @@ impl Resolver<Data<MyState>> for MyResolver {
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
std::env::set_var("RUST_LOG", "info");
|
||||||
|
pretty_env_logger::init();
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
.data(MyState {
|
.data(MyState {
|
||||||
domain: "localhost:8000".to_owned(),
|
domain: "localhost:8000".to_owned(),
|
||||||
})
|
})
|
||||||
.service(actix_webfinger::resource::<_, MyResolver>())
|
.wrap(Logger::default())
|
||||||
|
.service(actix_webfinger::resource::<MyResolver>())
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8000")?
|
.bind("127.0.0.1:8000")?
|
||||||
.run()
|
.run()
|
||||||
|
|
71
src/lib.rs
71
src/lib.rs
|
@ -2,7 +2,7 @@
|
||||||
//! A library to aid in resolving and providing webfinger objects with the Actix Web web framework.
|
//! A library to aid in resolving and providing webfinger objects with the Actix Web web framework.
|
||||||
//!
|
//!
|
||||||
//! The main functionality this crate provides is through the `Webfinger::fetch` method for Actix
|
//! The main functionality this crate provides is through the `Webfinger::fetch` method for Actix
|
||||||
//! Web-based clients, and the `Resolver<S>` trait for Actix Web-based servers.
|
//! Web-based clients, and the `Resolver` trait for Actix Web-based servers.
|
||||||
//!
|
//!
|
||||||
//! ### Usage
|
//! ### Usage
|
||||||
//! First, add Actix Webfinger as a dependency
|
//! First, add Actix Webfinger as a dependency
|
||||||
|
@ -49,7 +49,8 @@
|
||||||
//!
|
//!
|
||||||
//! pub struct MyResolver;
|
//! pub struct MyResolver;
|
||||||
//!
|
//!
|
||||||
//! impl Resolver<Data<MyState>> for MyResolver {
|
//! impl Resolver for MyResolver {
|
||||||
|
//! type State = Data<MyState>;
|
||||||
//! type Error = actix_web::error::JsonPayloadError;
|
//! type Error = actix_web::error::JsonPayloadError;
|
||||||
//!
|
//!
|
||||||
//! fn find(
|
//! fn find(
|
||||||
|
@ -74,7 +75,7 @@
|
||||||
//! .data(MyState {
|
//! .data(MyState {
|
||||||
//! domain: "asonix.dog".to_owned(),
|
//! domain: "asonix.dog".to_owned(),
|
||||||
//! })
|
//! })
|
||||||
//! .service(actix_webfinger::resource::<_, MyResolver>())
|
//! .service(actix_webfinger::resource::<MyResolver>())
|
||||||
//! })
|
//! })
|
||||||
//! .bind("127.0.0.1:8000")?
|
//! .bind("127.0.0.1:8000")?
|
||||||
//! .run()
|
//! .run()
|
||||||
|
@ -171,19 +172,18 @@ impl Guard for WebfingerGuard {
|
||||||
///
|
///
|
||||||
/// HttpServer::new(|| {
|
/// HttpServer::new(|| {
|
||||||
/// App::new()
|
/// App::new()
|
||||||
/// .service(actix_webfinger::resource::<_, MyResolver>())
|
/// .service(actix_webfinger::resource::<MyResolver>())
|
||||||
/// })
|
/// })
|
||||||
/// .bind("127.0.0.1:8000")?
|
/// .bind("127.0.0.1:8000")?
|
||||||
/// .start();
|
/// .start();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource<S, R>() -> Resource
|
pub fn resource<R>() -> Resource
|
||||||
where
|
where
|
||||||
R: Resolver<S> + 'static,
|
R: Resolver + 'static,
|
||||||
S: FromRequest + 'static,
|
|
||||||
{
|
{
|
||||||
actix_web::web::resource("/.well-known/webfinger")
|
actix_web::web::resource("/.well-known/webfinger")
|
||||||
.guard(WebfingerGuard)
|
.guard(WebfingerGuard)
|
||||||
.route(get().to(R::endpoint))
|
.route(get().to(endpoint::<R>))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A simple way to mount the webfinger service inside the /.well-known scope
|
/// A simple way to mount the webfinger service inside the /.well-known scope
|
||||||
|
@ -197,20 +197,19 @@ where
|
||||||
/// .data(())
|
/// .data(())
|
||||||
/// .service(
|
/// .service(
|
||||||
/// scope("/")
|
/// scope("/")
|
||||||
/// .service(resource::<(), MyResolver>())
|
/// .service(resource::<MyResolver>())
|
||||||
/// )
|
/// )
|
||||||
/// })
|
/// })
|
||||||
/// .bind("127.0.0.1:8000")
|
/// .bind("127.0.0.1:8000")
|
||||||
/// .start();
|
/// .start();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn scoped<S, R>() -> Resource
|
pub fn scoped<R>() -> Resource
|
||||||
where
|
where
|
||||||
R: Resolver<S> + 'static,
|
R: Resolver + 'static,
|
||||||
S: FromRequest + 'static,
|
|
||||||
{
|
{
|
||||||
actix_web::web::resource("/webfinger")
|
actix_web::web::resource("/webfinger")
|
||||||
.guard(WebfingerGuard)
|
.guard(WebfingerGuard)
|
||||||
.route(get().to(R::endpoint))
|
.route(get().to(endpoint::<R>))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The error created if the webfinger resource query is malformed
|
/// The error created if the webfinger resource query is malformed
|
||||||
|
@ -312,25 +311,20 @@ pub struct WebfingerQuery {
|
||||||
|
|
||||||
/// A trait to ease the implementation of Webfinger Resolvers
|
/// A trait to ease the implementation of Webfinger Resolvers
|
||||||
///
|
///
|
||||||
/// This trait can be implemented, and the provided `endpoint` method used to serve requests to an
|
|
||||||
/// Actix Web server.
|
|
||||||
///
|
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// use actix_webfinger::{Resolver, Webfinger};
|
/// use actix_webfinger::{Resolver, Webfinger};
|
||||||
/// use std::{future::Future, pin::Pin};
|
/// use std::{future::Future, pin::Pin};
|
||||||
///
|
///
|
||||||
/// struct MyResolver;
|
/// struct MyResolver;
|
||||||
///
|
///
|
||||||
/// impl<S> Resolver<S> for MyResolver
|
/// impl Resolver for MyResolver {
|
||||||
/// where
|
/// type State = ();
|
||||||
/// S: FromRequest,
|
|
||||||
/// {
|
|
||||||
/// type Error = CustomError;
|
/// type Error = CustomError;
|
||||||
///
|
///
|
||||||
/// fn find(
|
/// fn find(
|
||||||
/// account: &str,
|
/// account: &str,
|
||||||
/// domain: &str,
|
/// domain: &str,
|
||||||
/// _state: S
|
/// _state: Self::State,
|
||||||
/// ) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>> {
|
/// ) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>> {
|
||||||
/// let webfinger = Webfinger::new(&format!("{}@{}", account, domain));
|
/// let webfinger = Webfinger::new(&format!("{}@{}", account, domain));
|
||||||
///
|
///
|
||||||
|
@ -345,7 +339,7 @@ pub struct WebfingerQuery {
|
||||||
/// HttpServer::new(|| {
|
/// HttpServer::new(|| {
|
||||||
/// App::new()
|
/// App::new()
|
||||||
/// .data(())
|
/// .data(())
|
||||||
/// .service(resource::<Data<()>, MyResolver>())
|
/// .service(resource::<MyResolver>())
|
||||||
/// })
|
/// })
|
||||||
/// .bind("127.0.0.1:8000")?
|
/// .bind("127.0.0.1:8000")?
|
||||||
/// .run()
|
/// .run()
|
||||||
|
@ -354,30 +348,31 @@ pub struct WebfingerQuery {
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub trait Resolver<S>
|
pub trait Resolver {
|
||||||
where
|
type State: FromRequest + 'static;
|
||||||
S: FromRequest + 'static,
|
|
||||||
{
|
|
||||||
type Error: ResponseError + 'static;
|
type Error: ResponseError + 'static;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
account: &str,
|
account: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
state: S,
|
state: Self::State,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>>;
|
) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>>;
|
||||||
|
}
|
||||||
|
|
||||||
fn endpoint(
|
pub fn endpoint<R>(
|
||||||
(query, state): (Query<WebfingerQuery>, S),
|
(query, state): (Query<WebfingerQuery>, R::State),
|
||||||
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>>>> {
|
) -> Pin<Box<dyn Future<Output = Result<HttpResponse, R::Error>>>>
|
||||||
let WebfingerResource { account, domain } = query.into_inner().resource;
|
where
|
||||||
|
R: Resolver,
|
||||||
|
{
|
||||||
|
let WebfingerResource { account, domain } = query.into_inner().resource;
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
match Self::find(&account, &domain, state).await? {
|
match R::find(&account, &domain, state).await? {
|
||||||
Some(w) => Ok(w.respond()),
|
Some(w) => Ok(w.respond()),
|
||||||
None => Ok(HttpResponse::NotFound().finish()),
|
None => Ok(HttpResponse::NotFound().finish()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The webfinger Link type
|
/// The webfinger Link type
|
||||||
|
|
Loading…
Reference in a new issue