| File: | lib/Yukki/Web/Controller/Admin/User.pm |
| Coverage: | 27.5% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package Yukki::Web::Controller::Admin::User; | ||||||
| 2 | |||||||
| 3 | 1 1 | 1011 15 | use v5.24; | ||||
| 4 | 1 1 1 | 14 2 7 | use utf8; | ||||
| 5 | 1 1 1 | 20 2 6 | use Moo; | ||||
| 6 | |||||||
| 7 | 1 1 1 | 1167 4949 33 | use Email::Valid; | ||||
| 8 | 1 1 1 | 1464 10716 125 | use FormValidator::Tiny qw( :validation :predicates :filters ); | ||||
| 9 | 1 1 1 | 7 1 6 | use Yukki::Error qw( http_throw ); | ||||
| 10 | 1 1 1 | 404 2 18 | use Yukki::User; | ||||
| 11 | |||||||
| 12 | with 'Yukki::Web::Controller'; | ||||||
| 13 | |||||||
| 14 | 1 1 1 | 3 2 2 | use namespace::clean; | ||||
| 15 | |||||||
| 16 | # ABSTRACT: controller for administering your wiki | ||||||
| 17 | |||||||
| 18 - 26 | =head1 DESCRIPTION Controller for administering the wiki repositories and users. =head1 METHODS =head2 fire =cut | ||||||
| 27 | |||||||
| 28 | sub fire { | ||||||
| 29 | 0 | 1 | my ($self, $ctx) = @_; | ||||
| 30 | |||||||
| 31 | 0 | my $action = $ctx->request->path_parameters->{action}; | |||||
| 32 | 0 0 | if ($action eq 'list') { $self->list_users($ctx) } | |||||
| 33 | 0 | elsif ($action eq 'add') { $self->add_user($ctx) } | |||||
| 34 | 0 | elsif ($action eq 'edit') { $self->edit_user($ctx) } | |||||
| 35 | 0 | elsif ($action eq 'remove') { $self->remove_user($ctx) } | |||||
| 36 | else { | ||||||
| 37 | 0 | http_throw('No action found matching that URL.', { | |||||
| 38 | status => 'NotFound', | ||||||
| 39 | }); | ||||||
| 40 | } | ||||||
| 41 | } | ||||||
| 42 | |||||||
| 43 - 47 | =head2 list_users Displays a page listing user records. =cut | ||||||
| 48 | |||||||
| 49 | sub list_users { | ||||||
| 50 | 0 | 1 | my ($self, $ctx) = @_; | ||||
| 51 | |||||||
| 52 | 0 | my $users = $self->model('User'); | |||||
| 53 | 0 0 | my @users = map { $users->find(login_name => $_) } $users->list; | |||||
| 54 | |||||||
| 55 | 0 | my $body = $self->view('Admin::User')->list($ctx, { | |||||
| 56 | users => \@users, | ||||||
| 57 | }); | ||||||
| 58 | |||||||
| 59 | 0 | $ctx->response->body($body); | |||||
| 60 | } | ||||||
| 61 | |||||||
| 62 - 66 | =head2 add_user Add a user account. =cut | ||||||
| 67 | |||||||
| 68 | validation_spec add_user => [ | ||||||
| 69 | login_name => [ | ||||||
| 70 | required => 1, | ||||||
| 71 | must => limit_character_set('a-z', 'A-Z', '0-9', '_', '-'), | ||||||
| 72 | must => length_in_range(3, 20), | ||||||
| 73 | ], | ||||||
| 74 | name => [ | ||||||
| 75 | required => 1, | ||||||
| 76 | must => length_in_range(1, 200), | ||||||
| 77 | ], | ||||||
| 78 | email => [ | ||||||
| 79 | required => 1, | ||||||
| 80 | must => length_in_range(1, 200), | ||||||
| 81 | must => sub { | ||||||
| 82 | (Email::Valid->address($_), 'Not a valid email address.') | ||||||
| 83 | }, | ||||||
| 84 | ], | ||||||
| 85 | password => [ | ||||||
| 86 | required => 1, | ||||||
| 87 | must => length_in_range(8, 72), | ||||||
| 88 | ], | ||||||
| 89 | groups => [ | ||||||
| 90 | optional => 1, | ||||||
| 91 | into => split_by(qr/,/), | ||||||
| 92 | each_into => trim(), | ||||||
| 93 | each_must => limit_character_set('a-z', 'A-Z', '0-9', '_', '-'), | ||||||
| 94 | ], | ||||||
| 95 | ]; | ||||||
| 96 | |||||||
| 97 | sub add_user { | ||||||
| 98 | 0 | 1 | my ($self, $ctx) = @_; | ||||
| 99 | |||||||
| 100 | 0 | my $form_errors; | |||||
| 101 | 0 | if ($ctx->request->method eq 'POST') { | |||||
| 102 | 0 | my $user_params; | |||||
| 103 | 0 | ($user_params, $form_errors) | |||||
| 104 | = validate_form add_user => $ctx->request->body_parameters; | ||||||
| 105 | |||||||
| 106 | 0 | if (!defined $form_errors) { | |||||
| 107 | my $user = Yukki::User->new( | ||||||
| 108 | login_name => $user_params->{login_name}, | ||||||
| 109 | password => $user_params->{password}, | ||||||
| 110 | name => $user_params->{name}, | ||||||
| 111 | email => $user_params->{email}, | ||||||
| 112 | groups => $user_params->{groups}, | ||||||
| 113 | 0 | ); | |||||
| 114 | |||||||
| 115 | 0 | $self->model('User')->save($user); | |||||
| 116 | |||||||
| 117 | 0 | $ctx->add_info('Saved '.$user->login_name.'.'); | |||||
| 118 | |||||||
| 119 | 0 | $ctx->response->redirect('/admin/user/list'); | |||||
| 120 | 0 | return; | |||||
| 121 | } | ||||||
| 122 | } | ||||||
| 123 | |||||||
| 124 | 0 | my @breadcrumb = ( | |||||
| 125 | { | ||||||
| 126 | label => 'List', | ||||||
| 127 | href => '/admin/user/list', | ||||||
| 128 | }, | ||||||
| 129 | ); | ||||||
| 130 | |||||||
| 131 | 0 | my $body = $self->view('Admin::User')->edit($ctx, { | |||||
| 132 | form => $ctx->request->body_parameters->as_hashref, | ||||||
| 133 | breadcrumb => \@breadcrumb, | ||||||
| 134 | form_errors => $form_errors, | ||||||
| 135 | }); | ||||||
| 136 | |||||||
| 137 | 0 | $ctx->response->body($body); | |||||
| 138 | } | ||||||
| 139 | |||||||
| 140 - 144 | =head2 edit_user Edit a user account. =cut | ||||||
| 145 | |||||||
| 146 | validation_spec edit_user => [ | ||||||
| 147 | name => [ | ||||||
| 148 | required => 1, | ||||||
| 149 | must => length_in_range(1, 200), | ||||||
| 150 | ], | ||||||
| 151 | email => [ | ||||||
| 152 | required => 1, | ||||||
| 153 | must => length_in_range(1, 200), | ||||||
| 154 | must => sub { | ||||||
| 155 | (Email::Valid->address($_), 'Not a valid email address.') | ||||||
| 156 | }, | ||||||
| 157 | ], | ||||||
| 158 | password => [ | ||||||
| 159 | optional => 1, | ||||||
| 160 | must => length_in_range(8, 72), | ||||||
| 161 | ], | ||||||
| 162 | groups => [ | ||||||
| 163 | optional => 1, | ||||||
| 164 | into => split_by(qr/,/), | ||||||
| 165 | each_into => trim(), | ||||||
| 166 | each_must => limit_character_set('a-z', 'A-Z', '0-9', '_', '-'), | ||||||
| 167 | ], | ||||||
| 168 | ]; | ||||||
| 169 | |||||||
| 170 | sub edit_user { | ||||||
| 171 | 0 | 1 | my ($self, $ctx) = @_; | ||||
| 172 | |||||||
| 173 | 0 | my $login_name = $ctx->request->path_parameters->{login_name}; | |||||
| 174 | 0 | my $user = $self->model('User')->find(login_name => $login_name); | |||||
| 175 | |||||||
| 176 | 0 | my $form_errors; | |||||
| 177 | 0 | if ($ctx->request->method eq 'POST') { | |||||
| 178 | 0 | my $user_params; | |||||
| 179 | 0 | ($user_params, $form_errors) | |||||
| 180 | = validate_form edit_user => $ctx->request->body_parameters; | ||||||
| 181 | |||||||
| 182 | 0 | if (!defined $form_errors) { | |||||
| 183 | $user->password($user_params->{password}) | ||||||
| 184 | 0 | if defined $user_params->{password}; | |||||
| 185 | 0 | $user->name($user_params->{name}); | |||||
| 186 | 0 | $user->email($user_params->{email}); | |||||
| 187 | $user->groups->@* = $user_params->{groups}->@* | ||||||
| 188 | 0 | if defined $user_params->{groups}; | |||||
| 189 | |||||||
| 190 | 0 | $self->model('User')->save($user); | |||||
| 191 | |||||||
| 192 | 0 | $ctx->add_info('Saved '.$user->login_name.'.'); | |||||
| 193 | |||||||
| 194 | 0 | $ctx->response->redirect('/admin/user/list'); | |||||
| 195 | 0 | return; | |||||
| 196 | } | ||||||
| 197 | } | ||||||
| 198 | |||||||
| 199 | 0 | my @breadcrumb = ( | |||||
| 200 | { | ||||||
| 201 | label => 'List', | ||||||
| 202 | href => '/admin/user/list', | ||||||
| 203 | }, | ||||||
| 204 | ); | ||||||
| 205 | |||||||
| 206 | 0 | my $body = $self->view('Admin::User')->edit($ctx, { | |||||
| 207 | user => $user, | ||||||
| 208 | breadcrumb => \@breadcrumb, | ||||||
| 209 | form_errors => $form_errors, | ||||||
| 210 | }); | ||||||
| 211 | |||||||
| 212 | 0 | $ctx->response->body($body); | |||||
| 213 | } | ||||||
| 214 | |||||||
| 215 - 219 | =head2 remove_user Display a confirmation page and confirm the deletion of a user. =cut | ||||||
| 220 | |||||||
| 221 | sub remove_user { | ||||||
| 222 | 0 | 1 | my ($self, $ctx) = @_; | ||||
| 223 | |||||||
| 224 | 0 | my $login_name = $ctx->request->path_parameters->{login_name}; | |||||
| 225 | 0 | my $user = $self->model('User')->find(login_name => $login_name); | |||||
| 226 | |||||||
| 227 | 0 | if (!$user) { | |||||
| 228 | 0 | $ctx->add_errors("No user found with login naem $login_name."); | |||||
| 229 | 0 | $ctx->response->redirect('/admin/user/list'); | |||||
| 230 | 0 | return; | |||||
| 231 | } | ||||||
| 232 | |||||||
| 233 | 0 | my @breadcrumb = ( | |||||
| 234 | { | ||||||
| 235 | label => 'List', | ||||||
| 236 | href => '/admin/user/list', | ||||||
| 237 | }, | ||||||
| 238 | ); | ||||||
| 239 | |||||||
| 240 | 0 | my $confirmed = $ctx->request->body_parameters->{confirmed}; | |||||
| 241 | 0 | if ($ctx->request->method eq 'POST' and $confirmed) { | |||||
| 242 | |||||||
| 243 | 0 | $self->model('User')->delete($user); | |||||
| 244 | 0 | $ctx->add_info("Removed user with login name $login_name."); | |||||
| 245 | 0 | $ctx->response->redirect('/admin/user/list'); | |||||
| 246 | 0 | return; | |||||
| 247 | } | ||||||
| 248 | |||||||
| 249 | 0 | my $body = $self->view('Admin::User')->remove($ctx, { | |||||
| 250 | title => 'Remove ' . $user->login_name, | ||||||
| 251 | user => $user, | ||||||
| 252 | breadcrumb => \@breadcrumb, | ||||||
| 253 | return_link => $ctx->rebase_url('/admin/user/list'), | ||||||
| 254 | }); | ||||||
| 255 | |||||||
| 256 | 0 | $ctx->response->body($body); | |||||
| 257 | } | ||||||
| 258 | |||||||
| 259 | 1; | ||||||