Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GraphQL types for JID parts #3862

Merged
merged 6 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions big_tests/tests/graphql_account_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,15 @@ admin_register_user(Config) ->
% Try to register a user with existing name
Resp2 = register_user(Domain, Username, Password, Config),
?assertNotEqual(nomatch, binary:match(get_err_msg(Resp2), <<"already registered">>)),
% Try again, this time with a domain name that is not stringprepped
Resp3 = register_user(unprep(Domain), Username, Password, Config),
% Try again, this time with a name that is not stringprepped
Resp3 = register_user(unprep(Domain), unprep(Username), Password, Config),
?assertNotEqual(nomatch, binary:match(get_err_msg(Resp3), <<"already registered">>)),
% Try to register a user without any name
Resp4 = register_user(Domain, <<>>, Password, Config),
?assertNotEqual(nomatch, binary:match(get_err_msg(Resp4), <<"Invalid JID">>)).
?assertMatch({_, _}, binary:match(get_coercion_err_msg(Resp4), <<"empty_user_name">>)),
% Try to register a user with an invalid name
Resp5 = register_user(Domain, <<"@invalid">>, Password, Config),
?assertMatch({_, _}, binary:match(get_coercion_err_msg(Resp5), <<"failed_to_parse_user_name">>)).

admin_register_random_user(Config) ->
Password = <<"my_password">>,
Expand Down
24 changes: 12 additions & 12 deletions big_tests/tests/graphql_gdpr_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ groups() ->

