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

GraphQL - Implement account queries #3503

Merged
merged 17 commits into from
Jan 27, 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
1 change: 1 addition & 0 deletions big_tests/default.spec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
{suites, "tests", extdisco_SUITE}.
{suites, "tests", gdpr_SUITE}.
{suites, "tests", graphql_SUITE}.
{suites, "tests", graphql_account_SUITE}.
{suites, "tests", graphql_domain_SUITE}.
{suites, "tests", graphql_stanza_SUITE}.
{suites, "tests", inbox_SUITE}.
Expand Down
1 change: 1 addition & 0 deletions big_tests/dynamic_domains.spec
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"at the moment mod_pubsub doesn't support dynamic domains"}.

{suites, "tests", graphql_SUITE}.
{suites, "tests", graphql_account_SUITE}.
{suites, "tests", graphql_stanza_SUITE}.

{suites, "tests", graphql_domain_SUITE}.
Expand Down
1 change: 1 addition & 0 deletions big_tests/tests/graphql_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ init_per_suite(Config) ->

end_per_suite(Config) ->
dynamic_modules:restore_modules(Config),
escalus_fresh:clean(),
escalus:end_per_suite(Config).

init_per_group(admin_handler, Config) ->
Expand Down
494 changes: 494 additions & 0 deletions big_tests/tests/graphql_account_SUITE.erl

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions big_tests/tests/mongooseimctl_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1137,12 +1137,12 @@ graphql_wrong_arguments_number(Config) ->
simple_register(Config) ->
%% given
Domain = domain(),
{_, Password} = {<<"tyler">>, <<"durden">>},
{Name, Password} = {<<"tyler">>, <<"durden">>},
%% when
{R1, 0} = mongooseimctl("registered_users", [Domain], Config),
Before = length(string:tokens(R1, "\n")),
{_, 0} = mongooseimctl("register", [Domain, Password], Config),
{_, 0} = mongooseimctl("register", [Domain, Password], Config),
{_, 0} = mongooseimctl("register_identified", [Name, Domain, Password], Config),

{R2, 0} = mongooseimctl("registered_users", [Domain], Config),
After = length(string:tokens(R2, "\n")),
Expand Down
8 changes: 4 additions & 4 deletions big_tests/tests/rest_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ user_can_be_registered_and_removed(_Config) ->
assert_notinlist(<<"mike@", Domain/binary>>, Lusers2),
% invalid jid
CrBadUser = #{username => <<"m@ke">>, password => <<"nicniema">>},
{?BAD_REQUEST, <<"Invalid jid", _/binary>>} = post(admin, path("users"), CrBadUser),
{?BAD_REQUEST, <<"Invalid jid", _/binary>>} = delete(admin, path("users", ["@mike"])),
{?BAD_REQUEST, <<"Invalid JID", _/binary>>} = post(admin, path("users"), CrBadUser),
{?BAD_REQUEST, <<"Invalid JID", _/binary>>} = delete(admin, path("users", ["@mike"])),
%% {?FORBIDDEN, _} = delete(admin, path("users", ["mike"])), % he's already gone, but we
%% can't test it because ejabberd_auth_internal:remove_user/2 always returns ok, grrrr
ok.
Expand Down Expand Up @@ -397,10 +397,10 @@ password_can_be_changed(Config) ->
% test invalid calls
Res1 = putt(admin, path("users", ["bob"]),
#{newpass => <<>>}),
{?BAD_REQUEST, <<"empty password">>} = Res1,
{?BAD_REQUEST, <<"Empty password">>} = Res1,
Res2 = putt(admin, path("users", ["b@b"]),
#{newpass => NewPass}),
{?BAD_REQUEST, <<"invalid jid">>} = Res2,
{?BAD_REQUEST, <<"Invalid JID">>} = Res2,
ok.

list_contacts(Config) ->
Expand Down
70 changes: 70 additions & 0 deletions priv/graphql/schemas/admin/account.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
Allow admin to get information about accounts.
"""
type AccountAdminQuery @protected{
"List users per domain"
listUsers(domain: String!): [String!]!
"List users that didn't log in the last days or have never logged in. Globally or for a specified domain"
listOldUsers(domain: String, days: Int!): [String!]!
"Get number of users per domain"
countUsers(domain: String!): Int!
"Get number of users active in last days"
countActiveUsers(domain: String!, days: Int!): Int
"Check if a password is correct"
checkPassword(user: JID!, password: String!): CheckPasswordPayload
"Check if a password hash is correct (allowed methods: md5, sha). Works only for a plain passwords"
checkPasswordHash(user: JID!, passwordHash: String!, hashMethod: String!): CheckPasswordPayload
"Check if a user exists"
checkUser(user: JID!): CheckUserPayload
}

"""
Allow admin to manage user accounts.
"""
type AccountAdminMutation @protected{
"Register a user. Username will be generated when skipped"
registerUser(domain: String!, username: String, password: String!): UserPayload
"Remove a user"
removeUser(user: JID!): UserPayload
"""
Delete users that didn't log in the last days or have never logged in. Globally or for a specified domain.
Please use listOldUsers to check which users will be deleted
"""
removeOldUsers(domain: String, days: Int!): OldUsersPayload
Premwoik marked this conversation as resolved.
Show resolved Hide resolved
"Ban an account: kick sessions and set a random password"
banUser(user: JID!, reason: String!): UserPayload
"Change the password of a user"
changeUserPassword(user: JID!, newPassword: String!): UserPayload
}

"Remove old users payload"
type OldUsersPayload{
"Removed users"
users: [JID!]!
"Result message"
message: String!
}

"Modify user payload"
type UserPayload{
"User JID"
jid: JID!
"Result message"
message: String!
}

"Check password correctness payload"
type CheckPasswordPayload{
"Status of the password correctness"
correct: Bool!
"Result message"
message: String!
}

"Check user existence payload"
type CheckUserPayload{
"Status of the user existence"
exist: Bool!
"Result message"
message: String!
}
4 changes: 4 additions & 0 deletions priv/graphql/schemas/admin/admin_schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ type AdminQuery{
domains: DomainAdminQuery
"Check authorization status"
checkAuth: AuthStatus
"Account management"
account: AccountAdminQuery
stanza: StanzaAdminQuery
}

Expand All @@ -20,6 +22,8 @@ Contains all admin available mutations
Only an authenticated admin can execute these mutations.
"""
type AdminMutation @protected{
"Account management"
account: AccountAdminMutation
"Modify domains properties or create/destroy domain"
domains: DomainAdminMutation
stanza: StanzaAdminMutation
Expand Down
16 changes: 16 additions & 0 deletions priv/graphql/schemas/user/account.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Allow user to get information about account.
Premwoik marked this conversation as resolved.
Show resolved Hide resolved
"""
type AccountUserQuery @protected{
field: Bool
}

"""
Allow user to manage own account.
"""
type AccountUserMutation @protected{
"Remove an account"
unregister: String
"Change the password of an account"
changePassword(newPassword: String!): String
}
4 changes: 4 additions & 0 deletions priv/graphql/schemas/user/user_schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Only an authenticated user can execute these queries.
type UserQuery{
"Check authorization status"
checkAuth: UserAuthInfo
"Account management query"
account: AccountUserQuery
}

"""
Expand All @@ -19,4 +21,6 @@ Only an authenticated user can execute these mutations.
type UserMutation @protected{
"Something to not leave type without fields"
field: String
"Account management mutation"
account: AccountUserMutation
}
Loading