auth_server.erl 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. -module(auth_server).
  2. -include_lib("server/include/conf.hrl").
  3. -include_lib("server/include/settings.hrl").
  4. -include_lib("server/include/log.hrl").
  5. -include_lib("server/include/authtoken.hrl").
  6. -include_lib("server/include/requests.hrl").
  7. -behaviour(gen_server).
  8. -export([store_token/3,start_link/0,
  9. robot_credentials/0,
  10. fake_credentials/0,
  11. get_user_info/1, get_user_info/2,
  12. get_user_info_by_user_id/1
  13. ]).
  14. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
  15. -define(SERVER, ?MODULE).
  16. -define(SPARE_LOGINS, [#'PlayerInfo'{name = <<"Abe">>, surname="Kobo", login = <<"dunes">>, avatar_url = <<"/files/users/user_dunes/avatar/1-small.jpg">>},
  17. #'PlayerInfo'{name = <<"Herman">>, surname="Hesse", login = <<"wolves">>, avatar_url = <<"/files/users/user_wolves/avatar/1-small.jpg">>},
  18. #'PlayerInfo'{name = <<"Ernest">>, surname = <<"Hemingway">>, login = <<"oldman">>, avatar_url = <<"/files/users/user_oldman/avatar/1-small.jpg">>},
  19. #'PlayerInfo'{name = <<"Erich Maria">>, surname = <<"Remarque">>, login = <<"imwesten">>, avatar_url = <<"/files/users/user_imwesten/avatar/1-small.jpg">>}]).
  20. -record(state, {
  21. spare = ?SPARE_LOGINS,
  22. tokens
  23. }).
  24. %% definition of user from zealot/include/user.hrl
  25. -record(user_info,
  26. {username,
  27. name,
  28. surname,
  29. age,
  30. avatar_url,
  31. sex,
  32. skill :: integer(),
  33. score :: integer()}).
  34. start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
  35. store_token(GameId, Token, UserId) when is_list(Token) -> store_token(GameId, list_to_binary(Token), UserId);
  36. store_token(GameId, Token, UserId) when is_binary(Token) -> gen_server:call(?SERVER, {store_token, GameId, Token, UserId}).
  37. get_user_info(Token) when is_list(Token) -> get_user_info(list_to_binary(Token));
  38. get_user_info(Token) when is_binary(Token) -> gen_server:call(?SERVER, {get_user_info, Token}).
  39. get_user_info(Token, Id) when is_list(Token) -> get_user_info(list_to_binary(Token), Id);
  40. get_user_info(Token, Id) when is_list(Id) -> get_user_info(Token, list_to_binary(Id));
  41. get_user_info(Token, Id) when is_binary(Token), is_binary(Id) -> gen_server:call(?SERVER, {get_user_info, Token, Id}).
  42. get_user_info_by_user_id(UserId) when is_list(UserId) -> get_user_info_by_user_id(list_to_binary(UserId));
  43. get_user_info_by_user_id(UserId) -> user_info(UserId).
  44. fake_credentials() -> gen_server:call(?SERVER, {fake_credentials}).
  45. robot_credentials() -> gen_server:call(?SERVER, {robot_credentials}).
  46. init([]) ->
  47. Tokens = ets:new(tokens, [private, ordered_set, {keypos, #authtoken.token}]),
  48. store_token(0,Tokens, <<?TEST_TOKEN>>, "maxim"),
  49. store_token(0,Tokens, <<?TEST_TOKEN2>>, "alice"),
  50. {ok, #state{tokens = Tokens}}.
  51. handle_call({store_token, GameId, Token, UserId}, _From, #state{tokens = E} = State) ->
  52. store_token(GameId, E, Token, UserId),
  53. {reply, Token, State};
  54. handle_call({get_user_info, Token}, _From, #state{tokens = E} = State) ->
  55. ?INFO("checking token: ~p", [Token]),
  56. case ets:lookup(E, Token) of
  57. [] ->
  58. ?INFO("token not found", []),
  59. {reply, false, State};
  60. List ->
  61. {authtoken, _, UserId} = hd(List),
  62. ?INFO("token was registred, getting user info for ~p",[UserId]),
  63. proc_lib:spawn_link(fun() ->
  64. Reply =
  65. case user_info(UserId) of
  66. {ok, UserInfo} ->
  67. ?INFO("..user info retrieved", []),
  68. UserInfo;
  69. {error, user_not_found} ->
  70. ?INFO("..no such user info, providing fake credentials", []),
  71. fake_credentials0(State#state.spare); %% for eunit tests. FIX
  72. {badrpc, _} ->
  73. ?INFO("..bad rpc, providing fake credentials", []),
  74. fake_credentials0(State#state.spare) %% for eunit tests. FIX
  75. end,
  76. gen_server:reply(_From, Reply)
  77. end),
  78. {noreply, State}
  79. end;
  80. handle_call({get_user_info, Token, Id}, _From, #state{tokens = E} = State) ->
  81. ?INFO("checking token: ~p", [Token]),
  82. case ets:lookup(E, Token) of
  83. [] ->
  84. ?INFO("token not found", []),
  85. {reply, false, State};
  86. _List ->
  87. Reply0 = fake_credentials0(State#state.spare),
  88. Reply = Reply0#'PlayerInfo'{id = Id},
  89. {reply, Reply, State}
  90. end;
  91. handle_call({fake_credentials}, _From, #state{spare = Spare} = State) -> H = fake_credentials0(Spare), {reply, H, State};
  92. handle_call({robot_credentials}, _From, #state{spare = Spare} = State) -> H = fake_credentials0(Spare), {reply, H#'PlayerInfo'{robot = true}, State};
  93. handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}.
  94. handle_cast(_Msg, State) -> {noreply, State}.
  95. handle_info(_Info, State) -> {noreply, State}.
  96. terminate(_Reason, _State) -> ok.
  97. code_change(_OldVsn, State, _Extra) -> {ok, State}.
  98. fake_credentials0(Spare) ->
  99. Pos = crypto:rand_uniform(1, length(Spare)),
  100. H0 = lists:nth(Pos, Spare),
  101. Id = list_to_binary(binary_to_list(H0#'PlayerInfo'.login) ++ integer_to_list(id_generator:get_id2())),
  102. H0#'PlayerInfo'{id = Id}.
  103. store_token(GameId, E, Token, UserId) ->
  104. ?INFO("storing token: ~p", [Token]),
  105. Data = #authtoken{token = Token, id = UserId},
  106. ets:insert(E, Data).
  107. user_info(UserId) ->
  108. case nsm_auth:get_user_info(UserId) of
  109. {ok, UserData} ->
  110. {ok, #'PlayerInfo'{id = list_to_binary(UserData#user_info.username),
  111. login = list_to_binary(UserData#user_info.username),
  112. name = utils:convert_if(UserData#user_info.name, binary),
  113. avatar_url = utils:convert_if(UserData#user_info.avatar_url, binary),
  114. skill = UserData#user_info.skill,
  115. score = UserData#user_info.score,
  116. surname = utils:convert_if(UserData#user_info.surname, binary)}};
  117. Error ->
  118. Error
  119. end.