admin_gdpr_tests() ->
[admin_retrieve_user_data,
admin_retrieve_user_data_for_unprepped_domain,
admin_retrieve_user_data_with_unprepped_name,
admin_gdpr_no_user_test,
admin_gdpr_empty_filename_test,
admin_gdpr_access_denied_erofs,
Expand All @@ -36,7 +36,7 @@ admin_gdpr_tests() ->

domain_admin_gdpr_tests() ->
[admin_retrieve_user_data,
admin_retrieve_user_data_for_unprepped_domain,
admin_retrieve_user_data_with_unprepped_name,
admin_gdpr_no_user_test,
domain_admin_retrieve_user_data_no_permission].

Expand Down Expand Up @@ -68,22 +68,22 @@ end_per_testcase(CaseName, Config) ->
% Admin test cases

admin_retrieve_user_data(Config) ->
Config1 = [{domain, domain()} | Config],
escalus:fresh_story_with_config(Config1, [{alice, 1}], fun admin_retrieve_user_data/2).
Config1 = escalus_fresh:create_users(Config, [{alice, 1}]),
User = escalus_users:get_username(Config1, alice),
admin_retrieve_user_data(Config1, User, domain()).

admin_retrieve_user_data_for_unprepped_domain(Config) ->
Config1 = [{domain, unprep(domain())} | Config],
escalus:fresh_story_with_config(Config1, [{alice, 1}], fun admin_retrieve_user_data/2).
admin_retrieve_user_data_with_unprepped_name(Config) ->
Config1 = escalus_fresh:create_users(Config, [{alice, 1}]),
User = escalus_users:get_username(Config1, alice),
admin_retrieve_user_data(Config1, unprep(User), unprep(domain())).

admin_retrieve_user_data(Config, Alice) ->
admin_retrieve_user_data(Config, User, Domain) ->
Filename = random_filename(Config),
Domain = ?config(domain, Config),
Res = admin_retrieve_personal_data(escalus_client:username(Alice), Domain,
list_to_binary(Filename), Config),
Res = admin_retrieve_personal_data(User, Domain, list_to_binary(Filename), Config),
ParsedResult = get_ok_value([data, gdpr, retrievePersonalData], Res),
?assertEqual(<<"Data retrieved">>, ParsedResult),
FullPath = get_mim_cwd() ++ "/" ++ Filename,
Dir = make_dir_name(Filename, escalus_client:username(Alice)),
Dir = make_dir_name(Filename, User),
ct:log("extracting logs ~s", [Dir]),
?assertMatch({ok, _}, zip:extract(FullPath, [{cwd, Dir}])).

Expand Down
66 changes: 42 additions & 24 deletions big_tests/tests/graphql_muc_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ admin_groups() ->

user_muc_tests() ->
[user_create_and_delete_room,
user_create_room_with_unprepped_domain,
user_create_room_with_unprepped_name,
user_try_delete_nonexistent_room,
user_try_delete_room_by_not_owner,
user_try_create_instant_room_with_nonexistent_domain,
Expand Down Expand Up @@ -74,6 +74,7 @@ user_muc_tests() ->
user_participant_set_user_role,
user_try_set_nonexistent_room_role,
user_can_enter_room,
user_cannot_enter_room_with_invalid_resource,
user_can_enter_room_with_password,
user_can_exit_room,
user_list_room_affiliations,
Expand All @@ -99,7 +100,7 @@ user_muc_not_configured_tests() ->

admin_muc_tests() ->
[admin_create_and_delete_room,
admin_create_room_with_unprepped_domain,
admin_create_room_with_unprepped_name,
admin_try_create_instant_room_with_nonexistent_domain,
admin_try_create_instant_room_with_nonexistent_user,
admin_try_delete_nonexistent_room,
Expand Down Expand Up @@ -154,7 +155,7 @@ admin_muc_not_configured_tests() ->

domain_admin_muc_tests() ->
[admin_create_and_delete_room,
admin_create_room_with_unprepped_domain,
admin_create_room_with_unprepped_name,
admin_try_create_instant_room_with_nonexistent_domain,
admin_try_delete_nonexistent_room,
domain_admin_create_and_delete_room_no_permission,
Expand Down Expand Up @@ -318,14 +319,16 @@ admin_create_and_delete_room_story(Config, Alice) ->
Res4 = list_rooms(MUCServer, Alice, null, null, Config),
?assertNot(contain_room(Name, get_ok_value(?LIST_ROOMS_PATH, Res4))).

admin_create_room_with_unprepped_domain(Config) ->
admin_create_room_with_unprepped_name(Config) ->
FreshConfig = escalus_fresh:create_users(Config, [{alice, 1}]),
AliceJid = escalus_users:get_jid(FreshConfig, alice),
Name = rand_name(),
MUCServer = unprep(muc_helper:muc_host()),
Res = create_instant_room(MUCServer, Name, AliceJid, <<"Ali">>, FreshConfig),
Name = <<$a, (rand_name())/binary>>, % make it start with a letter
MUCServer = muc_helper:muc_host(),
Res = create_instant_room(unprep(MUCServer), unprep(Name), AliceJid, <<"Ali">>, FreshConfig),
?assertMatch(#{<<"title">> := Name, <<"private">> := false, <<"usersNumber">> := 0},
get_ok_value(?CREATE_INSTANT_ROOM_PATH, Res)).
get_ok_value(?CREATE_INSTANT_ROOM_PATH, Res)),
Res2 = list_rooms(MUCServer, AliceJid, null, null, Config),
?assert(contain_room(Name, get_ok_value(?LIST_ROOMS_PATH, Res2))).

admin_try_create_instant_room_with_nonexistent_domain(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}],
Expand Down Expand Up @@ -990,14 +993,14 @@ user_create_and_delete_room_story(Config, Alice) ->
Res4 = user_list_rooms(Alice, MUCServer, null, null, Config),
?assertNot(contain_room(Name, get_ok_value(?LIST_ROOMS_PATH, Res4))).

user_create_room_with_unprepped_domain(Config) ->
user_create_room_with_unprepped_name(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}],
fun user_create_room_with_unprepped_domain_story/2).
fun user_create_room_with_unprepped_name_story/2).

user_create_room_with_unprepped_domain_story(Config, Alice) ->
Name = rand_name(),
MUCServer = unprep(muc_helper:muc_host()),
Res = user_create_instant_room(Alice, MUCServer, Name, <<"Ali">>, Config),
user_create_room_with_unprepped_name_story(Config, Alice) ->
Name = <<$a, (rand_name())/binary>>, % make it start with a letter
MUCServer = muc_helper:muc_host(),
Res = user_create_instant_room(Alice, unprep(MUCServer), unprep(Name), <<"Ali">>, Config),
?assertMatch(#{<<"title">> := Name, <<"private">> := false, <<"usersNumber">> := 0},
get_ok_value(?CREATE_INSTANT_ROOM_PATH, Res)).

Expand All @@ -1015,7 +1018,7 @@ user_try_create_instant_room_with_invalid_name(Config) ->

