File Coverage

blib/lib/Mojolicious/Plugin/ContextAuth/DB/Context.pm
Criterion Covered Total %
statement 209 209 100.0
branch 54 54 100.0
condition 9 9 100.0
subroutine 33 33 100.0
pod 9 9 100.0
total 314 314 100.0


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::ContextAuth::DB::Context;
2              
3             # ABSTRACT: Context object for the ContextAuth database
4              
5 51     51   379 use Mojo::Base -base, -signatures;
  51         116  
  51         371  
6              
7 51     51   10085 use Data::UUID;
  51         123  
  51         3067  
8 51     51   373 use List::Util qw(any);
  51         124  
  51         2921  
9 51     51   397 use Try::Tiny;
  51         153  
  51         3475  
10              
11 51     51   436 use feature 'postderef';
  51         152  
  51         1998  
12 51     51   361 no warnings 'experimental::postderef';
  51         200  
  51         128782  
13              
14             has [qw'dbh context_id context_name context_description error'];
15              
16 46     46 1 6454 sub load ($self, $id) {
  45         128  
  45         115  
  45         126  
17 45         250 $self->error('');
18            
19 45 100       470 if ( !$id ) {
20 1         5 $self->error( "Need id" );
21 1         7 return;
22             }
23              
24 44         207 my $result = $self->dbh->db->select(
25             corbac_contexts => [qw/context_id context_name context_description/], {
26             context_id => $id,
27             }
28             );
29              
30 44         42581 my $data = $result->hash;
31 44         2656 $result->finish;
32              
33 44 100       595 return if !$result->rows;
34              
35 39         564 my $context = __PACKAGE__->new(
36             dbh => $self->dbh,
37             $data->%*,
38             context_id => $id,
39             );
40              
41 39         930 return $context;
42             }
43              
44 37     37 1 10752 sub add ($self, %params) {
  37         117  
  37         133  
  37         79  
45 37         264 $self->error('');
46              
47 37 100       517 if ( !$params{context_name} ) {
48 4         12 $self->error('Need context_name');
49 4         27 return;
50             }
51              
52 33 100 100     377 if ( length $params{context_name} > 255 || length $params{context_name} < 3 ) {
53 2         7 $self->error( 'Invalid parameter' );
54 2         13 return;
55             }
56              
57 31         8613 $params{context_id} = Data::UUID->new->create_str;
58              
59 31         159017 my $error;
60             try {
61 31     31   3003 $self->dbh->db->insert( corbac_contexts => \%params);
62             }
63             catch {
64 1     1   1191 $self->error( 'Invalid parameter' );
65 1         8 $error = $_;
66 31         792 };
67              
68 31 100       189839 return if $error;
69              
70 30         247 my $context = $self->load( $params{context_id} );
71 30         2095 return $context;
72             }
73              
74 6     6 1 7320 sub delete ($self, $id = $self->context_id) {
  6         15  
  6         20  
  6         22  
75 6         22 $self->error('');
76            
77 6 100       56 if ( !$id ) {
78 1         6 $self->error( "Need context id" );
79 1         9 return;
80             }
81              
82 5 100       16 if ( ref $id ) {
83 1         5 $self->error( "Invalid context id" );
84 1         8 return;
85             }
86              
87 4         9 my $result;
88             my $error;
89              
90             try {
91 4     4   211 my $tx = $self->dbh->db->begin;
92              
93 4         562 $self->dbh->db->delete(
94             corbac_roles => { context_id => $id },
95             );
96              
97 3         1991 $self->dbh->db->delete(
98             corbac_user_context_roles => { context_id => $id }
99             );
100              
101 3         1937 $result = $self->dbh->db->delete(
102             corbac_contexts => {
103             context_id => $id,
104             }
105             );
106              
107 3         2055 $tx->commit;
108             }
109             catch {
110 1     1   1081 $self->error( "Cannot delete context: " . $_ );
111 1         9 $error = 1;
112 4         38 };
113              
114 4 100       430 return if $error;
115 3         16 return $result->rows;
116             }
117              
118 9     9 1 10851 sub update ($self, @params) {
  9         20  
  9         28  
  9         14  
119 9         37 $self->error('');
120            
121 9 100       79 my $id = @params % 2 ? shift @params : $self->context_id;
122 9         46 my %to_update = @params;
123              
124 9 100 100     66 if ( exists $to_update{context_name} && (
      100        
125             length $to_update{context_name} > 255 ||
126             length $to_update{context_name} < 3 )
127             ) {
128 3         10 $self->error( 'Invalid parameter' );
129 3         31 return;
130             }
131              
132 6         14 delete $to_update{context_id};
133              
134 6         11 my $result;
135             my $error;
136             try {
137 6     6   284 $result = $self->dbh->db->update(
138             corbac_contexts => \%to_update,
139             { context_id => $id }
140             );
141             }
142             catch {
143 1     1   1638 $self->error( 'Invalid parameter' );
144 1         10 $error = $_;
145 6         46 };
146              
147 6 100       3545 return if $error;
148              
149 5 100       18 if ( !$result->rows ) {
150 1         15 $self->error( 'No context updated' );
151 1         9 return;
152             }
153              
154 4         44 return $self->load( $id );
155             }
156              
157 7     7 1 8849 sub search ($self, %params) {
  7         18  
  7         20  
  7         12  
158 7         34 $self->error('');
159              
160 7         58 my $error;
161             my @context_ids;
162              
163             try {
164 7     7   462 my $result = $self->dbh->db->select(
165             corbac_contexts => ['context_id'] => \%params,
166             );
167              
168 6         5143 while ( my $next = $result->hash ) {
169 6         329 push @context_ids, $next->{context_id};
170             }
171             }
172             catch {
173 1     1   986 $self->error('Cannot search for contexts');
174 1         9 $error = $_;
175 7         66 };
176              
177 7 100       711 return if $error;
178 6         33 return @context_ids;
179             }
180              
181 10     10 1 9949 sub set_user_roles ($self, %params) {
  10         24  
  10         32  
  10         15  
182 10         36 $self->error('');
183            
184 10 100       69 if ( !$self->context_id ) {
185 1         8 $self->error("Need context id");
186 1         10 return;
187             }
188              
189 9 100   17   86 if ( any{ !$params{$_} }qw/user_id roles/ ) {
  17         48  
190 2         8 $self->error( "Need user_id and roles" );
191 2         19 return;
192             }
193            
194 7         28 my $user_id = $params{user_id};
195              
196 7         33 my $rows = 0;
197 7         13 my $error;
198             try {
199 7     7   713 my $tx = $self->dbh->db->begin;
200              
201 7         1023 $self->dbh->db->delete(
202             corbac_user_context_roles => {
203             context_id => $self->context_id,
204             user_id => $user_id,
205             }
206             );
207              
208 7 100       5015 $rows = -1 if !$params{roles}->@*;
209              
210 6         281 for my $role_id ( $params{roles}->@* ) {
211 7         134 my $result = $self->dbh->db->insert(
212             corbac_user_context_roles => {
213             user_id => $user_id,
214             context_id => $self->context_id,
215             role_id => $role_id,
216             }
217             );
218              
219 7         4857 $rows += $result->rows;
220             }
221              
222 6         339 $tx->commit;
223             }
224             catch {
225 1     1   106 $self->error( "Transaction error: $_" );
226 1         9 $error = $_;
227 7         49 };
228              
229 7 100       800 return if $error;
230 6         43 return $rows;
231             }
232              
233 9     9 1 8140 sub set_role_users ($self, %params) {
  9         20  
  9         25  
  9         15  
234 9         36 $self->error('');
235            
236 9 100       77 if ( !$self->context_id ) {
237 1         9 $self->error("Need context id");
238 1         9 return;
239             }
240              
241 8 100   15   77 if ( any{ !$params{$_} }qw/role_id users/ ) {
  15         45  
242 2         7 $self->error( "Need role_id and users" );
243 2         34 return;
244             }
245              
246 6         24 my $role_id = $params{role_id};
247              
248 6         15 my $rows = 0;
249 6         14 my $error;
250             try {
251 6     6   271 my $tx = $self->dbh->db->begin;
252              
253 6         817 $self->dbh->db->delete(
254             corbac_user_context_roles => {
255             context_id => $self->context_id,
256             role_id => $role_id,
257             }
258             );
259              
260 6 100       4022 $rows = -1 if !$params{users}->@*;
261              
262 5         282 for my $user_id ( $params{users}->@* ) {
263 6         133 my $result = $self->dbh->db->insert(
264             corbac_user_context_roles => {
265             user_id => $user_id,
266             context_id => $self->context_id,
267             role_id => $role_id,
268             }
269             );
270              
271 6         3970 $rows += $result->rows;
272             }
273              
274 5         243 $tx->commit;
275             }
276             catch {
277 1     1   105 $self->error( "Transaction error: $_" );
278 1         11 $error = $_;
279 6         41 };
280              
281 6 100       591 return if $error;
282 5         40 return $rows;
283             }
284              
285 11     11 1 5953 sub role_users ($self, %params) {
  11         22  
  11         26  
  11         21  
286 11         41 $self->error('');
287            
288 11 100       81 if ( !$self->context_id ) {
289 1         9 $self->error("Need context id");
290 1         9 return;
291             }
292              
293 10         61 my $role_id = $params{role_id};
294 10 100       25 if ( !$role_id ) {
295 1         11 $self->error( "No role id given" );
296 1         13 return;
297             }
298              
299 9         16 my @users;
300             my $error;
301             try {
302 9     9   412 my $tx = $self->dbh->db->begin;
303              
304 9         1135 my $result = $self->dbh->db->select(
305             corbac_user_context_roles => ['user_id'] => {
306             context_id => $self->context_id,
307             role_id => $role_id,
308             }
309             );
310            
311 8         5245 while ( my $next = $result->hash ) {
312 6         168 push @users, $next->{user_id};
313             }
314              
315 8         177 $tx->commit;
316             }
317             catch {
318 1     1   1606 $self->error( "Cannot get list of role users: $_" );
319 1         9 $error = $_;
320 9         87 };
321              
322 9 100       923 return if $error;
323 8         46 return @users;
324             }
325              
326 12     12 1 6727 sub user_roles ($self, %params) {
  12         28  
  12         30  
  12         22  
327 12         43 $self->error('');
328            
329 12 100       133 if ( !$self->context_id ) {
330 1         9 $self->error("Need context id");
331 1         9 return;
332             }
333              
334 11         78 my $user_id = $params{user_id};
335 11 100       34 if ( !$user_id ) {
336 1         6 $self->error( "No user_id given" );
337 1         8 return;
338             }
339              
340 10         24 my @roles;
341             my $error;
342             try {
343 10     10   496 my $tx = $self->dbh->db->begin;
344              
345 10         1366 my $result = $self->dbh->db->select(
346             corbac_user_context_roles => ['role_id'] => {
347             context_id => $self->context_id,
348             user_id => $user_id,
349             }
350             );
351            
352 9         6789 while ( my $next = $result->hash ) {
353 7         239 push @roles, $next->{role_id};
354             }
355              
356 9         232 $tx->commit;
357             }
358             catch {
359 1     1   1489 $self->error( "Cannot get list of user roles: $_" );
360 1         9 $error = $_;
361 10         90 };
362              
363 10 100       1234 return if $error;
364 9         57 return @roles;
365             }
366              
367             1;
368              
369             =pod
370              
371             =encoding UTF-8
372              
373             =head1 NAME
374              
375             Mojolicious::Plugin::ContextAuth::DB::Context - Context object for the ContextAuth database
376              
377             =head1 VERSION
378              
379             version 0.01
380              
381             =head1 SYNOPSIS
382              
383             my $db = Mojolicious::Plugin::ContextAuth::DB->new(
384             dsn => 'sqlite:' . $file,
385             );
386              
387             my $context = Mojolicious::Plugin::ContextAuth::DB::Context->new(
388             dbh => $db->dbh,
389             );
390              
391             my $new_context = $context->add(
392             context_name => 'test',
393             context_description => 'hallo',
394             );
395              
396             my $updated_context = $new_context->update(
397             context_name => 'ernie',
398             context_description => 'bert',
399             );
400              
401             # create context object with data for context id 1
402             my $found_context = $context->load( 1 );
403              
404             # delete context
405             $new_context->delete;
406              
407             =head1 ATTRIBUTES
408              
409             =over 4
410              
411             =item * dbh
412              
413             =item * context_name
414              
415             =item * context_description
416              
417             =item * context_id
418              
419             =item * error
420              
421             =back
422              
423             =head1 METHODS
424              
425             =head2 load
426              
427             # create context object with data for context id 1
428             my $found_context = $context->load( 1 );
429              
430             =head2 add
431              
432             my $new_context = $context->add(
433             contextname => 'test',
434             context_password => 'hallo',
435             );
436              
437             =head2 update
438              
439             my $updated_context = $new_context->update(
440             contextname => 'ernie',
441             context_password => 'bert',
442             );
443              
444             =head2 delete
445              
446             $context->delete;
447              
448             =head2 set_user_roles
449              
450             $context->set_user_roles(
451             user_id => 123,
452             roles => [
453             123,
454             456,
455             789,
456             ],
457             );
458              
459             =head2 set_role_users
460              
461             $context->set_role_users(
462             role_id => 123,
463             users => [
464             123,
465             456,
466             789,
467             ],
468             );
469              
470             =head2 role_users
471              
472             my @user_ids = $context->role_users(
473             role_id => 123,
474             );
475              
476             =head2 user_roles
477              
478             my @role_ids = $context->user_roles(
479             user_id => 123,
480             );
481              
482             =head2 search
483              
484             =head1 AUTHOR
485              
486             Renee Baecker
487              
488             =head1 COPYRIGHT AND LICENSE
489              
490             This software is Copyright (c) 2020 by Renee Baecker.
491              
492             This is free software, licensed under:
493              
494             The Artistic License 2.0 (GPL Compatible)
495              
496             =cut
497              
498             __END__