Browse Source

persistent session

Maxim Sokhatsky 11 years ago
parent
commit
58188e8187

+ 1 - 0
apps/web/priv/static/doc/svg.js

@@ -28,6 +28,7 @@ function handle_web_socket(body) {
             removeChilds(document.getElementById('Stat-Right'));
             for (var i=0;i<games.length;i++) { statsRow(24, i,games); }
             for (var i=0;i<protocol.length;i++) { statsRow(340,i,protocol); }
+//            for (var i=0;i<reveals.length;i++) { statsRow(340,i,reveals); }
             break;
     }
 

+ 81 - 0
apps/web/src/js_session.erl

@@ -0,0 +1,81 @@
+-module(js_session).
+-author('Maxim Sokhatsky').
+-include_lib("n2o/include/wf.hrl").
+-include_lib("kvs/include/user.hrl").
+-include_lib("stdlib/include/ms_transform.hrl").
+-export(?SESSION_API).
+-compile(export_all).
+-record(state, {unique, node}).
+
+init(State,Ctx) -> {ok,State,Ctx}.
+finish(State,Ctx) -> {ok,State,Ctx}.
+
+generate_cookie(State, Ctx) -> 
+    wf:info(?MODULE,"Req: ~p",[?REQ]),
+    SessionUser = wf:cookie_req(<<"n2o-name">>,?REQ),
+    SessionId   = wf:cookie_req(<<"n2o-sid">>, ?REQ),
+    wf:info(?MODULE,"Session Init n2o-sid: ~p",[SessionId]),
+    {{D1,D2,D3},{T1,T2,T3}} = calendar:now_to_datetime(now()),
+    Till = {{D1,D2,D3+1},{T1,T2,T3}},
+    TTL = 24 * 60 * 60, % 1 day TTL
+    SessionCookie = case lookup_ets({SessionId,<<"auth">>}) of 
+        undefined ->
+            CookieValue = case kvs:get(user,SessionUser) of
+                {ok,User} ->
+                    SS = lists:keyfind(n2o,1,User#user.tokens),
+                    case SS of
+                        {n2o,SessionId} -> SessionId;
+                        _ -> new_cookie_value() end;
+                _ -> new_cookie_value() end,
+            Cookie = {{CookieValue,<<"auth">>},<<"/">>,now(),{TTL,Till},new},
+            ets:insert(cookies,Cookie),
+            wf:info(?MODULE,"Cookie New: ~p",[Cookie]), 
+            Cookie;
+        {{Session,Key},Path,Issued,{_TTL,_Till},Status} ->
+            case expired(Issued,{_TTL,_Till}) of
+                false ->
+                    Cookie = {{Session,Key},Path,Issued,{_TTL,_Till},Status},
+                    wf:info(?MODULE,"Cookie Same: ~p",[Cookie]),
+                    Cookie;
+                true -> Cookie = {{new_cookie_value(),<<"auth">>},<<"/">>,now(),{TTL,Till},new},
+                    ets:insert(cookies,Cookie), 
+                    wf:info(?MODULE,"Cookie Expired: ~p",[Cookie]),
+                    Cookie end;
+        _ -> error_logger:info_msg("Cookie Error"), skip
+    end,
+    {{ID,_},_,_,_,_} = SessionCookie,
+    put(session_id,ID),
+    wf:info(?MODULE,"State: ~p",[SessionCookie]),
+    {ok, State, Ctx#context{session=SessionCookie}}.
+
+expired(_Issued,{_TTL,Till}) -> false. %Till < calendar:now_to_datetime(now()).
+
+lookup_ets(Key) ->
+    Res = ets:lookup(cookies,Key),
+    wf:info(?MODULE,"Lookup ETS: ~p",[{Res,Key}]),
+    case Res of 
+         [] -> undefined;
+         [Value] -> Value;
+         Values -> Values end.
+
+clear() -> clear(session_id()).
+clear(Session) ->
+    [ ets:delete(cookies,X) || X <- ets:select(cookies,
+        ets:fun2ms(fun(A) when (element(1,element(1,A)) == Session) -> element(1,A) end)) ].
+
+session_id() -> get(session_id).
+new_cookie_value() ->
+    SessionKey = base64:encode(erlang:md5(term_to_binary({now(), make_ref()}))),
+    wf:wire(wf:f("document.cookie='~s=~s; path=/';",
+                [wf:to_list(session_cookie_name()),wf:to_list(SessionKey)])),
+    SessionKey.
+
+new_state() -> #state{unique=new_cookie_value()}.
+session_cookie_name() -> <<"n2o-sid">>.
+set_value(Key, Value) -> ets:insert(cookies,{{session_id(),Key},Value}), Value.
+get_value(Key, DefaultValue) -> 
+    Res = case lookup_ets({session_id(),Key}) of
+               undefined -> DefaultValue;
+               {_,Value} -> Value end,
+    wf:info(?MODULE,"Session Lookup Key ~p Value ~p",[Key,Res]),
+    Res.

+ 1 - 1
apps/web/src/logallow.erl

@@ -6,6 +6,6 @@ log_modules() -> [
     n2o_bullet,
     game_session,
     n2o_secret,
-    kvs,
+    js_session,
     okey
 ].

+ 37 - 8
apps/web/src/okey.erl

@@ -22,12 +22,36 @@ game_form() ->
     {h3, #dropdown{ id = h3, options = []}},
     {h4, #dropdown{ id = h4, options = []}} ]).
 
+new_user() ->
+    Imagionary = anonymous:imagionary_users(),
+    {Id,Name,Surname} = lists:nth(crypto:rand_uniform(1,length(Imagionary)),Imagionary),
+    FakeId = anonymous:fake_id(Id),
+    X = #user{
+        id = FakeId,
+        tokens=[{n2o,get(session_id)}],
+        names = Name,
+        surnames = Surname},
+    wf:wire(wf:f("document.cookie='~s=~s; path=/';", ["n2o-name",wf:to_list(FakeId)])),
+    kvs:put(X),
+    X.
+
 user() -> 
-    case wf:user() of undefined ->
-        Imagionary = anonymous:imagionary_users(),
-        {Id,Name,Surname} = lists:nth(crypto:rand_uniform(1,length(Imagionary)),Imagionary),
-        X = #user{id = anonymous:fake_id(Id),names = Name,surnames = Surname},
-        wf:user(X), X; U-> U end.
+    case wf:user() of
+        undefined ->
+            SessionUser = wf:cookie_req(<<"n2o-name">>,?REQ),
+            SessionId = get(session_id),
+            wf:info(?MODULE,"Auth User: ~p",[SessionUser]),
+            wf:info(?MODULE,"Auth Id: ~p",[SessionId]),
+            X = case kvs:get(user,SessionUser) of
+                {ok,User} ->
+                    SS = lists:keyfind(n2o,1,User#user.tokens),
+                    case SS of
+                        {n2o,SessionId} -> User;
+                        _ -> new_user() end;
+                _ -> new_user() end,
+            wf:user(X),
+            X;
+        U-> U end.
 
 color(Id,Color) -> wf:wire(wf:f("document.querySelector('#~s').style.color = \"~s\";",[Id,Color])).
 unselect(Id) -> color(Id,black).
@@ -93,13 +117,15 @@ body() ->
 event(terminate) -> wf:info(?MODULE,"terminate");
 
 event(init) -> 
+    js_session:generate_cookie([],?CTX),
+
     GamesIds = case game:get_all_games_ids() of
       [] -> [?GAMEID];
       List -> List end,
-    
+
     wf:update(games_ids,#dropdown{id = games_ids, value = ?GAMEID, options = 
       [#option{label = wf:to_list(GameId), value = wf:to_list(GameId)} || GameId <- GamesIds]}),
-    
+
     event(attach),
     event(join);
 
@@ -108,12 +134,15 @@ event(join) ->
     GameId = get(okey_game_id),
     wf:wire(protocol:join(wf:to_list(GameId)));
 event(take) -> 
+    wf:info(?MODULE,"Req: ~p",[?REQ]),
+    SessionId = wf:cookie_req(<<"n2o-sid">>,?CTX#context.req),
+    wf:info(?MODULE,"Session Internal Init n2o-sid: ~p",[wf:cookies()]),
     GameId = get(okey_game_id),
     wf:wire(protocol:take(wf:to_list(GameId), wf:q(take_src)));
 
 event(player_info) -> 
 %    wf:info(?MODULE,"Cowboy Cookies: ~p",[wf:cookies_req(?REQ)]),
-%    wf:info(?MODULE,"Cookie Reqt: ~p",[wf:cookie("Name","Value","/",0,?REQ)]),
+
     User = user(),
     wf:cookie(<<"user">>,<<"macim">>,<<"/ws/">>,24 * 60 * 60),
     Wire = protocol:player_info(

+ 6 - 1
rels/web/files/sys.config

@@ -1,7 +1,12 @@
 [
  {sync, [{sync_mode, nitrogen}]},
  {nsx_idgen, [{game_pool,5000000}]},
- {n2o, [{route,routes},{port,8443},{transition_port,8080},{log_modules,logallow},{pickler,n2o_pickle}]},
+ {n2o, [{route,routes},
+        {port,8443},
+        {transition_port,8080},
+        {log_modules,logallow},
+        {session,js_session},
+        {pickler,n2o_pickle}]},
  {server, [{log_modules,logallow}]},
  {face,[
     {http_address, "http://skyline.synrc.com"},