/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

  1. %%%-------------------------------------------------------------------
  2. %%% @author Heinz N. Gies <heinz@licenser.net>
  3. %%% @copyright (C) 2011, Heinz N. Gies
  4. %%% @doc This module provides simple Session handling with the data
  5. %%% entirely stored in the cookie, aka on the client. The data
  6. %%% is encrypted using an AES 128 CBC encryption to prevent
  7. %%% tempering.
  8. %%% Any Erlang term can be used as Session data.
  9. %%%
  10. %%% @end
  11. %%% Created : 9 Dec 2011 by Heinz N. Gies <heinz@licenser.net>
  12. %%%-------------------------------------------------------------------
  13. -module(ds_web_session).
  14. %% API
  15. -export([get/1, set/2, get_session/3, set_session/4, rem_session/2]).
  16. %%%===================================================================
  17. %%% API
  18. %%%===================================================================
  19. get(Req) ->
  20. {ok, SessionCookieName} = application:get_env(ds_web, session_name),
  21. {ok, SessionKey} = application:get_env(ds_web, session_key),
  22. get_session(SessionCookieName, SessionKey, Req).
  23. set(Req, Session) ->
  24. {ok, SessionCookieName} = application:get_env(ds_web, session_name),
  25. {ok, SessionKey} = application:get_env(ds_web, session_key),
  26. set_session(SessionCookieName, SessionKey, Req, Session).
  27. %%--------------------------------------------------------------------
  28. %% @doc Retrieves the session data from the cookies, returns either a
  29. %% the term stored or undefined when no session was found.
  30. %% SessionKey needs to be of the size 16 or a multiplyer from it.
  31. %% @spec get_session(binary(), binary(), #http_req{})
  32. %% -> undefined | term()
  33. %% @end
  34. %%--------------------------------------------------------------------
  35. get_session(SessionCookieName, SessionKey, Req) ->
  36. case cowboy_req:cookie(SessionCookieName, Req) of
  37. {undefined, Req1} ->
  38. {undefined, Req1};
  39. {<<>>, Req1} ->
  40. {undefined, Req1};
  41. {SessionData, Req1} ->
  42. {dec_term(SessionKey, SessionData), Req1}
  43. end.
  44. %%--------------------------------------------------------------------
  45. %% @doc Sets the session data as a cookie in the Request.
  46. %% SessionKey needs to be of the size 16 or a multiplyer from it.
  47. %% @spec set_session(binary(), binary(), #http_req{}, term())
  48. %% -> {ok, #http_req{}}
  49. %% @end
  50. %%--------------------------------------------------------------------
  51. set_session(SessionCookieName, SessionKey, Req, Session) ->
  52. cowboy_req:set_resp_cookie(SessionCookieName, enc_term(SessionKey, Session), [{max_age, 365*24*3600}], Req).
  53. %%--------------------------------------------------------------------
  54. %% @doc Deletes the session data as a cookie in the Request.
  55. %% @spec rem_session(binary(), binary(), #http_req{}, term())
  56. %% -> {ok, #http_req{}}
  57. %% @end
  58. %%--------------------------------------------------------------------
  59. rem_session(SessionCookieName, Req) ->
  60. cowboy_req:set_resp_cookie(SessionCookieName, <<>>, [{max_age, 0}], Req).
  61. %%%===================================================================
  62. %%% Internal functions
  63. %%%===================================================================
  64. aes_dec(Key, Text) when is_binary(Text) ->
  65. <<Size:32, Messag/binary>> = Text,
  66. <<Msg:Size/binary, _/binary>> = crypto:block_decrypt(aes_ecb, Key, Messag),
  67. Msg.
  68. aes_enc(Key, Text) when is_binary(Text) ->
  69. MsgSize = size(Text),
  70. Missing = (16 - (MsgSize rem 16)) * 8,
  71. Enc = crypto:block_encrypt(aes_ecb, Key, <<Text/binary, 0:Missing>>),
  72. <<MsgSize:32, Enc/binary>>.
  73. enc_term(Key, Term) when is_binary(Key)->
  74. base64:encode(aes_enc(Key, term_to_binary(Term))).
  75. dec_term(Key, Term) when is_binary(Term), is_binary(Key) ->
  76. binary_to_term(aes_dec(Key, base64:decode(Term))).