user_try_create_instant_room_with_invalid_name_story(Config, Alice) ->
Res = user_create_instant_room(Alice, muc_helper:muc_host(), <<"test room">>, <<"Ali">>, Config),
?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"Room name or domain is invalid">>)).
assert_coercion_err(Res, <<"failed_to_parse_room_name">>).

user_try_delete_nonexistent_room(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}],
Expand Down Expand Up @@ -1116,8 +1119,8 @@ user_send_message_to_room_with_specified_res_story(Config, _Alice, Bob, Bob2) ->
BobNick = <<"Bobek">>,
enter_room(RoomJID, Bob2, BobNick),
escalus:wait_for_stanza(Bob2),
% Send message
Res = user_send_message_to_room(Bob, RoomJID, Message, <<"res2">>, Config),
% Send message, the resource should be normalized to "res2"
Res = user_send_message_to_room(Bob, RoomJID, Message, <<"res₂"/utf8>>, Config),
?assertNotEqual(nomatch, binary:match(get_ok_value(?SEND_MESSAGE_PATH, Res),
<<"successfully">>)),
assert_is_message_correct(RoomJID, BobNick, <<"groupchat">>, Message,
Expand Down Expand Up @@ -1153,8 +1156,8 @@ user_send_private_message_with_specified_res(Config, Alice, Alice2, Bob) ->
enter_room(RoomJID, Bob, BobNick),
enter_room(RoomJID, Alice2, AliceNick),
escalus:wait_for_stanzas(Bob, 2),
% Send message
Res = user_send_private_message(Alice, RoomJID, Message, BobNick, <<"res2">>, Config),
% Send message, the resource should be normalized to "res2"
Res = user_send_private_message(Alice, RoomJID, Message, BobNick, <<"res₂"/utf8>>, Config),
assert_success(?SEND_PRIV_MESG_PATH, Res),
assert_is_message_correct(RoomJID, AliceNick, <<"chat">>, Message,
escalus:wait_for_stanza(Bob)).
Expand Down Expand Up @@ -1449,11 +1452,23 @@ user_can_enter_room(Config, Alice) ->
RoomJID = jid:from_binary(?config(room_jid, Config)),
Nick = <<"ali">>,
JID = jid:from_binary(escalus_utils:jid_to_lower(escalus_client:full_jid(Alice))),
Resource = escalus_client:resource(Alice),
Res = user_enter_room(Alice, RoomJID, Nick, Resource, null, Config),
% Resource should be normalized to "res1", which is Alice's connected resource
Res = user_enter_room(Alice, RoomJID, Nick, <<"res₁"/utf8>>, null, Config),
assert_success(?ENTER_ROOM_PATH, Res),
?assertMatch([#{nick := Nick, jid := JID}], get_room_users(RoomJID)).

user_cannot_enter_room_with_invalid_resource(Config) ->
muc_helper:story_with_room(Config, [], [{alice, 1}],
fun user_cannot_enter_room_with_invalid_resource/2).

user_cannot_enter_room_with_invalid_resource(Config, Alice) ->
RoomJID = jid:from_binary(?config(room_jid, Config)),
Nick = <<"ali">>,
Res1 = user_enter_room(Alice, RoomJID, Nick, <<"\n">>, null, Config),
assert_coercion_err(Res1, <<"failed_to_parse_resource_name">>),
Res2 = user_enter_room(Alice, RoomJID, Nick, <<>>, null, Config),
assert_coercion_err(Res2, <<"empty_resource_name">>).

user_can_enter_room_with_password(Config) ->
muc_helper:story_with_room(Config, [{password_protected, true}, {password, ?PASSWORD}],
[{alice, 1}, {bob, 1}],
Expand Down Expand Up @@ -1484,10 +1499,10 @@ user_can_exit_room(Config) ->
user_can_exit_room(Config, Alice) ->
RoomJID = jid:from_binary(?config(room_jid, Config)),
Nick = <<"ali">>,
Resource = escalus_client:resource(Alice),
enter_room(RoomJID, Alice, Nick),
?assertMatch([_], get_room_users(RoomJID)),
Res = user_exit_room(Alice, RoomJID, Nick, Resource, Config),
% Resource should be normalized to "res1", which is Alice's connected resource
Res = user_exit_room(Alice, RoomJID, Nick, <<"res₁"/utf8>>, Config),
assert_success(?EXIT_ROOM_PATH, Res),
?assertMatch([], get_room_users(RoomJID)).

Expand Down Expand Up @@ -1655,8 +1670,11 @@ user_list_room_affiliations_muc_not_configured_story(Config, Alice) ->

%% Helpers

assert_coercion_err(Res, Code) ->
?assertNotEqual(nomatch, binary:match(get_coercion_err_msg(Res), Code)).

assert_no_full_jid(Res) ->
?assertNotEqual(nomatch, binary:match(get_coercion_err_msg(Res), <<"jid_without_resource">>)).
assert_coercion_err(Res, <<"jid_without_resource">>).

assert_no_permission(Res) ->
?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"does not have permission">>)).
Expand Down
33 changes: 31 additions & 2 deletions big_tests/tests/graphql_muc_light_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ user_muc_light_tests() ->
user_create_room_with_unprepped_domain,
user_create_room_with_custom_fields,
user_create_identified_room,
user_create_room_with_unprepped_id,
user_change_room_config,
user_change_room_config_errors,
user_invite_user,
Expand Down Expand Up @@ -99,6 +100,7 @@ admin_muc_light_tests() ->
admin_create_room_with_unprepped_domain,
admin_create_room_with_custom_fields,
admin_create_identified_room,
admin_create_room_with_unprepped_id,
admin_change_room_config,
admin_change_room_config_with_custom_fields,
admin_change_room_config_errors,
Expand Down Expand Up @@ -129,6 +131,7 @@ domain_admin_muc_light_tests() ->
admin_create_room_with_custom_fields,
domain_admin_create_room_no_permission,
admin_create_identified_room,
admin_create_room_with_unprepped_id,
domain_admin_create_identified_room_no_permission,
admin_change_room_config,
admin_change_room_config_with_custom_fields,
Expand Down Expand Up @@ -313,7 +316,21 @@ user_create_identified_room_story(Config, Alice) ->
?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)),
% Try with an empty string passed as ID
Res4 = user_create_room(Alice, MucServer, <<"name">>, Subject, <<>>, Config),
?assertNotEqual(nomatch, binary:match(get_coercion_err_msg(Res4), <<"Given string is empty">>)).
?assertMatch({_, _}, binary:match(get_coercion_err_msg(Res4), <<"empty_room_name">>)).

