File Coverage

blib/lib/Plack/App/Register.pm
Criterion Covered Total %
statement 27 85 31.7
branch 0 24 0.0
condition 0 15 0.0
subroutine 9 16 56.2
pod n/a
total 36 140 25.7


line stmt bran cond sub pod time code
1             package Plack::App::Register;
2              
3 2     2   78149 use base qw(Plack::Component::Tags::HTML);
  2         9  
  2         1058  
4 2     2   166088 use strict;
  2         5  
  2         42  
5 2     2   9 use warnings;
  2         6  
  2         70  
6              
7 2     2   11 use Plack::Util::Accessor qw(generator message_cb redirect_register redirect_error register_cb title);
  2         13  
  2         22  
8 2     2   1361 use Plack::Request;
  2         118933  
  2         82  
9 2     2   1060 use Plack::Response;
  2         2311  
  2         78  
10 2     2   920 use Plack::Session;
  2         989  
  2         64  
11 2     2   946 use Tags::HTML::Container;
  2         2453  
  2         57  
12 2     2   1006 use Tags::HTML::Login::Register;
  2         5490  
  2         1579  
13              
14             our $VERSION = 0.02;
15              
16             sub _css {
17 0     0     my ($self, $env) = @_;
18              
19 0           $self->{'_container'}->process_css;
20 0           $self->{'_login_register'}->process_css({
21             'info' => 'blue',
22             'error' => 'red',
23             });
24              
25 0           return;
26             }
27              
28             sub _message {
29 0     0     my ($self, $env, $message_type, $message) = @_;
30              
31 0 0         if (defined $self->message_cb) {
32 0           $self->message_cb->($env, $message_type, $message);
33             }
34              
35 0           return;
36             }
37              
38             sub _prepare_app {
39 0     0     my $self = shift;
40              
41             # Defaults which rewrite defaults in module which I am inheriting.
42 0 0         if (! defined $self->generator) {
43 0           $self->generator(__PACKAGE__.'; Version: '.$VERSION);
44             }
45              
46 0 0         if (! defined $self->title) {
47 0           $self->title('Register page');
48             }
49              
50             # Inherite defaults.
51 0           $self->SUPER::_prepare_app;
52              
53             # Defaults from this module.
54 0           my %p = (
55             'css' => $self->css,
56             'tags' => $self->tags,
57             );
58 0           $self->{'_login_register'} = Tags::HTML::Login::Register->new(%p);
59 0           $self->{'_container'} = Tags::HTML::Container->new(%p);
60              
61 0           return;
62             }
63              
64             sub _process_actions {
65 0     0     my ($self, $env) = @_;
66              
67 0 0 0       if (defined $self->register_cb && $env->{'REQUEST_METHOD'} eq 'POST') {
68 0           my $req = Plack::Request->new($env);
69 0           my $body_params_hr = $req->body_parameters;
70 0           my ($status, $messages_ar) = $self->_register_check($env, $body_params_hr);
71 0           my $res = Plack::Response->new;
72 0 0         if ($status) {
73 0 0         if ($self->register_cb->($env, $body_params_hr->{'username'},
74             $body_params_hr->{'password1'})) {
75              
76 0           $self->_message($env, 'info',
77             "User '$body_params_hr->{'username'}' is registered.");
78 0           $res->redirect($self->redirect_register);
79             } else {
80 0           $res->redirect($self->redirect_error);
81             }
82             } else {
83 0           $res->redirect($self->redirect_error);
84             }
85 0           $self->psgi_app($res->finalize);
86             }
87              
88 0           return;
89             }
90              
91             sub _register_check {
92 0     0     my ($self, $env, $body_parameters_hr) = @_;
93              
94 0 0 0       if (! exists $body_parameters_hr->{'register'}
95             || $body_parameters_hr->{'register'} ne 'register') {
96              
97 0           $self->_message($env, 'error', 'There is no register POST.');
98 0           return 0;
99             }
100 0 0 0       if (! defined $body_parameters_hr->{'username'} || ! $body_parameters_hr->{'username'}) {
101 0           $self->_message($env, 'error', "Parameter 'username' doesn't defined.");
102 0           return 0;
103             }
104 0 0 0       if (! defined $body_parameters_hr->{'password1'} || ! $body_parameters_hr->{'password1'}) {
105 0           $self->_message($env, 'error', "Parameter 'password1' doesn't defined.");
106 0           return 0;
107             }
108 0 0 0       if (! defined $body_parameters_hr->{'password2'} || ! $body_parameters_hr->{'password2'}) {
109 0           $self->_message($env, 'error', "Parameter 'password2' doesn't defined.");
110 0           return 0;
111             }
112 0 0         if ($body_parameters_hr->{'password1'} ne $body_parameters_hr->{'password2'}) {
113 0           $self->_message($env, 'error', 'Passwords are not same.');
114 0           return 0;
115             }
116              
117 0           return 1;
118             }
119              
120             sub _tags_middle {
121 0     0     my ($self, $env) = @_;
122              
123 0           my $messages_ar = [];
124 0 0         if (exists $env->{'psgix.session'}) {
125 0           my $session = Plack::Session->new($env);
126 0           $messages_ar = $session->get('messages');
127 0           $session->set('messages', []);
128             }
129             $self->{'_container'}->process(
130             sub {
131 0     0     $self->{'_login_register'}->process($messages_ar);
132             },
133 0           );
134              
135 0           return;
136             }
137              
138             1;
139              
140             __END__
141              
142             =pod
143              
144             =encoding utf8
145              
146             =head1 NAME
147              
148             Plack::App::Register - Plack register application.
149              
150             =head1 SYNOPSIS
151              
152             use Plack::App::Register;
153              
154             my $obj = Plack::App::Register->new(%parameters);
155             my $psgi_ar = $obj->call($env);
156             my $app = $obj->to_app;
157              
158             =head1 METHODS
159              
160             =head2 C<new>
161              
162             my $obj = Plack::App::Register->new(%parameters);
163              
164             Constructor.
165              
166             Returns instance of object.
167              
168             =over 8
169              
170             =item * C<author>
171              
172             Author string to HTML head.
173              
174             Default value is undef.
175              
176             =item * C<content_type>
177              
178             Content type for output.
179              
180             Default value is 'text/html; charset=__ENCODING__'.
181              
182             =item * C<css>
183              
184             Instance of CSS::Struct::Output object.
185              
186             Default value is CSS::Struct::Output::Raw instance.
187              
188             =item * C<css_init>
189              
190             Reference to array with CSS::Struct structure.
191              
192             Default value is CSS initialization from Tags::HTML::Page::Begin like
193              
194             * {
195             box-sizing: border-box;
196             margin: 0;
197             padding: 0;
198             }
199              
200             =item * C<encoding>
201              
202             Set encoding for output.
203              
204             Default value is 'utf-8'.
205              
206             =item * C<favicon>
207              
208             Link to favicon.
209              
210             Default value is undef.
211              
212             =item * C<flag_begin>
213              
214             Flag that means begin of html writing via L<Tags::HTML::Page::Begin>.
215              
216             Default value is 1.
217              
218             =item * C<flag_end>
219              
220             Flag that means end of html writing via L<Tags::HTML::Page::End>.
221              
222             Default value is 1.
223              
224             =item * C<generator>
225              
226             HTML generator string.
227              
228             Default value is 'Plack::App::Register; Version: __VERSION__'.
229              
230             =item * C<message_cb>
231              
232             Callback to process message from application.
233             Arguments for callback are: C<$env>, C<$message_type> and C<$message>.
234             Returns undef.
235              
236             Default value is undef.
237              
238             =item * C<psgi_app>
239              
240             PSGI application to run instead of normal process.
241             Intent of this is change application in C<_process_actions> method.
242              
243             Default value is undef.
244              
245             =item * C<redirect_register>
246              
247             Redirect URL after successful registering.
248              
249             Default value is undef.
250              
251             =item * C<redirect_error>
252              
253             Redirect URL after error in registering.
254              
255             Default value is undef.
256              
257             =item * C<register_cb>
258              
259             Callback for main registering.
260             Arguments for callback are: C<$env>, C<username> and C<$password>.
261             Returns 0/1 for (un)successful registration.
262              
263             Default value is undef.
264              
265             =item * C<script_js>
266              
267             Reference to array with Javascript code strings.
268              
269             Default value is [].
270              
271             =item * C<script_js_src>
272              
273             Reference to array with Javascript URLs.
274              
275             Default value is [].
276              
277             =item * C<status_code>
278              
279             HTTP status code.
280              
281             Default value is 200.
282              
283             =item * C<tags>
284              
285             Instance of Tags::Output object.
286              
287             Default value is
288              
289             Tags::Output::Raw->new(
290             'xml' => 1,
291             'no_simple' => ['script', 'textarea'],
292             'preserved' => ['pre', 'style'],
293             );
294              
295             =item * C<title>
296              
297             Page title.
298              
299             Default value is 'Register page'.
300              
301             =back
302              
303             =head2 C<call>
304              
305             my $psgi_ar = $obj->call($env);
306              
307             Implementation of login page.
308              
309             Returns reference to array (PSGI structure).
310              
311             =head2 C<to_app>
312              
313             my $app = $obj->to_app;
314              
315             Creates Plack application.
316              
317             Returns Plack::Component object.
318              
319             =head1 EXAMPLE
320              
321             =for comment filename=register_psgi.pl
322              
323             use strict;
324             use warnings;
325              
326             use CSS::Struct::Output::Indent;
327             use Plack::App::Register;
328             use Plack::Runner;
329             use Tags::Output::Indent;
330              
331             # Run application.
332             my $app = Plack::App::Register->new(
333             'css' => CSS::Struct::Output::Indent->new,
334             'generator' => 'Plack::App::Register',
335             'tags' => Tags::Output::Indent->new(
336             'preserved' => ['style'],
337             'xml' => 1,
338             ),
339             )->to_app;
340             Plack::Runner->new->run($app);
341              
342             # Output:
343             # HTTP::Server::PSGI: Accepting connections at http://0:5000/
344              
345             # > curl http://localhost:5000/
346             # <!DOCTYPE html>
347             # <html lang="en">
348             # <head>
349             # <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
350             # <meta name="generator" content="Plack::App::Register" />
351             # <meta name="viewport" content="width=device-width, initial-scale=1.0" />
352             # <title>
353             # Register page
354             # </title>
355             # <style type="text/css">
356             # * {
357             # box-sizing: border-box;
358             # margin: 0;
359             # padding: 0;
360             # }
361             # .container {
362             # display: flex;
363             # align-items: center;
364             # justify-content: center;
365             # height: 100vh;
366             # }
367             # .form-register {
368             # width: 300px;
369             # background-color: #f2f2f2;
370             # padding: 20px;
371             # border-radius: 5px;
372             # box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
373             # }
374             # .form-register fieldset {
375             # border: none;
376             # padding: 0;
377             # margin-bottom: 20px;
378             # }
379             # .form-register legend {
380             # font-weight: bold;
381             # margin-bottom: 10px;
382             # }
383             # .form-register p {
384             # margin: 0;
385             # padding: 10px 0;
386             # }
387             # .form-register label {
388             # display: block;
389             # font-weight: bold;
390             # margin-bottom: 5px;
391             # }
392             # .form-register input[type="text"], .form-register input[type="password"] {
393             # width: 100%;
394             # padding: 8px;
395             # border: 1px solid #ccc;
396             # border-radius: 3px;
397             # }
398             # .form-register button[type="submit"] {
399             # width: 100%;
400             # padding: 10px;
401             # background-color: #4CAF50;
402             # color: #fff;
403             # border: none;
404             # border-radius: 3px;
405             # cursor: pointer;
406             # }
407             # .form-register button[type="submit"]:hover {
408             # background-color: #45a049;
409             # }
410             # .form-register .messages {
411             # text-align: center;
412             # }
413             # .info {
414             # color: blue;
415             # }
416             # .error {
417             # color: red;
418             # }
419             # </style>
420             # </head>
421             # <body>
422             # <div class="container">
423             # <div class="inner">
424             # <form class="form-register" method="post">
425             # <fieldset>
426             # <legend>
427             # Register
428             # </legend>
429             # <p>
430             # <label for="username" />
431             # User name
432             # <input type="text" name="username" id="username" />
433             # </p>
434             # <p>
435             # <label for="password1">
436             # Password #1
437             # </label>
438             # <input type="password" name="password1" id="password1" />
439             # </p>
440             # <p>
441             # <label for="password2">
442             # Password #2
443             # </label>
444             # <input type="password" name="password2" id="password2" />
445             # </p>
446             # <p>
447             # <button type="submit" name="register" value="register">
448             # Register
449             # </button>
450             # </p>
451             # </fieldset>
452             # </form>
453             # </div>
454             # </div>
455             # </body>
456             # </html>
457              
458             =head1 DEPENDENCIES
459              
460             L<Plack::Component::Tags::HTML>,
461             L<Plack::Request>,
462             L<Plack::Response>,
463             L<Plack::Session>,
464             L<Plack::Util::Accessor>,
465             L<Tags::HTML::Container>,
466             L<Tags::HTML::Login::Register>.
467              
468             =head1 SEE ALSO
469              
470             =over
471              
472             =item L<Plack::App::Login>
473              
474             Plack login application.
475              
476             =item L<Plack::App::Login::Password>
477              
478             Plack login/password application.
479              
480             =back
481              
482             =head1 REPOSITORY
483              
484             L<https://github.com/michal-josef-spacek/Plack-App-Register>
485              
486             =head1 AUTHOR
487              
488             Michal Josef Špaček L<mailto:skim@cpan.org>
489              
490             L<http://skim.cz>
491              
492             =head1 LICENSE AND COPYRIGHT
493              
494             © 2023 Michal Josef Špaček
495              
496             BSD 2-Clause License
497              
498             =head1 VERSION
499              
500             0.02
501              
502             =cut