Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup things before the next release (0.10) #30

Merged
merged 24 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ddccbea
chore: fix typo
ctron Jan 26, 2024
31d584d
chore: clear warning
ctron Jan 26, 2024
215e9c2
refactor: make the values of the storage keys internal
ctron Jan 26, 2024
55b57c2
docs: add some docs
ctron Jan 26, 2024
ae155ba
build: go back to a simple version
ctron Jan 26, 2024
a2993c4
fix: drop unused type arguments, clean up
ctron Jan 26, 2024
962a94f
refactor: cleanups before the next release
ctron Jan 26, 2024
9f2cdd2
refactor: drop the legacy re-export
ctron Jan 26, 2024
243c864
chore: uptick version
ctron Jan 26, 2024
b0d8e3f
refactor: tweak the API a bit, make it public again, document
ctron Jan 26, 2024
c494a36
refactor: rename properties
ctron Jan 26, 2024
c8af310
refactor: destructure to ensure we consumed all the fields
ctron Jan 26, 2024
a901bb6
fix: the default options did not get applied
ctron Jan 26, 2024
68e8cfc
style: typos
ctron Jan 26, 2024
7c841a3
docs: uptick version in docs
ctron Jan 26, 2024
9247002
ci: update actions to non-deprecated ones
ctron Jan 26, 2024
aa7eb5a
chore: fix up examples after refactoring
ctron Jan 26, 2024
e156442
chore: drop patches section, we're good for now
ctron Jan 26, 2024
530cbb8
chore: more docs and cleanups
ctron Jan 26, 2024
28495f0
ci: try fixing compiler issue
ctron Jan 26, 2024
78440f6
ci: explicitly set toolchain
ctron Jan 26, 2024
e0f6924
chore: align visibility with login options
ctron Jan 26, 2024
5b9702d
chore: rename feature "router" to "nested-router"
ctron Jan 26, 2024
8d2bc39
refactor: allow retrieving the login state from the session
ctron Jan 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ jobs:
toolchain:
- stable
# minimum version: because of "clap_lex"
- "1.70"
- "1.71.1"

steps:

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install Rust ${{ matrix.toolchain }}
run: |
rustup toolchain install ${{ matrix.toolchain }} --component rustfmt,clippy --target wasm32-unknown-unknown
rustup default ${{ matrix.toolchain }}

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
Expand All @@ -39,7 +39,7 @@ jobs:

- name: Run cargo fmt
run: |
cargo fmt --all -- --check
cargo +${{ matrix.toolchain }} fmt --all -- --check

- name: Install binstall
run: |
Expand All @@ -51,25 +51,29 @@ jobs:

- name: Run cargo check
run: |
cargo check-all-features --target wasm32-unknown-unknown
cargo +${{ matrix.toolchain }} check-all-features --target wasm32-unknown-unknown

- name: Run cargo test
run: |
cargo test-all-features
cargo +${{ matrix.toolchain }} test-all-features

- name: Run cargo clippy
run: |
cargo clippy --target wasm32-unknown-unknown -- -D warnings
cargo +${{ matrix.toolchain }} clippy --target wasm32-unknown-unknown -- -D warnings

- name: Run cargo clippy (all features)
run: |
cargo +${{ matrix.toolchain }} clippy --all-features --target wasm32-unknown-unknown -- -D warnings

examples:

runs-on: ubuntu-22.04

steps:

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "yew-oauth2"
version = "0.9.3"
version = "0.10.0"
authors = ["Jens Reimann <jreimann@redhat.com>"]
edition = "2021"
license = "Apache-2.0"
Expand Down Expand Up @@ -33,7 +33,7 @@ web-sys = { version = "0.3", features = [
] }

openidconnect = { version = "3.0", optional = true }
yew-nested-router = { version = ">=0.6.3, <0.7", optional = true }
yew-nested-router = { version = "0.6.3", optional = true }

[features]
# Enable for Yew nested router support
Expand Down
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
Add to your `Cargo.toml`:

```toml
yew-oauth2 = "0.9"
yew-oauth2 = "0.10"
```

