Skip to content

Commit 0f5f632

Browse files
committed
Added a possibility of external access to session interface
Added a option to use non-cookies based session ID storage Tests not implemented yet
1 parent 710eb66 commit 0f5f632

7 files changed

Lines changed: 300 additions & 79 deletions

File tree

cppcms/session_interface.h

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,24 @@
1717
#include <cppcms/serialization_classes.h>
1818
#include <string>
1919
#include <map>
20+
#include <set>
2021
#include <memory>
2122
#include <sstream>
2223
#include <typeinfo>
2324

2425
namespace cppcms {
26+
namespace impl {
27+
struct cached_settings;
28+
}
2529
namespace http {
2630
class context;
2731
class request;
2832
class response;
33+
class cookie;
2934
}
3035

3136
class session_api;
37+
class session_pool;
3238

3339
///
3440
/// \brief This exception is thrown when CSRF attempt is suspected:
@@ -42,6 +48,34 @@ class CPPCMS_API request_forgery_error : public cppcms_error {
4248
}
4349
};
4450

51+
52+
///
53+
/// API to handle session cookies.
54+
///
55+
/// This API allows two things:
56+
///
57+
/// (a) Integration with 3rd part web technologies to access CppCMS session, i.e. using CppCMS session
58+
/// from PHP or Java Servlets
59+
///
60+
/// (b) An API that allows to translate cookies session tracking system to a different
61+
/// method when cookies do not suite the design - for example for internal RPC
62+
/// systems, etc. Note incorrect use of non-cookies medium may expose you
63+
/// to security issues
64+
///
65+
class CPPCMS_API session_interface_cookie_adapter : public booster::noncopyable {
66+
public:
67+
virtual ~session_interface_cookie_adapter();
68+
///
69+
/// Set a new cookie value
70+
///
71+
virtual void set_cookie(http::cookie const &updated_cookie) = 0;
72+
///
73+
/// Get value of the cookie, it is guaranteed that \a name is
74+
/// what session_interface::session_cookie_name() returns
75+
///
76+
virtual std::string get_session_cookie(std::string const &name) = 0;
77+
};
78+
4579
///
4680
/// \brief This class provides an access to an application for session management
4781
///
@@ -69,11 +103,22 @@ class CPPCMS_API request_forgery_error : public cppcms_error {
69103
class CPPCMS_API session_interface : private booster::noncopyable {
70104
public:
71105

72-
/// \cond INTERNAL
106+
///
107+
/// Create cppcms::service independent session interface to be used
108+
/// for implementing interoperability with non-cppcms based web platforms
109+
///
110+
session_interface(session_pool &pool,session_interface_cookie_adapter &adapter);
111+
112+
///
113+
/// Creates session interface for the context - never should be used by users
114+
/// directly
115+
///
73116
session_interface(http::context &);
74-
~session_interface();
75-
/// \endcond
76117

118+
///
119+
/// destructor...
120+
///
121+
~session_interface();
77122
///
78123
/// Check if a \a key is set (assigned some value to it) in the session
79124
///
@@ -267,6 +312,14 @@ class CPPCMS_API session_interface : private booster::noncopyable {
267312
///
268313
bool load();
269314

315+
///
316+
/// Set alternative cookies interface and load session data, returns same value as load, note
317+
/// if any data was loaded from cookies it would be discarded
318+
///
319+
/// It can be used for use of an alternative session state medium
320+
///
321+
bool set_cookie_adapter_and_reload(session_interface_cookie_adapter &adapter);
322+
270323
///
271324
/// Save the session data, generally should not be called as it is saved automatically. However when
272325
/// writing asynchronous application and using custom slow storage devices like SQL it may be useful to control
@@ -335,11 +388,22 @@ class CPPCMS_API session_interface : private booster::noncopyable {
335388
///
336389
std::string get_csrf_token_cookie_name();
337390

391+
///
392+
/// Get the session cookie name
393+
///
394+
std::string session_cookie_name();
395+
396+
///
397+
/// Retrun a set of keys that are defined for a current session;
398+
///
399+
std::set<std::string> key_set();
338400
private:
339401
friend class http::response;
340402
friend class http::request;
341403

404+
void init();
342405

406+
impl::cached_settings const &cached_settings();
343407

344408
struct entry;
345409

cppcms/session_pool.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717

1818
namespace cppcms {
1919
class service;
20-
20+
namespace impl {
21+
struct cached_settings;
22+
}
2123
namespace sessions {
2224
class encryptor_factory;
2325
class session_storage_factory;
24-
};
26+
}
27+
namespace json { class value; }
2528

2629
///
2730
/// \brief This class provides an access to session management backends an allow customization.
@@ -31,14 +34,31 @@ namespace cppcms {
3134
///
3235
class CPPCMS_API session_pool: public booster::noncopyable {
3336
public:
34-
/// \cond INTERNAL
37+
///
38+
/// Constructor that is used together with CppCMS service
39+
///
3540
session_pool(service &srv);
41+
///
42+
/// Constructor that is used to create independent pool to access the session storage by external tools
43+
///
44+
session_pool(json::value const &v);
45+
46+
///
47+
/// Destructor
48+
///
3649
~session_pool();
3750

51+
///
52+
/// Initialize the pool - must be called before get() can be used
53+
///
54+
/// Note: it allows to install custom session_api, encryptor or storage functionality
55+
///
3856
void init();
3957

58+
///
59+
/// Get an actual object that is used to store/retreive session data
60+
///
4061
booster::shared_ptr<session_api> get();
41-
/// \endcond
4262

4363
///
4464
/// Assign your own implementation of session_api passing pointer to session_api_factory.
@@ -56,6 +76,8 @@ namespace cppcms {
5676
void storage(std::auto_ptr<sessions::session_storage_factory> s);
5777
private:
5878

79+
impl::cached_settings const &cached_settings();
80+
5981
void after_fork();
6082

6183
struct cookies_factory;
@@ -72,6 +94,7 @@ namespace cppcms {
7294
friend struct cookies_factory;
7395
friend struct dual_factory;
7496
friend struct sid_factory;
97+
friend class session_interface;
7598
friend class gc_job;
7699

77100
booster::hold_ptr<_data> d;

private/cached_settings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ namespace impl {
127127
struct cached_session {
128128
int timeout;
129129
std::string expire;
130+
bool disable_automatic_load;
130131
struct cached_cookies {
131132
std::string prefix;
132133
std::string domain;
@@ -140,6 +141,7 @@ namespace impl {
140141
{
141142
timeout = v.get("session.timeout",24*3600);
142143
expire = v.get("session.expire","browser");
144+
disable_automatic_load = v.get("session.disable_automatic_load",false);
143145
cookies.prefix = v.get("session.cookies.prefix","cppcms_session");
144146
cookies.domain = v.get("session.cookies.domain","");
145147
cookies.path = v.get("session.cookies.path","/");

src/http_context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void context::complete_response()
127127
void context::dispatch(booster::intrusive_ptr<application> app,std::string url,bool syncronous)
128128
{
129129
try {
130-
if(syncronous)
130+
if(syncronous && !app->context().service().cached_settings().session.disable_automatic_load)
131131
app->context().session().load();
132132
app->main(url);
133133
}

0 commit comments

Comments
 (0)