File Coverage

blib/lib/WebService/Mattermost/V4/API/Resource/User.pm
Criterion Covered Total %
statement 6 11 54.5
branch n/a
condition n/a
subroutine 2 4 50.0
pod 1 1 100.0
total 9 16 56.2


line stmt bran cond sub pod time code
1             package WebService::Mattermost::V4::API::Resource::User;
2              
3             # ABSTRACT: Wrapped API methods for the users API endpoints.
4              
5 7     7   49 use Moo;
  7         28  
  7         43  
6 7     7   2686 use Types::Standard qw(HashRef Str);
  7         21  
  7         48  
7              
8             extends 'WebService::Mattermost::V4::API::Resource';
9             with    qw(
10             WebService::Mattermost::V4::API::Resource::Role::Single
11             WebService::Mattermost::V4::API::Resource::Role::View::User
12             );
13              
14             ################################################################################
15              
16             has available_user_roles => (is => 'ro', isa => HashRef, lazy => 1, builder => 1);
17              
18             has role_system_admin => (is => 'ro', isa => Str, default => 'system_admin');
19             has role_system_user => (is => 'ro', isa => Str, default => 'system_user');
20              
21             ################################################################################
22              
23             around [ qw(
24             get
25             update
26             teams
27             patch
28            
29             update_roles
30             update_active_status
31             update_password
32             update_authentication_method
33            
34             generate_mfa_secret
35             update_mfa
36            
37             get_profile_image
38             set_profile_image
39            
40             get_status
41             set_status
42            
43             get_sessions
44             revoke_session
45             revoke_all_sessions
46            
47             get_preferences
48             set_preferences
49             delete_preferences
50             list_preferences_by_category
51             get_preference_by_category_and_name
52            
53             get_flagged_posts
54            
55             remove_reaction
56            
57             get_authorized_apps
58             get_authorised_apps
59             ) ] => sub {
60                 my $orig = shift;
61                 my $self = shift;
62                 my $id = shift;
63              
64                 return $self->validate_id($orig, $id, @_);
65             };
66              
67             sub get {
68                 my $self = shift;
69                 my $id = shift;
70              
71                 return $self->_single_view_get({
72                     endpoint => '%s',
73                     ids => [ $id ],
74                 });
75             }
76              
77             sub update {
78                 my $self = shift;
79                 my $id = shift;
80                 my $args = shift;
81              
82                 return $self->_put({
83                     endpoint => '%s',
84                     ids => [ $id ],
85                     parameters => $args,
86                 });
87             }
88              
89             sub teams {
90                 my $self = shift;
91                 my $id = shift;
92              
93                 return $self->_get({
94                     endpoint => '%s/teams',
95                     ids => [ $id ],
96                     view => 'Team',
97                 });
98             }
99              
100             sub deactivate {
101 0     0 1       my $self = shift;
102 0               my $id = shift;
103              
104 0               return $self->_delete({
105                     endpoint => '%s',
106                     ids => [ $id ],
107                 });
108             }
109              
110             sub patch {
111                 my $self = shift;
112                 my $id = shift;
113                 my $args = shift;
114              
115                 return $self->_put({
116                     endpoint => '%s/patch',
117                     ids => [ $id ],
118                     parameters => $args,
119                 });
120             }
121              
122             sub update_roles {
123                 my $self = shift;
124                 my $id = shift;
125                 my $roles = shift; # ArrayRef
126              
127                 foreach my $role (@{$roles}) {
128                     unless ($self->available_user_roles->{$role}) {
129                         my $err = sprintf('"%s" is not a valid role. Valid roles: %s',
130                             $role, join(', ', keys %{$self->available_user_roles}));
131              
132                         return $self->error_return($err);
133                     }
134                 }
135              
136                 return $self->_put({
137                     endpoint => '%s/roles',
138                     ids => [ $id ],
139                     parameters => {
140                         roles => $roles,
141                     },
142                 });
143             }
144              
145             sub generate_mfa_secret {
146                 my $self = shift;
147                 my $id = shift;
148              
149                 return $self->_post({
150                     endpoint => '%s/mfa/generate',
151                     ids => [ $id ],
152                 });
153             }
154              
155             sub update_mfa {
156                 my $self = shift;
157                 my $id = shift;
158                 my $args = shift;
159              
160                 return $self->_put({
161                     endpoint => '%s/mfa',
162                     ids => [ $id ],
163                     parameters => $args,
164                 });
165             }
166              
167             sub get_profile_image {
168                 my $self = shift;
169                 my $id = shift;
170              
171                 return $self->_get({
172                     endpoint => '%s/image',
173                     ids => [ $id ],
174                 });
175             }
176              
177             sub set_profile_image {
178                 my $self = shift;
179                 my $id = shift;
180                 my $filename = shift;
181              
182                 unless ($filename && -f $filename) {
183                     return $self->error_return(sprintf('%s is not a valid file', $filename));
184                 }
185              
186                 return $self->_post({
187                     endpoint => '%s/image',
188                     ids => [ $id ],
189                     override_data_type => 'form',
190                     parameters => {
191                         image => { file => $filename },
192                     },
193                 });
194             }
195              
196             sub update_active_status {
197                 my $self = shift;
198                 my $id = shift;
199                 my $args = shift;
200              
201                 return $self->_put({
202                     endpoint => '%s/active',
203                     ids => [ $id ],
204                     parameters => $args,
205                     required => [ 'active' ],
206                 });
207             }
208              
209             sub update_password {
210                 my $self = shift;
211                 my $id = shift;
212                 my $args = shift;
213              
214                 return $self->_put({
215                     endpoint => '%s/password',
216                     ids => [ $id ],
217                     parameters => $args,
218                 });
219             }
220              
221             sub update_authentication_method {
222                 my $self = shift;
223                 my $id = shift;
224                 my $args = shift;
225              
226                 return $self->_put({
227                     endpoint => '%s/auth',
228                     ids => [ $id ],
229                     paramters => $args,
230                 });
231             }
232              
233             sub get_status {
234                 my $self = shift;
235                 my $id = shift;
236              
237                 return $self->_single_view_get({
238                     endpoint => '%s/status',
239                     ids => [ $id ],
240                     view => 'User::Status',
241                 });
242             }
243              
244             sub set_status {
245                 my $self = shift;
246                 my $id = shift;
247                 my $status = shift;
248              
249             # online, away, offline, dnd
250              
251                 return $self->_single_view_put({
252                     endpoint => '%s/status',
253                     ids => [ $id ],
254                     parameters => {
255                         status => $status,
256                     },
257                     required => [ 'status' ],
258                     view => 'User::Status',
259                 });
260             }
261              
262             sub get_sessions {
263                 my $self = shift;
264                 my $id = shift;
265              
266                 return $self->_get({
267                     endpoint => '%s/sessions',
268                     ids => [ $id ],
269                     view => 'User::Session',
270                 });
271             }
272              
273             sub revoke_session {
274                 my $self = shift;
275                 my $id = shift;
276                 my $session_id = shift;
277              
278                 return $self->_single_view_post({
279                     endpoint => '%s/sessions/revoke',
280                     ids => [ $id ],
281                     parameters => {
282                         session_id => $session_id,
283                     },
284                     required => [ 'session_id' ],
285                     view => 'Status',
286                 });
287             }
288              
289             sub revoke_all_sessions {
290                 my $self = shift;
291                 my $id = shift;
292              
293                 return $self->_single_view_post({
294                     endpoint => '%s/sessions/revoke/all',
295                     view => 'Status',
296                 });
297             }
298              
299             sub get_preferences {
300                 my $self = shift;
301                 my $id = shift;
302              
303                 return $self->_get({
304                     endpoint => '%s/preferences',
305                     ids => [ $id ],
306                     view => 'User::Preference',
307                 });
308             }
309              
310             sub set_preferences {
311                 my $self = shift;
312                 my $id = shift;
313                 my $args = shift;
314              
315                 unless (ref $args eq 'ARRAY') {
316                     return $self->error_return('An ArrayRef of preferences must be passed');
317                 }
318              
319                 return $self->_single_view_put({
320                     endpoint => '%s/preferences',
321                     ids => [ $id ],
322                     parameters => $args,
323                     view => 'Status',
324                 });
325             }
326              
327             sub delete_preferences {
328                 my $self = shift;
329                 my $id = shift;
330                 my $args = shift;
331              
332                 unless (ref $args eq 'ARRAY') {
333                     return $self->error_return('An ArrayRef of preferences must be passed');
334                 }
335              
336                 return $self->_single_view_post({
337                     endpoint => '%s/preferences/delete',
338                     ids => [ $id ],
339                     parameters => $args,
340                     view => 'Status',
341                 });
342             }
343              
344             sub list_preferences_by_category {
345                 my $self = shift;
346                 my $id = shift;
347                 my $category = shift;
348              
349                 unless ($category) {
350                     return $self->error_return('A category is required');
351                 }
352              
353                 return $self->_get({
354                     endpoint => '%s/preferences/%s',
355                     ids => [ $id, $category ],
356                     view => 'User::Category',
357                 });
358             }
359              
360             sub get_preference_by_category_and_name {
361                 my $self = shift;
362                 my $id = shift;
363                 my $category = shift;
364                 my $name = shift;
365              
366                 unless ($category && $name) {
367                     return $self->error_return('A category and a name must be passed');
368                 }
369              
370                 return $self->_single_view_get({
371                     endpoint => '%s/preferences/%s/name/%s',
372                     ids => [ $id, $category, $name ],
373                     view => 'User::Category',
374                 });
375             }
376              
377             sub get_flagged_posts {
378                 my $self = shift;
379                 my $id = shift;
380                 my $args = shift;
381              
382                 return $self->_single_view_get({
383                     endpoint => '%s/posts/flagged',
384                     ids => [ $id ],
385                     parameters => $args,
386                     view => 'Thread',
387                 });
388             }
389              
390             sub remove_reaction {
391                 my $self = shift;
392                 my $user_id = shift;
393                 my $post_id = shift;
394                 my $emoji_name = shift;
395              
396                 unless ($post_id && $emoji_name) {
397                     return $self->error_return('A post ID and an emoji name are required');
398                 }
399              
400                 return $self->_single_view_delete({
401                     endpoint => '%s/posts/%s/reactions/%s',
402                     ids => [ $user_id, $post_id, $emoji_name ],
403                     view => 'Status',
404                 });
405             }
406              
407             sub get_authorized_apps { shift->get_authorised_apps(@_) }
408              
409             sub get_authorised_apps {
410                 my $self = shift;
411                 my $id = shift;
412                 my $args = shift;
413              
414                 return $self->_get({
415                     endpoint => '%s/oauth/apps/authorized',
416                     ids => [ $id ],
417                     parameters => $args,
418                     view => 'Application',
419                 });
420             }
421              
422             ################################################################################
423              
424             sub _build_available_user_roles {
425 0     0         my $self = shift;
426              
427                 return {
428 0                   $self->role_system_admin => 1,
429                     $self->role_system_user => 1,
430                 };
431             }
432              
433             ################################################################################
434              
435             1;
436              
437             __END__
438            
439             =pod
440            
441             =encoding UTF-8
442            
443             =head1 NAME
444            
445             WebService::Mattermost::V4::API::Resource::User - Wrapped API methods for the users API endpoints.
446            
447             =head1 VERSION
448            
449             version 0.26
450            
451             =head1 DESCRIPTION
452            
453             API methods relating to a single user by ID.
454            
455             =head2 USAGE
456            
457             use WebService::Mattermost;
458            
459             my $mm = WebService::Mattermost->new({
460             authenticate => 1,
461             username => 'me@somewhere.com',
462             password => 'hunter2',
463             base_url => 'https://my.mattermost.server.com/api/v4/',
464             });
465            
466             my $resource = $mm->api->user;
467            
468             Optionally, you can set a global user ID for the resource and not pass the ID
469             to every method:
470            
471             $resource->id('USER-ID-HERE');
472            
473             =head2 METHODS
474            
475             All of the below methods can either be called as documented under each item, or
476             from a user result object:
477            
478             my $user = $resource->get('USER-ID-HERE')->item;
479            
480             # Calls method "teams"
481             my $response = $user->call('teams');
482            
483             # Calls method "update"
484             $response = $user->call('update', {
485             # parameters
486             });
487            
488             =over 4
489            
490             =item C<get()>
491            
492             L<Get a user|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D%2Fget>
493            
494             Get a user by their ID.
495            
496             my $response = $resource->get('USER-ID-HERE');
497            
498             =item C<update()>
499            
500             L<Update a user|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D%2Fput>
501            
502             Update a user by their ID.
503            
504             my $response = $resource->update('USER-ID-HERE', {
505             # Optional arguments
506             email => '...',
507             username => '...',
508             first_name => '...',
509             last_name => '...',
510             nickname => '...',
511             locale => '...',
512             position => '...',
513             props => {
514             # ...
515             },
516             notify_props => {
517             email => \1,
518             push => \1,
519             desktop => \1,
520             desktop_sound => \1,
521             mention_keys => \1,
522             channel => \1,
523             first_name => \1,
524             },
525             });
526            
527             =item C<teams()>
528            
529             L<Get a user's teams|https://api.mattermost.com/#tag/teams%2Fpaths%2F~1users~1%7Buser_id%7D~1teams%2Fget>
530            
531             =item C<deactivate()>
532            
533             L<Deactivate a user account|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D%2Fdelete>
534            
535             Set a user as inactive by ID.
536            
537             $response->deactivate('USER-ID-HERE');
538            
539             =item C<patch()>
540            
541             L<Patch a user|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1patch%2Fput>
542            
543             my $response = $resource->patch('USER-ID-HERE', {
544             # Optional parameters:
545             email => '...',
546             username => '...',
547             first_name => '...',
548             last_name => '...',
549             nickname => '...',
550             locale => '...',
551             position => '...',
552             props => {
553             # ...
554             },
555             notify_props => {
556             email => \1,
557             push => \1,
558             desktop => \1,
559             desktop_sound => \1,
560             mention_keys => \1,
561             channel => \1,
562             first_name => \1,
563             },
564             });
565            
566             =item C<update_roles()>
567            
568             L<Update a user's roles|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1roles%2Fput>
569            
570             Valid roles are C<system_user> and C<system_admin>.
571            
572             my $response = $resource->update_roles('USER-ID-HERE', [
573             'ROLE-NAME-HERE',
574             'ANOTHER-ROLE-HERE',
575             ]);
576            
577             =item C<generate_mfa_secret()>
578            
579             L<Generate MFA secret|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1mfa~1generate%2Fpost>
580            
581             Returns a base64 encoded QR code image.
582            
583             my $response = $resource->generate_mfa_secret('USER-ID-HERE');
584            
585             =item C<update_mfa()>
586            
587             L<Update a user's MFA|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1mfa%2Fput>
588            
589             Set whether a user requires multi-factor auth. If the user currently has MFA
590             active, a code from the MFA client is required.
591            
592             my $response = $resource->update_mfa('ID-HERE', {
593             activate => \1, # or \0 for false
594             code => 1234, # required if MFA is already active
595             });
596            
597             =item C<get_profile_image()>
598            
599             L<Get user's profile image|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1image%2Fget>
600            
601             Get a user's profile image. Warning: returns binary content.
602            
603             my $response = $resource->get_profile_image('ID-HERE');
604            
605             # $response->raw_content contains the image as binary
606            
607             =item C<set_profile_image()>
608            
609             L<Set user's profile image|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1image%2Fpost>
610            
611             Set a user's profile image.
612            
613             my $response = $resource->set_profile_image('ID-HERE', '/path/to/file.jpg');
614            
615             =item C<update_active_status()>
616            
617             L<Update user active status|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1active%2Fput>
618            
619             Set a user as active or inactive.
620            
621             $resource->update_active_status('ID-HERE', {
622             active => \1, # \1 for true, \0 for false
623             });
624            
625             =item C<update_password()>
626            
627             L<Update a user's password|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1password%2Fput>
628            
629             my $response = $resource->update_password('ID-HERE', {
630             old_password => '...',
631             new_password => '...',
632             });
633            
634             =item C<update_authentication_method()>
635            
636             L<Update a user's authentication method|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1auth%2Fput>
637            
638             my $response = $resource->update_authentication_method('USER-ID-HERE', {
639             # Optional parameters:
640             auth_data => '...',
641             auth_service => '...',
642             password => '...',
643             });
644            
645             =item C<get_status()>
646            
647             L<Get a user's status|https://api.mattermost.com/#tag/status%2Fpaths%2F~1users~1%7Buser_id%7D~1status%2Fget>
648            
649             my $response = $resource->get_status('USER-ID-HERE');
650            
651             =item C<set_status()>
652            
653             L<Update a user's status|https://api.mattermost.com/#tag/status%2Fpaths%2F~1users~1%7Buser_id%7D~1status%2Fput>
654            
655             my $response = $resource->set_status('USER-ID-HERE', 'STATUS-HERE');
656            
657             Available statuses are "online", "away", "offline" and "dnd".
658            
659             =item C<get_sessions()>
660            
661             L<Get a user's sessions|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1sessions%2Fget>
662            
663             my $response = $resource->get_sessions('USER-ID-HERE');
664            
665             =item C<revoke_session()>
666            
667             L<Revoke a user sesssion|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1sessions~1revoke%2Fpost>
668            
669             my $response = $resource->revoke_session('USER-ID-HERE', 'SESSION-ID-HERE');
670            
671             =item C<revoke_all_sessions()>
672            
673             L<Revoke all active sessions for a user|https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1%7Buser_id%7D~1sessions~1revoke~1all%2Fpost>
674            
675             my $response = $resource->revoke_all_sessions('USER-ID-HERE');
676            
677             =item C<get_preferences()>
678            
679             L<Get the user's preferences|https://api.mattermost.com/#tag/preferences%2Fpaths%2F~1users~1%7Buser_id%7D~1preferences%2Fget>
680            
681             my $response = $resource->get_preferences('USER-ID-HERE');
682            
683             =item C<set_preferences()>
684            
685             L<Save the user's preferences|https://api.mattermost.com/#tag/preferences%2Fpaths%2F~1users~1%7Buser_id%7D~1preferences%2Fput>
686            
687             my $response = $resource->set_preferences('USER-ID-HERE', [
688             { user_id => 'USER-ID-HERE', category => '...', name => '...', value => '...' },
689             { user_id => 'USER-ID-HERE', category => '...', name => '...', value => '...' },
690             { user_id => 'USER-ID-HERE', category => '...', name => '...', value => '...' },
691             ]);
692            
693             =item C<delete_preferences()>
694            
695             L<Delete user's preferences|https://api.mattermost.com/#tag/preferences%2Fpaths%2F~1users~1%7Buser_id%7D~1preferences~1delete%2Fpost>
696            
697             my $response = $resource->delete_preferences('USER-ID-HERE', [
698             { user_id => 'USER-ID-HERE', category => '...', name => '...', value => '...' },
699             { user_id => 'USER-ID-HERE', category => '...', name => '...', value => '...' },
700             { user_id => 'USER-ID-HERE', category => '...', name => '...', value => '...' },
701             ]);
702            
703             =item C<list_preferences_by_category()>
704            
705             L<List a user's preferences by category|https://api.mattermost.com/#tag/preferences%2Fpaths%2F~1users~1%7Buser_id%7D~1preferences~1%7Bcategory%7D%2Fget>
706            
707             my $response = $resource->list_preferences_by_category('USER-ID-HERE', 'CATEGORY-HERE');
708            
709             =item C<get_preference_by_category_and_name()>
710            
711             L<Get a specific user preference|https://api.mattermost.com/#tag/preferences%2Fpaths%2F~1users~1%7Buser_id%7D~1preferences~1%7Bcategory%7D~1name~1%7Bpreference_name%7D%2Fget>
712            
713             my $response = $resource->get_preference_by_category_and_name(
714             'USER-ID-HERE',
715             'CATEGORY-HERE',
716             'NAME-HERE',
717             );
718            
719             =item C<get_flagged_posts()>
720            
721             L<Get a list of flagged posts|https://api.mattermost.com/#tag/posts%2Fpaths%2F~1users~1%7Buser_id%7D~1posts~1flagged%2Fget>
722            
723             Retrieve a list of posts flagged by the user with the given ID.
724            
725             my $response = $resource->get_flagged_posts('USER-ID-HERE', {
726             # Optional parameters
727             team_id => '...',
728             channel_id => '...',
729             page => 0,
730             per_page => 60,
731             });
732            
733             =item C<remove_reaction()>
734            
735             L<Remove a reaction from a user's post|https://api.mattermost.com/#tag/reactions%2Fpaths%2F~1users~1%7Buser_id%7D~1posts~1%7Bpost_id%7D~1reactions~1%7Bemoji_name%7D%2Fdelete>
736            
737             my $response = $resource->remove_reaction(
738             'USER-ID-HERE',
739             'POST-ID-HERE',
740             'EMOJI-NAME-HERE',
741             );
742            
743             =item C<get_authorized_apps()>
744            
745             Alias for C<get_authorised_apps()>.
746            
747             =item C<get_authorised_apps()>
748            
749             L<Get authorized OAuth apps|https://api.mattermost.com/#tag/OAuth%2Fpaths%2F~1users~1%7Buser_id%7D~1oauth~1apps~1authorized%2Fget>
750            
751             my $response = $resource->get_authorised_apps('USER-ID-HERE', {
752             # Optional parameters:
753             page => 0,
754             per_page => 60,
755             });
756            
757             =back
758            
759             =head1 AUTHOR
760            
761             Mike Jones <mike@netsplit.org.uk>
762            
763             =head1 COPYRIGHT AND LICENSE
764            
765             This software is Copyright (c) 2020 by Mike Jones.
766            
767             This is free software, licensed under:
768            
769             The MIT (X11) License
770            
771             =cut
772