By default, the `router` integration is disabled, you can enable it using:
By default, the `router` integration for [`yew-nested-router`](https://github.com/ctron/yew-nested-router) is disabled,
you can enable it using:

```toml
yew-oauth2 = { version = "0.9", features = ["router"] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering, since the api is changing already anyway - coming at this as a yew beginner, this was a slightly confusing part, because I didn't realize that yew-nested-router and yew-router are mutually incompatible. Wouldn't naming this feature nested-router be more descriptive?

yew-oauth2 = { version = "0.10", features = ["router"] }
```

## OpenID Connect
Expand All @@ -31,14 +32,14 @@ use yew_oauth2::oauth2::*; // use `openid::*` when using OpenID connect

#[function_component(MyApplication)]
fn my_app() -> Html {
let config = Config {
client_id: "my-client".into(),
auth_url: "https://my-sso/auth/realms/my-realm/protocol/openid-connect/auth".into(),
token_url: "https://my-sso/auth/realms/my-realm/protocol/openid-connect/token".into(),
};
let config = Config::new(
"my-client",
"https://my-sso/auth/realms/my-realm/protocol/openid-connect/auth",
"https://my-sso/auth/realms/my-realm/protocol/openid-connect/token"
);

html!(
<OAuth2 config={config}>
<OAuth2 {config}>
<MyApplicationMain/>
</OAuth2>
)
Expand All @@ -48,13 +49,10 @@ fn my_app() -> Html {
fn my_app_main() -> Html {
let agent = use_auth_agent().expect("Must be nested inside an OAuth2 component");

let login = {
let agent = agent.clone();
Callback::from(move |_| {
let _ = agent.start_login();
})
};
let logout = Callback::from(move |_| {
let login = use_callback(agent.clone(), |_, agent| {
let _ = agent.start_login();
});
let logout = use_callback(agent, |_, agent| {
let _ = agent.logout();
});

Expand Down
2 changes: 2 additions & 0 deletions src/agent/client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Client implementations

mod oauth2;
#[cfg(feature = "openid")]
mod openid;
Expand Down
17 changes: 12 additions & 5 deletions src/agent/client/oauth2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ pub struct LoginState {
pub pkce_verifier: String,
}

/// An OAuth2 based client implementation
#[derive(Clone, Debug)]
pub struct OAuth2Client {
client: ::oauth2::basic::BasicClient,
client: BasicClient,
}

impl OAuth2Client {
Expand All @@ -41,19 +42,25 @@ impl OAuth2Client {

#[async_trait(?Send)]
impl Client for OAuth2Client {
type TokenResponse = ::oauth2::basic::BasicTokenResponse;
type TokenResponse = BasicTokenResponse;
type Configuration = oauth2::Config;
type LoginState = LoginState;
type SessionState = ();

async fn from_config(config: Self::Configuration) -> Result<Self, OAuth2Error> {
let oauth2::Config {
client_id,
auth_url,
token_url,
} = config;

let client = BasicClient::new(
ClientId::new(config.client_id),
ClientId::new(client_id),
None,
AuthUrl::new(config.auth_url)
AuthUrl::new(auth_url)
.map_err(|err| OAuth2Error::Configuration(format!("invalid auth URL: {err}")))?,
Some(
TokenUrl::new(config.token_url).map_err(|err| {
TokenUrl::new(token_url).map_err(|err| {
OAuth2Error::Configuration(format!("invalid token URL: {err}"))
})?,
),
Expand Down
30 changes: 16 additions & 14 deletions src/agent/client/openid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct OpenIdLoginState {

const DEFAULT_POST_LOGOUT_DIRECT_NAME: &str = "post_logout_redirect_uri";

/// An OpenID Connect based client implementation
#[derive(Clone, Debug)]
pub struct OpenIdClient {
/// The client
Expand Down Expand Up @@ -85,7 +86,16 @@ impl Client for OpenIdClient {
);

async fn from_config(config: Self::Configuration) -> Result<Self, OAuth2Error> {
let issuer = IssuerUrl::new(config.issuer_url)
let openid::Config {
client_id,
issuer_url,
end_session_url,
after_logout_url,
post_logout_redirect_name,
additional_trusted_audiences,
} = config;

let issuer = IssuerUrl::new(issuer_url)
.map_err(|err| OAuth2Error::Configuration(format!("invalid issuer URL: {err}")))?;

let metadata = ExtendedProviderMetadata::discover_async(issuer, async_http_client)
Expand All @@ -94,30 +104,22 @@ impl Client for OpenIdClient {
OAuth2Error::Configuration(format!("Failed to discover client: {err}"))
})?;

let end_session_url = config
.additional
.end_session_url
let end_session_url = end_session_url
.map(|url| Url::parse(&url))
.transpose()
.map_err(|err| {
OAuth2Error::Configuration(format!("Unable to parse end_session_url: {err}"))
})?
.or_else(|| metadata.additional_metadata().end_session_endpoint.clone());

let after_logout_url = config.additional.after_logout_url;

let client = CoreClient::from_provider_metadata(
metadata,
ClientId::new(config.client_id.clone()),
None,
);
let client = CoreClient::from_provider_metadata(metadata, ClientId::new(client_id), None);

Ok(Self {
client,
end_session_url,
after_logout_url,
post_logout_redirect_name: config.additional.post_logout_redirect_name,
additional_trusted_audiences: config.additional.additional_trusted_audiences,
post_logout_redirect_name,
additional_trusted_audiences,
})
}

Expand Down Expand Up @@ -271,7 +273,7 @@ impl OpenIdClient {
fn after_logout_url(&self) -> Option<String> {
if let Some(after) = &self.after_logout_url {
if Url::parse(after).is_ok() {
// test if the is an absolute URL
// test if this is an absolute URL
return Some(after.to_string());
}

Expand Down
9 changes: 6 additions & 3 deletions src/agent/config.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
use super::LoginOptions;
use super::{LoginOptions, LogoutOptions};
use crate::agent::Client;
use std::time::Duration;

#[doc(hidden)]
#[derive(Clone, Debug)]
pub struct AgentConfiguration<C: Client> {
pub config: C::Configuration,
pub scopes: Vec<String>,
pub grace_period: Duration,
pub audience: Option<String>,
pub options: Option<LoginOptions>,
pub valid_audiences: Option<Vec<String>>,

pub default_login_options: Option<LoginOptions>,
pub default_logout_options: Option<LogoutOptions>,
}

impl<C: Client> PartialEq for AgentConfiguration<C> {
fn eq(&self, other: &Self) -> bool {
self.config == other.config
&& self.scopes == other.scopes
&& self.grace_period == other.grace_period
&& self.audience == other.audience
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/agent/error.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
use crate::context::OAuth2Context;
use core::fmt::{Display, Formatter};

/// An error with the OAuth2 agent
#[derive(Debug)]
pub enum OAuth2Error {
/// Not initialized
NotInitialized,
/// Configuration error
Configuration(String),
/// Failed to start login
StartLogin(String),
/// Failed to handle login result
LoginResult(String),
/// Failing storing information
Storage(String),
/// Internal error
Internal(String),
}

Expand Down
Loading