PageRenderTime 73ms CodeModel.GetById 41ms app.highlight 13ms RepoModel.GetById 17ms app.codeStats 0ms

/src/middleware/ewgi_session/ewgi_session_server_store.erl

http://github.com/skarab/ewgi
Erlang | 130 lines | 87 code | 13 blank | 30 comment | 1 complexity | 7e412a7163eaf6c7a78687344a3b4533 MD5 | raw file
  1%% @author Davide Marquês <nesrait@gmail.com>
  2%% @copyright 2009 Davide Marquês <nesrait@gmail.com>
  3%%
  4%% @doc Interface for server-side session stores.
  5%%
  6%% This store serves as an interface for stores that manage
  7%% client sessions on the server side using session_id's to
  8%% between differenciate the sessions.
  9%%
 10%% Currently cookies are needed for the client to hold the session_id.
 11%% BUT/TODO: we could also encode the session_id on the urls so it might
 12%% be a good idea to swap cookie_headers/4 for a inject_session_data_on_response/?
 13%% function defined on the ewgi_session module.
 14%% @end
 15%%
 16%% Licensed under the MIT license:
 17%% http://www.opensource.org/licenses/mit-license.php
 18
 19-module(ewgi_session_server_store).
 20-author('Davide Marquês <nesrait@gmail.com>').
 21
 22%% Session Store API
 23-export([load_session/2, delete_session/2, store_session/2]).
 24
 25%% Usage examples
 26-export([create_example/1, delete_example/1]).
 27
 28-import(ewgi_util_cookie, [cookie_headers/5, cookie_safe_encode/1, cookie_safe_decode/1]).
 29
 30-include("ewgi.hrl").
 31
 32-define(SESSION_ID, "ewgi.session_server_store.session_id").
 33-define(SESSION_SERVER_MODULE, ewgi_session_server).
 34
 35%%====================================================================
 36%% Session Store API
 37%%====================================================================
 38load_session(Ctx, [ServerId, CookieName, _CookiePath, _SecureCookie, Timeout, IncludeIp] = StoreArgs) ->
 39    case ewgi_api:get_header_value("cookie", Ctx) of
 40	undefined ->
 41	    ewgi_session2:new_session(Ctx);
 42	Cookies ->
 43	    CookieValues = ewgi_util_cookie:parse_cookie(Cookies),
 44	    case proplists:get_value(CookieName, CookieValues) of
 45		undefined ->
 46		    ewgi_session:new_session(Ctx);
 47		SidB64 ->
 48		    BinSid = cookie_safe_decode(SidB64),
 49		    case (catch(binary_to_term(BinSid))) of
 50			Sid when is_list(Sid) ->
 51			    Ctx1 = ewgi_api:store_data(?SESSION_ID, Sid, Ctx),
 52			    case ?SESSION_SERVER_MODULE:get_session(ServerId, Sid) of
 53				undefined ->
 54				    ewgi_session:new_session(Ctx1);
 55				Session ->
 56				    case ewgi_session:init_session(Ctx1, Session, Timeout, IncludeIp) of
 57					invalid_session ->
 58					    %% DISPLAY ERROR!?
 59					    Ctx_2 = ?MODULE:delete_session(Ctx, StoreArgs),
 60					    ewgi_session:new_session(Ctx_2);
 61					Ctx_2 ->
 62					    Ctx_2
 63				    end
 64			    end;
 65			_ ->
 66			    %% DISPLAY ERROR! {?MODULE, cookie_tampered}
 67			    ewgi_session:new_session(Ctx)
 68		    end
 69	    end
 70    end.
 71
 72store_session(Ctx, [ServerId, CookieName, CookiePath, SecureCookie, _Timeout, IncludeIp]) ->
 73    Sid = ewgi_api:find_data(?SESSION_ID, Ctx),
 74    case Sid of
 75	undefined ->
 76	    %% New session
 77	    Session = ewgi_session:get_session(Ctx, IncludeIp),
 78	    NewId = ?SESSION_SERVER_MODULE:save_new_session(ServerId, Session),
 79	    SidB64 = cookie_safe_encode(term_to_binary(NewId)),
 80	    cookie_headers(Ctx, CookieName, SidB64, CookiePath, SecureCookie);
 81	Sid ->
 82	    %% existing session
 83	    Updated = ewgi_session:session_updated(Ctx),
 84	    if Updated ->
 85		    Session = ewgi_session:get_session(Ctx, IncludeIp),
 86		    ?SESSION_SERVER_MODULE:save_session(ServerId, Sid, Session);
 87	       true -> ok %% nothing to do!
 88	    end,
 89	    Ctx
 90    end.
 91
 92delete_session(Ctx, [ServerId, CookieName, CookiePath, SecureCookie]) ->
 93    Sid = ewgi_api:find_data(?SESSION_ID, Ctx),
 94    case Sid of
 95	undefined -> ok;
 96	_ -> ?SESSION_SERVER_MODULE:delete_session(ServerId, Sid)
 97    end,
 98    Ctx1 = ewgi_api:store_data(?SESSION_ID, undefined, Ctx),
 99    cookie_headers(Ctx1, CookieName, [], CookiePath, SecureCookie).
100
101%%====================================================================
102%% example functions on how to use the session middleware
103%%====================================================================
104%% The server reference :: Pid | LocalName | {Node,Name} | {global,Name}
105-define(SESSION_SERVER_REF, ewgi_session_server).
106-define(COOKIE_PATH, "/").
107-define(SECURE_COOKIE, false).
108-define(INCLUDE_IP, true).
109-define(SESSION_TIMEOUT, 15 * 60 * 1000). %% 15 minutes
110-define(SESSION_STORE_ARGS, [
111			     ?SESSION_SERVER_REF,
112			     "server_session_id",
113				 ?COOKIE_PATH,
114			     ?SECURE_COOKIE,
115			     ?SESSION_TIMEOUT,
116			     ?INCLUDE_IP
117			    ]).
118
119create_example(Ctx) ->
120    SessionApp = fun ewgi_session:session_create_app/1,
121    Ctx1 = ?MODULE:load_session(Ctx, ?SESSION_STORE_ARGS),
122    Ctx2 = SessionApp(Ctx1),
123    ?MODULE:store_session(Ctx2, ?SESSION_STORE_ARGS).
124
125delete_example(Ctx) ->
126    SessionApp = fun ewgi_session:session_delete_app/1,
127    Ctx1 = ?MODULE:load_session(Ctx, ?SESSION_STORE_ARGS),
128    Ctx2 = SessionApp(Ctx1),
129    ?MODULE:store_session(Ctx2, ?SESSION_STORE_ARGS).
130