File Coverage

File:lib/Yukki/Web/Controller/Admin/User.pm
Coverage:27.5%

linestmtbrancondsubpodtimecode
1package 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
12with '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
28sub 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
49sub 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
68validation_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
97sub 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
146validation_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
170sub 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
221sub 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
2591;