File Coverage

blib/lib/Mojolicious/Plugin/ContextAuth/DB/Role.pm
Criterion Covered Total %
statement 231 231 100.0
branch 68 68 100.0
condition 21 21 100.0
subroutine 34 34 100.0
pod 9 9 100.0
total 363 363 100.0


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::ContextAuth::DB::Role;
2              
3             # ABSTRACT: Role object for the ContextAuth database
4              
5 51     51   400 use Mojo::Base -base, -signatures;
  51         115  
  51         373  
6 51     51   10351 use List::Util qw(any);
  51         137  
  51         3060  
7 51     51   398 use Try::Tiny;
  51         156  
  51         2986  
8              
9 51     51   373 use Mojolicious::Plugin::ContextAuth::DB::Permission;
  51         137  
  51         359  
10              
11 51     51   1991 use feature 'postderef';
  51         116  
  51         1756  
12 51     51   322 no warnings 'experimental::postderef';
  51         136  
  51         139217  
13              
14             has [qw'dbh role_id role_name role_description context_id is_valid error'];
15              
16 51     51 1 5237 sub load ($self, $id) {
  50         135  
  50         146  
  50         127  
17 50         242 $self->error('');
18            
19 50 100       452 if ( !$id ) {
20 1         6 $self->error( "Need id" );
21 1         9 return;
22             }
23              
24 49         203 my $result = $self->dbh->db->select(
25             corbac_roles => [qw/role_id role_name role_description context_id is_valid/], {
26             role_id => $id,
27             }
28             );
29              
30 49         44132 my $data = $result->hash;
31 49         2354 $result->finish;
32              
33 49 100       560 return if !$result->rows;
34              
35 44         504 my $role = __PACKAGE__->new(
36             dbh => $self->dbh,
37             $data->%*,
38             role_id => $id,
39             );
40              
41 44         983 return $role;
42             }
43              
44 44     44 1 19998 sub add ($self, %params) {
  44         126  
  44         147  
  44         121  
45 44         279 $self->error('');
46              
47 44 100   85   776 if ( any{ !$params{$_} }qw(role_name context_id) ) {
  85         337  
48 5         17 $self->error('Need role_name and context_id');
49 5         32 return;
50             }
51              
52 39 100 100     488 if ( length $params{role_name} > 255 || length $params{role_name} < 3 ) {
53 2         14 $self->error( 'Invalid parameter' );
54 2         14 return;
55             }
56              
57 37         8536 $params{role_id} = Data::UUID->new->create_str;
58              
59 37         36640 my $error;
60             try {
61 37     37   2400 $self->dbh->db->insert( corbac_roles => \%params);
62             }
63             catch {
64 2     2   2371 $self->error( 'Invalid parameter' );
65 2         17 $error = $_;
66 37         716 };
67              
68 37 100       35025 return if $error;
69              
70 35         211 my $role = $self->load( $params{role_id} );
71 35         2252 return $role;
72             }
73              
74 6     6 1 5989 sub delete ($self, $id = $self->role_id) {
  6         13  
  6         16  
  6         17  
75 6         20 $self->error('');
76            
77 6 100       44 if ( !$id ) {
78 1         6 $self->error( "Need role id" );
79 1         10 return;
80             }
81              
82 5 100       15 if ( ref $id ) {
83 1         5 $self->error( "Invalid role id" );
84 1         9 return;
85             }
86              
87 4         10 my $error;
88             my $result;
89              
90             try {
91 4     4   197 my $tx = $self->dbh->db->begin;
92              
93 4         485 $self->dbh->db->delete(
94             corbac_role_permissions => { role_id => $id },
95             );
96              
97 3         2033 $self->dbh->db->delete(
98             corbac_user_context_roles => { role_id => $id }
99             );
100              
101 3         1568 $result = $self->dbh->db->delete(
102             corbac_roles => {
103             role_id => $id,
104             }
105             );
106              
107 3         1655 $tx->commit;
108             }
109             catch {
110 1     1   1078 $self->error( "Cannot delete role: " . $_ );
111 1         8 $error = 1;
112 4         33 };
113              
114 4 100       349 return if $error;
115 3         13 return $result->rows;
116             }
117              
118 10     10 1 12889 sub update ($self, @params) {
  10         22  
  10         29  
  10         17  
119 10         34 $self->error('');
120            
121 10 100       85 my $id = @params % 2 ? shift @params : $self->role_id;
122 10         42 my %to_update = @params;
123              
124 10 100 100     70 if ( exists $to_update{role_name} && (
      100        
125             length $to_update{role_name} > 255 ||
126             length $to_update{role_name} < 3 )
127             ) {
128 3         12 $self->error( 'Invalid parameter' );
129 3         42 return;
130             }
131              
132 7         12 delete $to_update{role_id};
133              
134 7         14 my $result;
135             my $error;
136             try {
137 7     7   319 $result = $self->dbh->db->update(
138             corbac_roles => \%to_update,
139             { role_id => $id }
140             );
141             }
142             catch {
143 2     2   2232 $self->error( 'Invalid parameter' );
144 2         17 $error = $_;
145 7         59 };
146              
147 7 100       3737 return if $error;
148              
149 5 100       16 if ( !$result->rows ) {
150 1         16 $self->error( 'No role updated' );
151 1         8 return;
152             }
153              
154 4         44 return $self->load( $id );
155             }
156              
157 12     12 1 6944 sub search ($self, %params) {
  12         21  
  12         24  
  12         22  
158 12         41 $self->error('');
159              
160 12         75 my $error;
161             my @role_ids;
162              
163             try {
164 12     12   551 my $result = $self->dbh->db->select(
165             corbac_roles => ['role_id'] => \%params,
166             );
167              
168 10         6834 while ( my $next = $result->hash ) {
169 12         474 push @role_ids, $next->{role_id};
170             }
171             }
172             catch {
173 2     2   2037 $self->error('Cannot search for roles');
174 2         17 $error = $_;
175 12         86 };
176              
177 12 100       937 return if $error;
178 10         47 return @role_ids;
179             }
180              
181 14     14 1 12037 sub set_context_users ($self, %params) {
  14         29  
  14         43  
  14         23  
182 14         49 $self->error('');
183              
184 14   100     115 my $role_id = $params{role_id} // $self->role_id;
185 14 100       74 if ( !$role_id ) {
186 1         7 $self->error("Need role id");
187 1         11 return;
188             }
189              
190 13 100       39 if ( ref $role_id ) {
191 1         7 $self->error("Invalid role id");
192 1         12 return;
193             }
194              
195 12 100   23   100 if ( any{!$params{$_} }qw/context_id users/ ) {
  23         64  
196 2         7 $self->error( "Need context_id and users" );
197 2         18 return;
198             }
199              
200 10         36 my $context_id = $params{context_id};
201              
202 10 100       27 if ( ref $context_id ) {
203 2         8 $self->error( "Invalid context id" );
204 2         25 return;
205             }
206              
207 8         15 my $rows = 0;
208 8         15 my $error;
209             try {
210 8     8   357 my $tx = $self->dbh->db->begin;
211              
212 8         1340 $self->dbh->db->delete(
213             corbac_user_context_roles => {
214             role_id => $role_id,
215             context_id => $context_id,
216             }
217             );
218              
219 8 100       5161 $rows = -1 if !$params{users}->@*;
220              
221 7         289 for my $user_id ( $params{users}->@* ) {
222 9         194 my $result = $self->dbh->db->insert(
223             corbac_user_context_roles => {
224             user_id => $user_id,
225             role_id => $role_id,
226             context_id => $context_id,
227             }
228             );
229              
230 9         5623 $rows += $result->rows;
231             }
232              
233 7         363 $tx->commit;
234             }
235             catch {
236 1     1   107 $self->error( "Transaction error: $_" );
237 1         10 $error = $_;
238 8         59 };
239              
240 8 100       844 return if $error;
241 7         46 return $rows;
242             }
243              
244 15     15 1 9278 sub context_users ($self, %params) {
  15         32  
  15         37  
  15         26  
245 15         49 $self->error('');
246              
247 15   100     138 my $role_id = $params{role_id} // $self->role_id;
248 15 100       94 if ( !$role_id ) {
249 1         5 $self->error("Need role id");
250 1         9 return;
251             }
252              
253 14 100       40 if ( ref $role_id ) {
254 1         5 $self->error("Invalid role id");
255 1         9 return;
256             }
257              
258 13         27 my $context_id = $params{context_id};
259 13 100       51 if ( !$context_id ) {
260 1         7 $self->error( "No context id given" );
261 1         10 return;
262             }
263              
264 12 100       33 if ( ref $context_id ) {
265 2         8 $self->error( "Invalid context id" );
266 2         18 return;
267             }
268              
269 10         24 my @users;
270             my $error;
271             try {
272 10     10   471 my $tx = $self->dbh->db->begin;
273              
274 10         1340 my $result = $self->dbh->db->select(
275             corbac_user_context_roles => ['user_id'] => {
276             context_id => $context_id,
277             role_id => $role_id,
278             }
279             );
280            
281 9         5930 while ( my $next = $result->hash ) {
282 9         253 push @users, $next->{user_id};
283             }
284              
285 9         195 $tx->commit;
286             }
287             catch {
288 1     1   1338 $self->error( "Cannot get list of context users: $_" );
289 1         9 $error = $_;
290 10         118 };
291              
292 10 100       1030 return if $error;
293 9         46 return @users;
294             }
295              
296 15     15 1 14266 sub set_permissions ($self, %params) {
  15         32  
  15         37  
  15         28  
297 15         55 $self->error('');
298              
299 15   100     130 my $role_id = $params{role_id} // $self->role_id;
300 15 100       90 if ( !$role_id ) {
301 1         7 $self->error("Need role id");
302 1         9 return;
303             }
304              
305 14 100       39 if ( ref $role_id ) {
306 1         4 $self->error("Invalid role id");
307 1         10 return;
308             }
309              
310 13 100   13   76 if ( any{!$params{$_} }qw/permissions/ ) {
  13         44  
311 1         4 $self->error( "Need permissions" );
312 1         11 return;
313             }
314              
315 12         54 my $perm_object = Mojolicious::Plugin::ContextAuth::DB::Permission->new( dbh => $self->dbh );
316              
317 12         122 my $rows = 0;
318 12         19 my $error;
319             try {
320 12     12   521 my $tx = $self->dbh->db->begin;
321              
322 12         1415 $self->dbh->db->delete(
323             corbac_role_permissions => {
324             role_id => $role_id,
325             }
326             );
327              
328 11 100       6041 $rows = -1 if !$params{permissions}->@*;
329              
330             PERMISSION_ID:
331 10         417 for my $permission_id ( $params{permissions}->@* ) {
332 15 100       424 next PERMISSION_ID if ref $permission_id;
333            
334 14         50 my $permission = $perm_object->load( $permission_id );
335              
336 14 100       752 next PERMISSION_ID if !$permission;
337              
338 12         41 my $result = $self->dbh->db->insert(
339             corbac_role_permissions => {
340             permission_id => $permission_id,
341             role_id => $role_id,
342             resource_id => $permission->resource_id,
343             }
344             );
345              
346 12         7237 $rows += $result->rows;
347             }
348              
349 10         322 $tx->commit;
350             }
351             catch {
352 2     2   1123 $self->error( "Transaction error: $_" );
353 2         18 $error = $_;
354 12         87 };
355              
356 12 100       1132 return if $error;
357 10         74 return $rows;
358             }
359              
360 12     12 1 6885 sub permissions ($self, %params) {
  12         27  
  12         29  
  12         20  
361 12         45 $self->error('');
362              
363 12   100     111 my $role_id = $params{role_id} // $self->role_id;
364 12 100       65 if ( !$role_id ) {
365 1         7 $self->error("Need role id");
366 1         9 return;
367             }
368              
369 11 100       30 if ( ref $role_id ) {
370 1         5 $self->error("Invalid role id");
371 1         14 return;
372             }
373              
374 10         19 my @permissions;
375             my $error;
376             try {
377 10     10   465 my $tx = $self->dbh->db->begin;
378              
379 10         1170 my $result = $self->dbh->db->select(
380             corbac_role_permissions => ['permission_id'] => {
381             role_id => $role_id,
382             }
383             );
384            
385 9         5033 while ( my $next = $result->hash ) {
386 9         287 push @permissions, $next->{permission_id};
387             }
388              
389 9         187 $tx->commit;
390             }
391             catch {
392 1     1   1091 $self->error( "Transaction error: $_" );
393 1         11 $error = $_;
394 10         83 };
395              
396 10 100       1115 return if $error;
397 9         52 return @permissions;
398             }
399              
400             1;
401              
402             =pod
403              
404             =encoding UTF-8
405              
406             =head1 NAME
407              
408             Mojolicious::Plugin::ContextAuth::DB::Role - Role object for the ContextAuth database
409              
410             =head1 VERSION
411              
412             version 0.01
413              
414             =head1 SYNOPSIS
415              
416             my $db = Mojolicious::Plugin::ContextAuth::DB->new(
417             dsn => 'sqlite:' . $file,
418             );
419              
420             my $role = Mojolicious::Plugin::ContextAuth::DB::role->new(
421             dbh => $db->dbh,
422             );
423              
424             my $new_role = $role->add(
425             role_name => 'test',
426             role_description => 'hallo',
427             );
428              
429             my $updated_role = $new_role->update(
430             role_name => 'ernie',
431             role_description => 'bert',
432             );
433              
434             # create role object with data for role id 1
435             my $found_role = $role->load( 1 );
436              
437             # delete role
438             $new_role->delete;
439              
440             =head1 ATTRIBUTES
441              
442             =over 4
443              
444             =item * dbh
445              
446             =item * role_name
447              
448             =item * role_description
449              
450             =item * role_id
451              
452             =item * error
453              
454             =back
455              
456             =head1 METHODS
457              
458             =head2 load
459              
460             # create role object with data for role id 1
461             my $found_role = $role->load( 1 );
462              
463             =head2 add
464              
465             my $new_role = $role->add(
466             rolename => 'test',
467             role_password => 'hallo',
468             );
469              
470             =head2 update
471              
472             my $updated_role = $new_role->update(
473             rolename => 'ernie',
474             role_password => 'bert',
475             );
476              
477             =head2 delete
478              
479             $role->delete;
480              
481             =head2 search
482              
483             Search for roles...
484              
485             my @role_ids = $role->search(); # get all roles
486             my @role_ids = $role->search( # get all roles for a context
487             context_id => 123,
488             );
489              
490             my @role_ids = $role->search(
491             role_name => { 'LIKE' => 'project%' },
492             )
493              
494             Returns a list of role ids if roles are found.
495              
496             =head2 set_context_users
497              
498             =head2 set_permissions
499              
500             =head2 context_users
501              
502             =head2 permissions
503              
504             =head1 AUTHOR
505              
506             Renee Baecker
507              
508             =head1 COPYRIGHT AND LICENSE
509              
510             This software is Copyright (c) 2020 by Renee Baecker.
511              
512             This is free software, licensed under:
513              
514             The Artistic License 2.0 (GPL Compatible)
515              
516             =cut
517              
518             __END__