From bf3847bc35ba04d7ac2e8b2a37205509e4f3eab2 Mon Sep 17 00:00:00 2001 From: gspasov Date: Tue, 26 Mar 2019 20:44:24 +0200 Subject: [PATCH 1/2] Added Feature for JoinLink to Room, created REST API for getting room_id from join_link_id --- apps/roster/include/roster.hrl | 6 +++ apps/roster/include/static/rest_var.hrl | 1 + apps/roster/src/protocol/roster_room.erl | 9 +++- apps/roster/src/rest/rest_group_join_link.erl | 41 +++++++++++++++++++ apps/roster/src/rest/rest_handler.erl | 1 + apps/roster/src/roster.erl | 3 +- apps/roster/src/roster_db.erl | 10 +++++ rebar.config | 3 +- 8 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 apps/roster/src/rest/rest_group_join_link.erl diff --git a/apps/roster/include/roster.hrl b/apps/roster/include/roster.hrl index c01d4edbd..394fd1521 100644 --- a/apps/roster/include/roster.hrl +++ b/apps/roster/include/roster.hrl @@ -18,6 +18,7 @@ -define(FILE_GROUP, <<"FILE_DATA">>). -define(LANG_GROUP, <<"LANGUAGE_SETTINGS">>). -define(DUMMY_GROUP, <<"DUMMY_GROUP">>). +-define(LINKS_GROUP, <<"LINKS">>). %% #'Feature'{} file group keys -define(SIZE_KEY , <<"SIZE">>). @@ -35,6 +36,7 @@ -define(LANG_KEY , <<"LANGUAGE">>). -define(TRANSLATION_KEY , <<"TRANSLATION">>). -define(USERS_KEY , <<"USERS">>). +-define(GROUP_JOIN_LINK_KEY , <<"GROUP_JOIN_LINK">>). %% #'Feature'{} language group keys -define(DEFAULT_LANGUAGE_KEY, <<"DEFAULT_LANGUAGE">>). @@ -143,6 +145,10 @@ created = 0 :: [] | integer(), %% datetime field for sorting status = [] :: [] | gen | check | add | delete | update }). +-record('JoinLink', {id = [] :: [] | binary(), + room_id = [] :: [] | binary(), + type = [] :: [] | room}). + -record('Room', {id = [] :: [] | binary(), name = [] :: [] | binary(), links = [] :: [] | list(#'Link'{}), diff --git a/apps/roster/include/static/rest_var.hrl b/apps/roster/include/static/rest_var.hrl index 22c1afb79..5b2bb29bf 100644 --- a/apps/roster/include/static/rest_var.hrl +++ b/apps/roster/include/static/rest_var.hrl @@ -14,6 +14,7 @@ -define(MSG_PUSH_ENDPOINT, "/push/message"). -define(ROOM_ENDPOINT, "/room"). +-define(ROOM_JOIN_ID_ENDPOINT, "/room/join/id"). -define(PUBLISH_ENDPOINT, "/publish"). -define(USERS_ENDPOINT, "/users"). -define(METRICS_ENDPOINT, "/metrics"). diff --git a/apps/roster/src/protocol/roster_room.erl b/apps/roster/src/protocol/roster_room.erl index ee20e2b6f..4f0a48325 100644 --- a/apps/roster/src/protocol/roster_room.erl +++ b/apps/roster/src/protocol/roster_room.erl @@ -35,8 +35,15 @@ info(#'Room'{status = create, id = <>, name = Name, admins = [Owner <<"sys_", _/binary>> -> Owner end, Admin = Adm#'Member'{id = [], status = admin, feed_id = #muc{name = Room}, update = roster:now_msec()}, + RoomJoinId = roster_db:generate_room_join_id(), + JoinLinkFeature = #'Feature'{id = list_to_binary(io_lib:format("~s_~p", [Room, erlang:unique_integer([monotonic, positive])])), + key = ?GROUP_JOIN_LINK_KEY, + value = list_to_binary(io_lib:format("https://web.nynja.net/room/join/~s", [RoomJoinId])), + group = ?LINKS_GROUP}, + kvs:put(#'JoinLink'{id = RoomJoinId, room_id = Room, type = room}), info(R#'Room'{admins = [Admin|lists:keydelete(OwnPId, #'Member'.phone_id, Admins)], - members = lists:keydelete(OwnPId, #'Member'.phone_id, Members)}, + members = lists:keydelete(OwnPId, #'Member'.phone_id, Members), + settings = [JoinLinkFeature]}, Req, State#cx{state = verified}); _ -> {reply, {bert, #io{code = #error{code = invalid_data}}}, Req, State} end; diff --git a/apps/roster/src/rest/rest_group_join_link.erl b/apps/roster/src/rest/rest_group_join_link.erl new file mode 100644 index 000000000..f6a5ce92a --- /dev/null +++ b/apps/roster/src/rest/rest_group_join_link.erl @@ -0,0 +1,41 @@ +%%%----------------------------------------------------------------------------- +%%% @doc TODO: write documentation +%%% +%%% @see rest_handler:handle_request/3 +%%% @end +%%%----------------------------------------------------------------------------- +-module(rest_group_join_link). +-include("roster.hrl"). +-include_lib("roster/include/static/rest_var.hrl"). +-include_lib("kvs/include/metainfo.hrl"). + +-export([ + handle_request/3 + ]). + +handle_request('POST', Path, Req) -> + ReqData = Req:parse_post(), + roster:info(?MODULE, "~p:Request:~p:~p", [Req:get(method), Req:get(path), ReqData]), + + case parse_incomming_data(ReqData) of + {ok, RoomJoinId} -> + case kvs:get('JoinLink', RoomJoinId) of + {ok, #'JoinLink'{room_id = RoomId}} -> + {ResponseStatus, ResponseData} = {?HTTP_CODE_200, jsx:encode([{room_id, RoomId}])}, + roster:info(?MODULE, "ResponseData:~p", [ResponseData]), + Req:respond({ResponseStatus, [], ResponseData}); + {error, _} -> + rest_response_helper:error_400_response(Req) + % rest_response_helper:error_response(Req, ?HTTP_CODE_404, + % io_lib:format("No Room is associated with JoinId: ~s", [RoomJoinId])) + end; + {error, wrong_data} -> + rest_response_helper:error_400_response(Req) + end; + +handle_request(_, _, Req) -> + rest_response_helper:error_405_response(Req). + +-spec parse_incomming_data(list(tuple())) -> {ok, term()} | {error, wrong_data}. +parse_incomming_data([{"room_join_id", RoomJoinId}]) -> {ok, list_to_binary(RoomJoinId)}; +parse_incomming_data(_) -> {error, wrong_data}. \ No newline at end of file diff --git a/apps/roster/src/rest/rest_handler.erl b/apps/roster/src/rest/rest_handler.erl index 6a4375066..2cd6269ba 100644 --- a/apps/roster/src/rest/rest_handler.erl +++ b/apps/roster/src/rest/rest_handler.erl @@ -81,6 +81,7 @@ handle_request(Method, Path, Req) %% NOTE! uncomment the row under to turn on call bubbles %% handle_request(_, ?RCI_BUBBLE_ENDPOINT, Req) -> rest_cri :handle_request(Req); +handle_request(Method, ?ROOM_JOIN_ID_ENDPOINT = Path, Req) -> rest_group_join_link:handle_request(Method, Path, Req); handle_request(Method, ?CSV_P2P_ENDPOINT = Path, Req) -> rest_chat_csv:handle_request(Method, Path, Req); handle_request(Method, ?CSV_MUC_ENDPOINT = Path, Req) -> rest_chat_csv:handle_request(Method, Path, Req); handle_request(Method, "/metrics" = Path, Req) -> rest_metric :handle_request(Method, Path, Req); diff --git a/apps/roster/src/roster.erl b/apps/roster/src/roster.erl index 33cdd0e84..06c66b2e3 100644 --- a/apps/roster/src/roster.erl +++ b/apps/roster/src/roster.erl @@ -102,7 +102,8 @@ tables() -> [ #table{name = 'Schedule', fields = record_info(fields, 'Schedule'), type = ordered_set}, #table{name = 'Whitelist', fields = record_info(fields, 'Whitelist')}, #table{name = 'StickerPack', fields = record_info(fields, 'StickerPack')}, - #table{name = 'FakeNumbers', fields = record_info(fields, 'FakeNumbers'), keys = [phone]} + #table{name = 'FakeNumbers', fields = record_info(fields, 'FakeNumbers'), keys = [phone]}, + #table{name = 'JoinLink', fields = record_info(fields, 'JoinLink')} ]. %% LOGGER diff --git a/apps/roster/src/roster_db.erl b/apps/roster/src/roster_db.erl index e0a7dfd37..5ab98e3f2 100644 --- a/apps/roster/src/roster_db.erl +++ b/apps/roster/src/roster_db.erl @@ -603,3 +603,13 @@ remigrate_default_contact_settings() -> kvs:delete(schema_migrations, 20181008144317), roster:migrate(). +generate_room_join_id() -> + RandomValue = list_to_binary( + string:sub_string( + string:uppercase( + base58:binary_to_base58( + crypto:strong_rand_bytes(7))), 1, 8)), + case kvs:get('JoinLink', RandomValue) of + {error, not_found} -> RandomValue; + {ok, _} -> generate_room_join_id() + end. \ No newline at end of file diff --git a/rebar.config b/rebar.config index 3000e846c..20f82ad00 100644 --- a/rebar.config +++ b/rebar.config @@ -30,7 +30,8 @@ {locus, ".*", {git, "https://github.com/g-andrade/locus.git",{tag,"master"}}}, {prometheus, ".*", {git, "https://github.com/deadtrickster/prometheus.erl",{tag,"master"}}}, {cowboy, ".*", {git, "git://github.com/voxoz/cowboy", {tag,"master"}}}, - {'erlang-uuid', ".*", {git, "https://github.com/avtobiff/erlang-uuid.git",{tag,"master"}}} + {'erlang-uuid', ".*", {git, "https://github.com/avtobiff/erlang-uuid.git",{tag,"master"}}}, + {'erl-base58', ".*", {git, "https://github.com/titan098/erl-base58.git", {tag,"master"}}} % {json_rec, ".*", {git, "https://github.com/justinkirby/json_rec.git",{tag,"master"}}} ]}. {erl_opts, [{parse_transform,lager_transform},{parse_transform, oc_transform},debug_info]}. \ No newline at end of file -- GitLab From bab6be8030354de0bddd0d956bef72719d2a9852 Mon Sep 17 00:00:00 2001 From: gspasov Date: Tue, 26 Mar 2019 21:02:46 +0200 Subject: [PATCH 2/2] Fixed error response --- apps/roster/src/rest/rest_group_join_link.erl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/roster/src/rest/rest_group_join_link.erl b/apps/roster/src/rest/rest_group_join_link.erl index f6a5ce92a..db7d6bd88 100644 --- a/apps/roster/src/rest/rest_group_join_link.erl +++ b/apps/roster/src/rest/rest_group_join_link.erl @@ -25,9 +25,8 @@ handle_request('POST', Path, Req) -> roster:info(?MODULE, "ResponseData:~p", [ResponseData]), Req:respond({ResponseStatus, [], ResponseData}); {error, _} -> - rest_response_helper:error_400_response(Req) - % rest_response_helper:error_response(Req, ?HTTP_CODE_404, - % io_lib:format("No Room is associated with JoinId: ~s", [RoomJoinId])) + rest_response_helper:error_response(Req, ?HTTP_CODE_404, + io_lib:format("No Room is associated with JoinId: ~s", [RoomJoinId])) end; {error, wrong_data} -> rest_response_helper:error_400_response(Req) -- GitLab