/new/apps/ds_web/src/ds_web_session.erl
http://github.com/Licenser/dividedspace · Erlang · 93 lines · 36 code · 17 blank · 40 comment · 0 complexity · ec156d3afece019f9ee2987358fceb29 MD5 · raw file
- %%%-------------------------------------------------------------------
- %%% @author Heinz N. Gies <heinz@licenser.net>
- %%% @copyright (C) 2011, Heinz N. Gies
- %%% @doc This module provides simple Session handling with the data
- %%% entirely stored in the cookie, aka on the client. The data
- %%% is encrypted using an AES 128 CBC encryption to prevent
- %%% tempering.
- %%% Any Erlang term can be used as Session data.
- %%%
- %%% @end
- %%% Created : 9 Dec 2011 by Heinz N. Gies <heinz@licenser.net>
- %%%-------------------------------------------------------------------
- -module(ds_web_session).
- %% API
- -export([get/1, set/2, get_session/3, set_session/4, rem_session/2]).
- %%%===================================================================
- %%% API
- %%%===================================================================
- get(Req) ->
- {ok, SessionCookieName} = application:get_env(ds_web, session_name),
- {ok, SessionKey} = application:get_env(ds_web, session_key),
- get_session(SessionCookieName, SessionKey, Req).
- set(Req, Session) ->
- {ok, SessionCookieName} = application:get_env(ds_web, session_name),
- {ok, SessionKey} = application:get_env(ds_web, session_key),
- set_session(SessionCookieName, SessionKey, Req, Session).
- %%--------------------------------------------------------------------
- %% @doc Retrieves the session data from the cookies, returns either a
- %% the term stored or undefined when no session was found.
- %% SessionKey needs to be of the size 16 or a multiplyer from it.
- %% @spec get_session(binary(), binary(), #http_req{})
- %% -> undefined | term()
- %% @end
- %%--------------------------------------------------------------------
- get_session(SessionCookieName, SessionKey, Req) ->
- case cowboy_req:cookie(SessionCookieName, Req) of
- {undefined, Req1} ->
- {undefined, Req1};
- {<<>>, Req1} ->
- {undefined, Req1};
- {SessionData, Req1} ->
- {dec_term(SessionKey, SessionData), Req1}
- end.
- %%--------------------------------------------------------------------
- %% @doc Sets the session data as a cookie in the Request.
- %% SessionKey needs to be of the size 16 or a multiplyer from it.
- %% @spec set_session(binary(), binary(), #http_req{}, term())
- %% -> {ok, #http_req{}}
- %% @end
- %%--------------------------------------------------------------------
- set_session(SessionCookieName, SessionKey, Req, Session) ->
- cowboy_req:set_resp_cookie(SessionCookieName, enc_term(SessionKey, Session), [{max_age, 365*24*3600}], Req).
- %%--------------------------------------------------------------------
- %% @doc Deletes the session data as a cookie in the Request.
- %% @spec rem_session(binary(), binary(), #http_req{}, term())
- %% -> {ok, #http_req{}}
- %% @end
- %%--------------------------------------------------------------------
- rem_session(SessionCookieName, Req) ->
- cowboy_req:set_resp_cookie(SessionCookieName, <<>>, [{max_age, 0}], Req).
- %%%===================================================================
- %%% Internal functions
- %%%===================================================================
- aes_dec(Key, Text) when is_binary(Text) ->
- <<Size:32, Messag/binary>> = Text,
- <<Msg:Size/binary, _/binary>> = crypto:block_decrypt(aes_ecb, Key, Messag),
- Msg.
- aes_enc(Key, Text) when is_binary(Text) ->
- MsgSize = size(Text),
- Missing = (16 - (MsgSize rem 16)) * 8,
- Enc = crypto:block_encrypt(aes_ecb, Key, <<Text/binary, 0:Missing>>),
- <<MsgSize:32, Enc/binary>>.
- enc_term(Key, Term) when is_binary(Key)->
- base64:encode(aes_enc(Key, term_to_binary(Term))).
- dec_term(Key, Term) when is_binary(Term), is_binary(Key) ->
- binary_to_term(aes_dec(Key, base64:decode(Term))).