diff options
Diffstat (limited to 'Bugzilla/WebService/User.pm')
-rw-r--r-- | Bugzilla/WebService/User.pm | 292 |
1 files changed, 252 insertions, 40 deletions
diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm index deb7518ec..988ae3cd5 100644 --- a/Bugzilla/WebService/User.pm +++ b/Bugzilla/WebService/User.pm @@ -28,7 +28,10 @@ use Bugzilla::Error; use Bugzilla::Group; use Bugzilla::User; use Bugzilla::Util qw(trim); -use Bugzilla::WebService::Util qw(filter validate); +use Bugzilla::WebService::Util qw(filter filter_wants validate); +use Bugzilla::Hook; + +use List::Util qw(first); # Don't need auth to login use constant LOGIN_EXEMPT => { @@ -70,14 +73,36 @@ sub login { $input_params->{'Bugzilla_password'} = $params->{password}; $input_params->{'Bugzilla_remember'} = $remember; - Bugzilla->login(); - return { id => $self->type('int', Bugzilla->user->id) }; + my $user = Bugzilla->login(); + + my $result = { id => $self->type('int', $user->id) }; + + # We will use the stored cookie value combined with the user id + # to create a token that can be used with future requests in the + # query parameters + my $login_cookie = first { $_->name eq 'Bugzilla_logincookie' } + @{ Bugzilla->cgi->{'Bugzilla_cookie_list'} }; + if ($login_cookie) { + $result->{'token'} = $user->id . "-" . $login_cookie->value; + } + + return $result; } sub logout { my $self = shift; Bugzilla->logout; - return undef; +} + +sub valid_login { + my ($self, $params) = @_; + defined $params->{login} + || ThrowCodeError('param_required', { param => 'login' }); + Bugzilla->login(); + if (Bugzilla->user->id && Bugzilla->user->login eq $params->{login}) { + return $self->type('boolean', 1); + } + return $self->type('boolean', 0); } ################# @@ -124,7 +149,9 @@ sub create { # $call = $rpc->call( 'User.get', { ids => [1,2,3], # names => ['testusera@redhat.com', 'testuserb@redhat.com'] }); sub get { - my ($self, $params) = validate(@_, 'names', 'ids'); + my ($self, $params) = validate(@_, 'names', 'ids', 'match', 'group_ids', 'groups'); + + Bugzilla->switch_to_shadow_db(); defined($params->{names}) || defined($params->{ids}) || defined($params->{match}) @@ -152,11 +179,11 @@ sub get { } my $in_group = $self->_filter_users_by_group( \@user_objects, $params); - @users = map {filter $params, { + @users = map { filter $params, { id => $self->type('int', $_->id), - real_name => $self->type('string', $_->name), - name => $self->type('string', $_->login), - }} @$in_group; + real_name => $self->type('string', $_->name), + name => $self->type('email', $_->login), + } } @$in_group; return { users => \@users }; } @@ -196,33 +223,47 @@ sub get { } } } - - my $in_group = $self->_filter_users_by_group( - \@user_objects, $params); - if (Bugzilla->user->in_group('editusers')) { - @users = - map {filter $params, { - id => $self->type('int', $_->id), - real_name => $self->type('string', $_->name), - name => $self->type('string', $_->login), - email => $self->type('string', $_->email), - can_login => $self->type('boolean', $_->is_enabled ? 1 : 0), - email_enabled => $self->type('boolean', $_->email_enabled), - login_denied_text => $self->type('string', $_->disabledtext), - }} @$in_group; - - } - else { - @users = - map {filter $params, { - id => $self->type('int', $_->id), - real_name => $self->type('string', $_->name), - name => $self->type('string', $_->login), - email => $self->type('string', $_->email), - can_login => $self->type('boolean', $_->is_enabled ? 1 : 0), - }} @$in_group; + + my $in_group = $self->_filter_users_by_group(\@user_objects, $params); + foreach my $user (@$in_group) { + my $user_info = filter $params, { + id => $self->type('int', $user->id), + real_name => $self->type('string', $user->name), + name => $self->type('email', $user->login), + email => $self->type('email', $user->email), + can_login => $self->type('boolean', $user->is_enabled ? 1 : 0), + }; + + if (Bugzilla->user->in_group('editusers')) { + $user_info->{email_enabled} = $self->type('boolean', $user->email_enabled); + $user_info->{login_denied_text} = $self->type('string', $user->disabledtext); + } + + if (Bugzilla->user->id == $user->id) { + if (filter_wants($params, 'saved_searches')) { + $user_info->{saved_searches} = [ + map { $self->_query_to_hash($_) } @{ $user->queries } + ]; + } + } + + if (filter_wants($params, 'groups')) { + if (Bugzilla->user->id == $user->id || Bugzilla->user->in_group('editusers')) { + $user_info->{groups} = [ + map { $self->_group_to_hash($_) } @{ $user->groups } + ]; + } + else { + $user_info->{groups} = $self->_filter_bless_groups($user->groups); + } + } + + push(@users, $user_info); } + Bugzilla::Hook::process('webservice_user_get', + { webservice => $self, params => $params, users => \@users }); + return { users => \@users }; } @@ -259,6 +300,40 @@ sub _user_in_any_group { return 0; } +sub _filter_bless_groups { + my ($self, $groups) = @_; + my $user = Bugzilla->user; + + my @filtered_groups; + foreach my $group (@$groups) { + next unless ($user->in_group('editusers') || $user->can_bless($group->id)); + push(@filtered_groups, $self->_group_to_hash($group)); + } + + return \@filtered_groups; +} + +sub _group_to_hash { + my ($self, $group) = @_; + my $item = { + id => $self->type('int', $group->id), + name => $self->type('string', $group->name), + description => $self->type('string', $group->description), + }; + return $item; +} + +sub _query_to_hash { + my ($self, $query) = @_; + my $item = { + id => $self->type('int', $query->id), + name => $self->type('string', $query->name), + url => $self->type('string', $query->url), + }; + + return $item; +} + 1; __END__ @@ -277,6 +352,10 @@ log in/out using an existing account. See L<Bugzilla::WebService> for a description of how parameters are passed, and what B<STABLE>, B<UNSTABLE>, and B<EXPERIMENTAL> mean. +Although the data input and output is the same for JSONRPC, XMLRPC and REST, +the directions for how to access the data via REST is noted in each method +where applicable. + =head1 Logging In and Out =head2 login @@ -295,7 +374,7 @@ etc. This method logs in an user. =over -=item C<login> (string) - The user's login name. +=item C<login> (string) - The user's login name. =item C<password> (string) - The user's password. @@ -311,10 +390,14 @@ management of cookies across sessions. =item B<Returns> -On success, a hash containing one item, C<id>, the numeric id of the -user that was logged in. A set of http cookies is also sent with the -response. These cookies must be sent along with any future requests -to the webservice, for the duration of the session. +On success, a hash containing two items, C<id>, the numeric id of the +user that was logged in, and a C<token> which can be passed in +the parameters as authentication in other calls. A set of http cookies +is also sent with the response. These cookies *or* the token can be sent +along with any future requests to the webservice, for the duration of the +session. Note that cookies are not accepted for GET requests for JSONRPC +and REST for security reasons. You may, however, use the token or valid +login parameters for those requests. =item B<Errors> @@ -360,6 +443,50 @@ Log out the user. Does nothing if there is no user logged in. =back +=head2 valid_login + +B<UNSTABLE> + +=over + +=item B<Description> + +This method will verify whether a client's cookies or current login +token is still valid or have expired. A valid username must be provided +as well that matches. + +=item B<Params> + +=over + +=item C<login> + +The login name that matches the provided cookies or token. + +=item C<token> + +(string) Persistent login token current being used for authentication (optional). +Cookies passed by client will be used before the token if both provided. + +=back + +=item B<Returns> + +Returns true/false depending on if the current cookies or token are valid +for the provided username. + +=item B<Errors> (none) + +=item B<History> + +=over + +=item Added in Bugzilla B<5.0>. + +=back + +=back + =head1 Account Creation =head2 offer_account_by_email @@ -419,6 +546,13 @@ actually receive an email. This function does not check that. You must be logged in and have the C<editusers> privilege in order to call this function. +=item B<REST> + +POST /user + +The params to include in the POST body as well as the returned data format, +are the same as below. + =item B<Params> =over @@ -462,6 +596,8 @@ password is under three characters.) =item Error 503 (Password Too Long) removed in Bugzilla B<3.6>. +=item REST API call added in Bugzilla B<5.0>. + =back =back @@ -478,6 +614,18 @@ B<STABLE> Gets information about user accounts in Bugzilla. +=item B<REST> + +To get information about a single user: + +GET /user/<user_id_or_name> + +To search for users by name, group using URL params same as below: + +GET /user + +The returned data format is the same as below. + =item B<Params> B<Note>: At least one of C<ids>, C<names>, or C<match> must be specified. @@ -539,6 +687,14 @@ match string. Setting C<include_disabled> to C<true> will include disabled users in the returned results even if their username doesn't fully match the input string. +=item B<History> + +=over + +=item REST API call added in Bugzilla B<5.0>. + +=back + =back =item B<Returns> @@ -581,10 +737,60 @@ C<string> A text field that holds the reason for disabling a user from logging into bugzilla, if empty then the user account is enabled. Otherwise it is disabled/closed. +=item groups + +C<array> An array of group hashes the user is a member of. Each hash describes +the group and contains the following items: + +=over + +=item id + +C<int> The group id + +=item name + +C<string> The name of the group + +=item description + +C<string> The description for the group + +=back + +=over + +=item saved_searches + +C<array> An array of hashes, each of which represents a user's saved search and has +the following keys: + +=over + +=item id + +C<int> An integer id uniquely identifying the saved search. + +=item name + +C<string> The name of the saved search. + +=item url + +C<string> The CGI parameters for the saved search. + +=back + +B<Note>: The elements of the returned array (i.e. hashes) are ordered by the +name of each saved search. + +=back + B<Note>: If you are not logged in to Bugzilla when you call this function, you will only be returned the C<id>, C<name>, and C<real_name> items. If you are logged in and not in editusers group, you will only be returned the C<id>, C<name>, -C<real_name>, C<email>, and C<can_login> items. +C<real_name>, C<email>, and C<can_login> items. The groups returned are filtered +based on your permission to bless each group. =back @@ -625,9 +831,15 @@ exist or you do not belong to it. =item C<include_disabled> added in Bugzilla B<4.0>. Default behavior for C<match> has changed to only returning enabled accounts. +=item C<groups> Added in Bugzilla B<4.4>. + +=item C<saved_searches> Added in Bugzilla B<4.4>. + =item Error 804 has been added in Bugzilla 4.0.9 and 4.2.4. It's now illegal to pass a group name you don't belong to. =back +=item REST API call added in Bugzilla B<5.0>. + =back |