1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-07-01 04:05:09 +02:00

Feature: Add IdentityError to actix-identity crate. (#296)

* Add IdentityError to actix-identity crate.

In order to let crates in the actix web ecosystem interact correctly
with `actix_web::Error`, this commit introduces its own error type,
replacing the previous usage of `anyhow::Error`.

* Mend some clippy warnings on IdentityError.

* Split identity error into more granular versions.

- `MissingIdentityError` occurs whenever we attempt to gather
  information about an identity from a session, and fail.
- `LoginError` occurs whenever we attempt to login via an identity, and
  fail.

* Feedback for identity error implementation.

- `IdentityError` -> `GetIdentityError`
- Move error messages into Display impl where appropriate
- Split `id` and `get_identity` errors into two types
- Implement `source` on custom errors

* Expand identity error types with struct markers.

In order to get a little more future compatibility and reduce
abstraction leaking, this commit introduces some contextual structs to
our identity errors package.

* Improve doc message for SessionExpiryError.

Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>

* Improve identity error docs and messaging.

Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>

* Expand LostIdentityError with placeholder.

Adds a placeholder unit struct to the LostIdentityError variant of
GetIdentityError, which should let us expand on that variant with extra
context later if we like.

* Add From coercion for LostIdentityError.

Improve the ergonomics of using the LostIdentityError unit struct.

* Update Cargo.toml

* Update CHANGES.md

* expose identity error module

* fix error impl

Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
Joseph McCormick
2023-01-06 20:05:12 -06:00
committed by GitHub
parent 708aa945dc
commit 1ed893a08c
6 changed files with 188 additions and 29 deletions

View File

@ -6,9 +6,11 @@ use actix_web::{
http::StatusCode,
Error, FromRequest, HttpMessage, HttpRequest, HttpResponse,
};
use anyhow::{anyhow, Context};
use crate::config::LogoutBehaviour;
use crate::{
config::LogoutBehaviour,
error::{GetIdentityError, LoginError, LostIdentityError, MissingIdentityError},
};
/// A verified user identity. It can be used as a request extractor.
///
@ -95,13 +97,10 @@ impl IdentityInner {
}
/// Retrieve the user id attached to the current session.
fn get_identity(&self) -> Result<String, anyhow::Error> {
fn get_identity(&self) -> Result<String, GetIdentityError> {
self.session
.get::<String>(ID_KEY)
.context("Failed to deserialize the user identifier attached to the current session")?
.ok_or_else(|| {
anyhow!("There is no identity information attached to the current session")
})
.get::<String>(ID_KEY)?
.ok_or_else(|| MissingIdentityError.into())
}
}
@ -126,10 +125,11 @@ impl Identity {
/// }
/// }
/// ```
pub fn id(&self) -> Result<String, anyhow::Error> {
self.0.session.get(ID_KEY)?.ok_or_else(|| {
anyhow!("Bug: the identity information attached to the current session has disappeared")
})
pub fn id(&self) -> Result<String, GetIdentityError> {
self.0
.session
.get(ID_KEY)?
.ok_or_else(|| LostIdentityError.into())
}
/// Attach a valid user identity to the current session.
@ -149,7 +149,7 @@ impl Identity {
/// HttpResponse::Ok()
/// }
/// ```
pub fn login(ext: &Extensions, id: String) -> Result<Self, anyhow::Error> {
pub fn login(ext: &Extensions, id: String) -> Result<Self, LoginError> {
let inner = IdentityInner::extract(ext);
inner.session.insert(ID_KEY, id)?;
let now = OffsetDateTime::now_utc().unix_timestamp();
@ -200,31 +200,31 @@ impl Identity {
}
}
pub(crate) fn extract(ext: &Extensions) -> Result<Self, anyhow::Error> {
pub(crate) fn extract(ext: &Extensions) -> Result<Self, GetIdentityError> {
let inner = IdentityInner::extract(ext);
inner.get_identity()?;
Ok(Self(inner))
}
pub(crate) fn logged_at(&self) -> Result<Option<OffsetDateTime>, anyhow::Error> {
self.0
pub(crate) fn logged_at(&self) -> Result<Option<OffsetDateTime>, GetIdentityError> {
Ok(self
.0
.session
.get(LOGIN_UNIX_TIMESTAMP_KEY)?
.map(OffsetDateTime::from_unix_timestamp)
.transpose()
.map_err(anyhow::Error::from)
.transpose()?)
}
pub(crate) fn last_visited_at(&self) -> Result<Option<OffsetDateTime>, anyhow::Error> {
self.0
pub(crate) fn last_visited_at(&self) -> Result<Option<OffsetDateTime>, GetIdentityError> {
Ok(self
.0
.session
.get(LAST_VISIT_UNIX_TIMESTAMP_KEY)?
.map(OffsetDateTime::from_unix_timestamp)
.transpose()
.map_err(anyhow::Error::from)
.transpose()?)
}
pub(crate) fn set_last_visited_at(&self) -> Result<(), anyhow::Error> {
pub(crate) fn set_last_visited_at(&self) -> Result<(), LoginError> {
let now = OffsetDateTime::now_utc().unix_timestamp();
self.0.session.insert(LAST_VISIT_UNIX_TIMESTAMP_KEY, now)?;
Ok(())