user_create_room_with_unprepped_id(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}],
fun user_create_room_with_unprepped_id_story/2).

user_create_room_with_unprepped_id_story(Config, Alice) ->
MucServer = ?config(muc_light_host, Config),
Name = <<"first room">>,
Subject = <<"testing">>,
Id = <<"user_room_with_unprepped_id">>,
Res = user_create_room(Alice, unprep(MucServer), Name, Subject, unprep(Id), Config),
#{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
get_ok_value(?CREATE_ROOM_PATH, Res),
?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary_noprep(JID)).

user_change_room_config(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_change_room_config_story/2).
Expand Down Expand Up @@ -1001,7 +1018,19 @@ admin_create_identified_room_story(Config, Alice) ->
?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)),
% Try with an empty string passed as ID
Res4 = create_room(MucServer, <<"name">>, AliceBin, Subject, <<>>, Config),
?assertNotEqual(nomatch, binary:match(get_coercion_err_msg(Res4), <<"Given string is empty">>)).
?assertMatch({_, _}, binary:match(get_coercion_err_msg(Res4), <<"empty_room_name">>)).

admin_create_room_with_unprepped_id(Config) ->
FreshConfig = escalus_fresh:create_users(Config, [{alice, 1}]),
AliceBin = escalus_users:get_jid(FreshConfig, alice),
MucServer = ?config(muc_light_host, FreshConfig),
Name = <<"first room">>,
Subject = <<"testing">>,
Id = <<"room_with_unprepped_id">>,
Res = create_room(unprep(MucServer), Name, AliceBin, Subject, unprep(Id), FreshConfig),
#{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
get_ok_value(?CREATE_ROOM_PATH, Res),
?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary_noprep(JID)).

