Skip to content

Commit d660ebf

Browse files
authored
Merge branch 'master' into alternative-protobuf-implementation
2 parents 1780f7e + e61dbae commit d660ebf

File tree

14 files changed

+139
-107
lines changed

14 files changed

+139
-107
lines changed

actix-session/src/config.rs

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
//! Configuration options to tune the behaviour of [`SessionMiddleware`].
22
33
use actix_web::cookie::{time::Duration, Key, SameSite};
4+
use derive_more::From;
45

56
use crate::{storage::SessionStore, SessionMiddleware};
67

78
/// Determines what type of session cookie should be used and how its lifecycle should be managed.
89
///
910
/// Used by [`SessionMiddlewareBuilder::session_lifecycle`].
10-
#[derive(Debug, Clone)]
11+
#[derive(Debug, Clone, From)]
1112
#[non_exhaustive]
1213
pub enum SessionLifecycle {
1314
/// The session cookie will expire when the current browser session ends.
@@ -27,25 +28,16 @@ pub enum SessionLifecycle {
2728
PersistentSession(PersistentSession),
2829
}
2930

30-
impl From<BrowserSession> for SessionLifecycle {
31-
fn from(session: BrowserSession) -> Self {
32-
Self::BrowserSession(session)
33-
}
34-
}
35-
36-
impl From<PersistentSession> for SessionLifecycle {
37-
fn from(session: PersistentSession) -> Self {
38-
Self::PersistentSession(session)
39-
}
40-
}
41-
4231
/// A [session lifecycle](SessionLifecycle) strategy where the session cookie expires when the
4332
/// browser's current session ends.
4433
///
4534
/// When does a browser session end? It depends on the browser. Chrome, for example, will often
4635
/// continue running in the background when the browser is closed—session cookies are not deleted
4736
/// and they will still be available when the browser is opened again. Check the documentation of
4837
/// the browsers you are targeting for up-to-date information.
38+
///
39+
/// Due to its `Into<SessionLifecycle>` implementation, a `BrowserSession` can be passed directly
40+
/// to [`SessionMiddlewareBuilder::session_lifecycle()`].
4941
#[derive(Debug, Clone)]
5042
pub struct BrowserSession {
5143
state_ttl: Duration,
@@ -103,6 +95,26 @@ impl Default for BrowserSession {
10395
/// Persistent cookies have a pre-determined expiration, specified via the `Max-Age` or `Expires`
10496
/// attribute. They do not disappear when the current browser session ends.
10597
///
98+
/// Due to its `Into<SessionLifecycle>` implementation, a `PersistentSession` can be passed directly
99+
/// to [`SessionMiddlewareBuilder::session_lifecycle()`].
100+
///
101+
/// # Examples
102+
/// ```
103+
/// use actix_web::cookie::time::Duration;
104+
/// use actix_session::SessionMiddleware;
105+
/// use actix_session::config::{PersistentSession, TtlExtensionPolicy};
106+
///
107+
/// const SECS_IN_WEEK: i64 = 60 * 60 * 24 * 7;
108+
///
109+
/// // a session lifecycle with a time-to-live (expiry) of 1 week and default extension policy
110+
/// PersistentSession::default().session_ttl(Duration::seconds(SECS_IN_WEEK));
111+
///
112+
/// // a session lifecycle with the default time-to-live (expiry) and a custom extension policy
113+
/// PersistentSession::default()
114+
/// // this policy causes the session state's TTL to be refreshed on every request
115+
/// .session_ttl_extension_policy(TtlExtensionPolicy::OnEveryRequest);
116+
/// ```
117+
///
106118
/// [persistent]: https://www.whitehatsec.com/glossary/content/persistent-session-cookie
107119
#[derive(Debug, Clone)]
108120
pub struct PersistentSession {
@@ -113,10 +125,10 @@ pub struct PersistentSession {
113125
impl PersistentSession {
114126
/// Specifies how long the session cookie should live.
115127
///
116-
/// Defaults to 1 day if left unspecified.
117-
///
118128
/// The session TTL is also used as the TTL for the session state in the storage backend.
119129
///
130+
/// Defaults to 1 day.
131+
///
120132
/// A persistent session can live more than the specified TTL if the TTL is extended.
121133
/// See [`session_ttl_extension_policy`](Self::session_ttl_extension_policy) for more details.
122134
pub fn session_ttl(mut self, session_ttl: Duration) -> Self {
@@ -127,7 +139,7 @@ impl PersistentSession {
127139
/// Determines under what circumstances the TTL of your session should be extended.
128140
/// See [`TtlExtensionPolicy`] for more details.
129141
///
130-
/// Defaults to [`TtlExtensionPolicy::OnStateChanges`] if left unspecified.
142+
/// Defaults to [`TtlExtensionPolicy::OnStateChanges`].
131143
pub fn session_ttl_extension_policy(
132144
mut self,
133145
ttl_extension_policy: TtlExtensionPolicy,
@@ -148,23 +160,23 @@ impl Default for PersistentSession {
148160

149161
/// Configuration for which events should trigger an extension of the time-to-live for your session.
150162
///
151-
/// If you are using a [`BrowserSession`], `TtlExtensionPolicy` controls how often the TTL of
152-
/// the session state should be refreshed. The browser is in control of the lifecycle of the
153-
/// session cookie.
163+
/// If you are using a [`BrowserSession`], `TtlExtensionPolicy` controls how often the TTL of the
164+
/// session state should be refreshed. The browser is in control of the lifecycle of the session
165+
/// cookie.
154166
///
155-
/// If you are using a [`PersistentSession`], `TtlExtensionPolicy` controls both the expiration
156-
/// of the session cookie and the TTL of the session state.
167+
/// If you are using a [`PersistentSession`], `TtlExtensionPolicy` controls both the expiration of
168+
/// the session cookie and the TTL of the session state on the storage backend.
157169
#[derive(Debug, Clone)]
158170
#[non_exhaustive]
159171
pub enum TtlExtensionPolicy {
160172
/// The TTL is refreshed every time the server receives a request associated with a session.
161173
///
162174
/// # Performance impact
163-
/// Refreshing the TTL on every request is not free.
164-
/// It implies a refresh of the TTL on the session state. This translates into a request over
165-
/// the network if you are using a remote system as storage backend (e.g. Redis).
166-
/// This impacts both the total load on your storage backend (i.e. number of
167-
/// queries it has to handle) and the latency of the requests served by your server.
175+
/// Refreshing the TTL on every request is not free. It implies a refresh of the TTL on the
176+
/// session state. This translates into a request over the network if you are using a remote
177+
/// system as storage backend (e.g. Redis). This impacts both the total load on your storage
178+
/// backend (i.e. number of queries it has to handle) and the latency of the requests served by
179+
/// your server.
168180
OnEveryRequest,
169181

170182
/// The TTL is refreshed every time the session state changes or the session key is renewed.
@@ -197,8 +209,7 @@ pub(crate) const fn default_ttl_extension_policy() -> TtlExtensionPolicy {
197209
TtlExtensionPolicy::OnStateChanges
198210
}
199211

200-
/// A fluent builder to construct a [`SessionMiddleware`] instance with custom configuration
201-
/// parameters.
212+
/// A fluent, customized [`SessionMiddleware`] builder.
202213
#[must_use]
203214
pub struct SessionMiddlewareBuilder<Store: SessionStore> {
204215
storage_backend: Store,
@@ -236,6 +247,22 @@ impl<Store: SessionStore> SessionMiddlewareBuilder<Store> {
236247
/// Check out [`SessionLifecycle`]'s documentation for more details on the available options.
237248
///
238249
/// Default is [`SessionLifecycle::BrowserSession`].
250+
///
251+
/// # Examples
252+
/// ```
253+
/// use actix_web::cookie::{Key, time::Duration};
254+
/// use actix_session::{SessionMiddleware, config::PersistentSession};
255+
/// use actix_session::storage::CookieSessionStore;
256+
///
257+
/// const SECS_IN_WEEK: i64 = 60 * 60 * 24 * 7;
258+
///
259+
/// // creates a session middleware with a time-to-live (expiry) of 1 week
260+
/// SessionMiddleware::builder(CookieSessionStore::default(), Key::from(&[0; 64]))
261+
/// .session_lifecycle(
262+
/// PersistentSession::default().session_ttl(Duration::seconds(SECS_IN_WEEK))
263+
/// )
264+
/// .build();
265+
/// ```
239266
pub fn session_lifecycle<S: Into<SessionLifecycle>>(mut self, session_lifecycle: S) -> Self {
240267
match session_lifecycle.into() {
241268
SessionLifecycle::BrowserSession(BrowserSession {

actix-session/src/middleware.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ use crate::{
3535
/// [`SessionStore`]);
3636
/// - a secret key, to sign or encrypt the content of client-side session cookie.
3737
///
38+
/// # How did we choose defaults?
39+
/// You should not regret adding `actix-session` to your dependencies and going to production using
40+
/// the default configuration. That is why, when in doubt, we opt to use the most secure option for
41+
/// each configuration parameter.
42+
///
43+
/// We expose knobs to change the default to suit your needs—i.e., if you know what you are doing,
44+
/// we will not stop you. But being a subject-matter expert should not be a requirement to deploy
45+
/// reasonably secure implementation of sessions.
46+
///
47+
/// # Examples
3848
/// ```no_run
3949
/// use actix_web::{web, App, HttpServer, HttpResponse, Error};
4050
/// use actix_session::{Session, SessionMiddleware, storage::RedisActorSessionStore};
@@ -103,16 +113,6 @@ use crate::{
103113
/// .await
104114
/// }
105115
/// ```
106-
///
107-
/// ## How did we choose defaults?
108-
///
109-
/// You should not regret adding `actix-session` to your dependencies and going to production using
110-
/// the default configuration. That is why, when in doubt, we opt to use the most secure option for
111-
/// each configuration parameter.
112-
///
113-
/// We expose knobs to change the default to suit your needs—i.e., if you know what you are doing,
114-
/// we will not stop you. But being a subject-matter expert should not be a requirement to deploy
115-
/// reasonably secure implementation of sessions.
116116
#[derive(Clone)]
117117
pub struct SessionMiddleware<Store: SessionStore> {
118118
storage_backend: Rc<Store>,
@@ -125,7 +125,7 @@ impl<Store: SessionStore> SessionMiddleware<Store> {
125125
///
126126
/// To create a new instance of [`SessionMiddleware`] you need to provide:
127127
/// - an instance of the session storage backend you wish to use (i.e. an implementation of
128-
/// [`SessionStore]);
128+
/// [`SessionStore`]);
129129
/// - a secret key, to sign or encrypt the content of client-side session cookie.
130130
pub fn new(store: Store, key: Key) -> Self {
131131
Self::builder(store, key).build()
@@ -135,7 +135,7 @@ impl<Store: SessionStore> SessionMiddleware<Store> {
135135
///
136136
/// It takes as input the two required inputs to create a new instance of [`SessionMiddleware`]:
137137
/// - an instance of the session storage backend you wish to use (i.e. an implementation of
138-
/// [`SessionStore]);
138+
/// [`SessionStore`]);
139139
/// - a secret key, to sign or encrypt the content of client-side session cookie.
140140
pub fn builder(store: Store, key: Key) -> SessionMiddlewareBuilder<Store> {
141141
SessionMiddlewareBuilder::new(store, config::default_configuration(key))

actix-settings/CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
## Unreleased - 2022-xx-xx
44

5+
- Rename `AtError => Error`.
6+
- Remove `AtResult` type alias.
57

68
## 0.6.0 - 2022-07-31
9+
710
- Update Actix Web dependencies to v4 ecosystem.
811
- Rename `actix.ssl` settings object to `actix.tls`.
912
- `NoSettings` is now marked `#[non_exhaustive]`.
1013

1114
## 0.5.2 - 2022-07-31
15+
1216
- Adopted into @actix org from <https://github.com/jjpe/actix-settings>.

actix-settings/src/error.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ use std::{env::VarError, io, num::ParseIntError, path::PathBuf, str::ParseBoolEr
22

33
use toml::de::Error as TomlError;
44

5-
/// Convenience type alias for `Result<T, AtError>`.
6-
pub type AtResult<T> = std::result::Result<T, AtError>;
7-
85
/// Errors that can be returned from methods in this crate.
96
#[derive(Debug, Clone)]
10-
pub enum AtError {
7+
pub enum Error {
118
/// Environment variable does not exists or is invalid.
129
EnvVarError(VarError),
1310

@@ -42,7 +39,7 @@ pub enum AtError {
4239

4340
macro_rules! InvalidValue {
4441
(expected: $expected:expr, got: $got:expr,) => {
45-
crate::AtError::InvalidValue {
42+
crate::Error::InvalidValue {
4643
expected: $expected,
4744
got: $got.to_string(),
4845
file: file!(),
@@ -52,56 +49,56 @@ macro_rules! InvalidValue {
5249
};
5350
}
5451

55-
impl From<io::Error> for AtError {
52+
impl From<io::Error> for Error {
5653
fn from(err: io::Error) -> Self {
5754
Self::IoError(ioe::IoError::from(err))
5855
}
5956
}
6057

61-
impl From<ioe::IoError> for AtError {
58+
impl From<ioe::IoError> for Error {
6259
fn from(err: ioe::IoError) -> Self {
6360
Self::IoError(err)
6461
}
6562
}
6663

67-
impl From<ParseBoolError> for AtError {
64+
impl From<ParseBoolError> for Error {
6865
fn from(err: ParseBoolError) -> Self {
6966
Self::ParseBoolError(err)
7067
}
7168
}
7269

73-
impl From<ParseIntError> for AtError {
70+
impl From<ParseIntError> for Error {
7471
fn from(err: ParseIntError) -> Self {
7572
Self::ParseIntError(err)
7673
}
7774
}
7875

79-
impl From<TomlError> for AtError {
76+
impl From<TomlError> for Error {
8077
fn from(err: TomlError) -> Self {
8178
Self::TomlError(err)
8279
}
8380
}
8481

85-
impl From<VarError> for AtError {
82+
impl From<VarError> for Error {
8683
fn from(err: VarError) -> Self {
8784
Self::EnvVarError(err)
8885
}
8986
}
9087

91-
impl From<AtError> for io::Error {
92-
fn from(err: AtError) -> Self {
88+
impl From<Error> for io::Error {
89+
fn from(err: Error) -> Self {
9390
match err {
94-
AtError::EnvVarError(var_error) => {
91+
Error::EnvVarError(var_error) => {
9592
let msg = format!("Env var error: {}", var_error);
9693
io::Error::new(io::ErrorKind::InvalidInput, msg)
9794
}
9895

99-
AtError::FileExists(path_buf) => {
96+
Error::FileExists(path_buf) => {
10097
let msg = format!("File exists: {}", path_buf.display());
10198
io::Error::new(io::ErrorKind::AlreadyExists, msg)
10299
}
103100

104-
AtError::InvalidValue {
101+
Error::InvalidValue {
105102
expected,
106103
ref got,
107104
file,
@@ -115,24 +112,24 @@ impl From<AtError> for io::Error {
115112
io::Error::new(io::ErrorKind::InvalidInput, msg)
116113
}
117114

118-
AtError::IoError(io_error) => io_error.into(),
115+
Error::IoError(io_error) => io_error.into(),
119116

120-
AtError::ParseBoolError(parse_bool_error) => {
117+
Error::ParseBoolError(parse_bool_error) => {
121118
let msg = format!("Failed to parse boolean: {}", parse_bool_error);
122119
io::Error::new(io::ErrorKind::InvalidInput, msg)
123120
}
124121

125-
AtError::ParseIntError(parse_int_error) => {
122+
Error::ParseIntError(parse_int_error) => {
126123
let msg = format!("Failed to parse integer: {}", parse_int_error);
127124
io::Error::new(io::ErrorKind::InvalidInput, msg)
128125
}
129126

130-
AtError::ParseAddressError(string) => {
127+
Error::ParseAddressError(string) => {
131128
let msg = format!("Failed to parse address: {}", string);
132129
io::Error::new(io::ErrorKind::InvalidInput, msg)
133130
}
134131

135-
AtError::TomlError(toml_error) => {
132+
Error::TomlError(toml_error) => {
136133
let msg = format!("TOML error: {}", toml_error);
137134
io::Error::new(io::ErrorKind::InvalidInput, msg)
138135
}

0 commit comments

Comments
 (0)