admin_change_room_config(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_change_room_config_story/2).
Expand Down
2 changes: 1 addition & 1 deletion priv/graphql/schemas/admin/account.gql
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Allow admin to manage user accounts.
"""
type AccountAdminMutation @protected{
"Register a user. Username will be generated when skipped"
registerUser(domain: DomainName!, username: String, password: String!): UserPayload
registerUser(domain: DomainName!, username: UserName, password: String!): UserPayload
@protected(type: DOMAIN, args: ["domain"])
"Remove the user's account along with all the associated personal data"
removeUser(user: JID!): UserPayload
Expand Down
2 changes: 1 addition & 1 deletion priv/graphql/schemas/admin/gdpr.gql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"Retrieve user's presonal data"
type GdprAdminQuery @protected{
"Retrieves all personal data from MongooseIM for a given user"
retrievePersonalData(username: String!, domain: DomainName!, resultFilepath: String!): String
retrievePersonalData(username: UserName!, domain: DomainName!, resultFilepath: String!): String
@protected(type: DOMAIN, args: ["domain"])
}
2 changes: 1 addition & 1 deletion priv/graphql/schemas/admin/muc.gql
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Allow admin to manage Multi-User Chat rooms.
type MUCAdminMutation @protected @use(modules: ["mod_muc"]){
"Create a MUC room under the given XMPP hostname"
#There is no @use directive because it is currently impossible to get HostType from mucDomain in directive code
createInstantRoom(mucDomain: DomainName!, name: String!, owner: JID!, nick: String!): MUCRoomDesc
createInstantRoom(mucDomain: DomainName!, name: RoomName!, owner: JID!, nick: String!): MUCRoomDesc
@protected(type: DOMAIN, args: ["owner"])
"Invite a user to a MUC room"
inviteUser(room: JID!, sender: JID!, recipient: JID!, reason: String): String
Expand Down
2 changes: 1 addition & 1 deletion priv/graphql/schemas/admin/muc_light.gql
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Allow admin to manage Multi-User Chat Light rooms.
type MUCLightAdminMutation @use(modules: ["mod_muc_light"]) @protected{
"Create a MUC light room under the given XMPP hostname"
#There is no @use directive because it is currently impossible to get HostType from mucDomain in directive code
createRoom(mucDomain: DomainName!, name: String!, owner: JID!, subject: String!, id: NonEmptyString, options: [RoomConfigDictEntryInput!]): Room
createRoom(mucDomain: DomainName!, name: String!, owner: JID!, subject: String!, id: RoomName, options: [RoomConfigDictEntryInput!]): Room
@protected(type: DOMAIN, args: ["owner"])
"Change configuration of a MUC Light room"
changeRoomConfiguration(room: JID!, owner: JID!, name: String!, subject: String!, options: [RoomConfigDictEntryInput!]): Room
Expand Down
2 changes: 1 addition & 1 deletion priv/graphql/schemas/admin/session.gql
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type SessionAdminQuery @protected{
countUserResources(user: JID!): Int
@protected(type: DOMAIN, args: ["user"])
"Get the resource string of the n-th session of a user"
getUserResource(user: JID!, number: Int): String
getUserResource(user: JID!, number: Int): ResourceName
@protected(type: DOMAIN, args: ["user"])
"Get the list of logged users with this status for a specified domain or globally"
listUsersWithStatus(domain: DomainName, status: String!): [UserStatus!]
Expand Down
8 changes: 7 additions & 1 deletion priv/graphql/schemas/global/scalar_types.gql
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ scalar Stanza @spectaql(options: [{ key: "example", value: "Hi!" }])
scalar JID @spectaql(options: [{ key: "example", value: "alice@localhost" }])
"The JID with resource"
scalar FullJID @spectaql(options: [{ key: "example", value: "alice@localhost/res1" }])
"XMPP Domain name (domain part of a JID)"
"XMPP user name (local part of a JID)"
scalar UserName @spectaql(options: [{ key: "example", value: "alice" }])
"XMPP room name (local part of a JID)"
scalar RoomName @spectaql(options: [{ key: "example", value: "my-chat-room" }])
"XMPP domain name (domain part of a JID)"
scalar DomainName @spectaql(options: [{ key: "example", value: "localhost" }])
"XMPP resource name (resource part of a JID)"
scalar ResourceName @spectaql(options: [{ key: "example", value: "res1" }])
"String that contains at least one character"
scalar NonEmptyString @spectaql(options: [{ key: "example", value: "xyz789" }])
"Integer that has a value above zero"
Expand Down
Loading