... | ... |
@@ -6,6 +6,11 @@ |
6 | 6 |
;git_bin=/usr/local/bin/git |
7 | 7 |
;git_bin=~/local/git |
8 | 8 |
|
9 |
+[admin] |
|
10 |
+;;; If you forget admin password, |
|
11 |
+;;; set this value to 1 and access /reset-password page. |
|
12 |
+;;; Forget to comment out after resetting password. |
|
13 |
+;reset_password=1 |
|
9 | 14 |
|
10 | 15 |
[hypnotoad] |
11 | 16 |
listen=http://*:10020 |
... | ... |
@@ -150,6 +150,9 @@ EOS |
150 | 150 |
# Auto route |
151 | 151 |
$self->plugin('AutoRoute'); |
152 | 152 |
|
153 |
+ # Reset admin password |
|
154 |
+ |
|
155 |
+ |
|
153 | 156 |
# User defined Routes |
154 | 157 |
{ |
155 | 158 |
my $r = $self->routes->route->to('main#'); |
... | ... |
@@ -5,12 +5,29 @@ use Carp (); |
5 | 5 |
use File::Basename (); |
6 | 6 |
use Mojo::JSON; |
7 | 7 |
use Encode qw/encode decode/; |
8 |
+use Digest::MD5 'md5_hex'; |
|
8 | 9 |
|
9 | 10 |
sub croak { Carp::croak(@_) } |
10 | 11 |
sub dirname { File::Basename::dirname(@_) } |
11 | 12 |
|
12 | 13 |
has 'cntl'; |
13 | 14 |
|
15 |
+sub encrypt_password { |
|
16 |
+ my ($self, $password) = @_; |
|
17 |
+ |
|
18 |
+ my $salt; |
|
19 |
+ $salt .= int(rand 10) for (1 .. 40); |
|
20 |
+ my $password_encryped = md5_hex md5_hex "$salt$password"; |
|
21 |
+ |
|
22 |
+ return ($password_encryped, $salt); |
|
23 |
+} |
|
24 |
+ |
|
25 |
+sub check_password { |
|
26 |
+ my ($self, $password, $salt, $password_encryped) = @_; |
|
27 |
+ |
|
28 |
+ return md5_hex md5_hex "$salt$password" eq $password_encryped; |
|
29 |
+} |
|
30 |
+ |
|
14 | 31 |
sub new { |
15 | 32 |
my ($class, $cntl) = @_; |
16 | 33 |
|
... | ... |
@@ -1,21 +1,12 @@ |
1 | 1 |
<% |
2 |
- use Mojo::Util 'md5_sum'; |
|
3 |
- |
|
4 | 2 |
my $api = gitprep_api; |
5 | 3 |
|
6 | 4 |
my $op = param('op') || ''; |
7 |
- my $state = 'start'; |
|
8 | 5 |
|
9 | 6 |
my $errors; |
10 | 7 |
if ($op eq 'create') { |
11 |
- $state = 'create'; |
|
12 | 8 |
|
13 |
- my $params = { |
|
14 |
- id => scalar param('id'), |
|
15 |
- password => scalar param('password'), |
|
16 |
- password2 => scalar param('password2') |
|
17 |
- }; |
|
18 |
- my $id = param('id'); |
|
9 |
+ my $params = $api->params; |
|
19 | 10 |
my $validator = $self->app->validator; |
20 | 11 |
my $rule = [ |
21 | 12 |
id => [ |
... | ... |
@@ -37,11 +28,17 @@ |
37 | 28 |
my $vresult = $validator->validate($params, $rule); |
38 | 29 |
|
39 | 30 |
if ($vresult->is_ok) { |
40 |
- my $valid_params = $vresult->data; |
|
41 |
- my $id = delete $valid_params->{id}; |
|
42 |
- $valid_params->{password} = md5_sum $valid_params->{password}; |
|
43 |
- my $config_json = $api->json($valid_params); |
|
44 | 31 |
|
32 |
+ # Valid parameters |
|
33 |
+ my $params = $vresult->data; |
|
34 |
+ my $id = delete $params->{id}; |
|
35 |
+ my ($password_encrypted, $salt) |
|
36 |
+ = $api->encrypt_password($params->{password}); |
|
37 |
+ $params->{password} = $password_encrypted; |
|
38 |
+ $params->{salt} = $salt; |
|
39 |
+ my $config_json = $api->json($params); |
|
40 |
+ |
|
41 |
+ # Create user |
|
45 | 42 |
eval { app->manager->create_user($id, {config => $config_json}) }; |
46 | 43 |
if ($@) { |
47 | 44 |
app->log->error($@); |
... | ... |
@@ -53,10 +50,7 @@ |
53 | 50 |
$self->redirect_to('current'); |
54 | 51 |
} |
55 | 52 |
} |
56 |
- else { |
|
57 |
- $state = 'error'; |
|
58 |
- $errors = $vresult->messages; |
|
59 |
- } |
|
53 |
+ else { $errors = $vresult->messages } |
|
60 | 54 |
} |
61 | 55 |
%> |
62 | 56 |
|
... | ... |
@@ -1,32 +1,31 @@ |
1 | 1 |
<% |
2 | 2 |
use Mojo::JSON (); |
3 | 3 |
use Encode (); |
4 |
- use Gitprep::API; |
|
5 | 4 |
use Mojo::Util 'md5_sum'; |
6 |
- |
|
7 |
- my $api = Gitprep::API->new($self); |
|
8 | 5 |
|
6 |
+ # API |
|
7 |
+ my $api = gitprep_api; |
|
8 |
+ |
|
9 |
+ # Operator |
|
9 | 10 |
my $op = param('op') || ''; |
10 |
- my $state = 'start'; |
|
11 | 11 |
|
12 | 12 |
# DBI |
13 | 13 |
my $dbi = $self->app->dbi; |
14 | 14 |
|
15 |
+ # Errors |
|
16 |
+ my $error; |
|
17 |
+ |
|
18 |
+ # Login |
|
15 | 19 |
if ($op eq 'login') { |
16 |
- sleep 2; |
|
17 |
- $state = 'login'; |
|
20 |
+ sleep 3; |
|
18 | 21 |
|
19 |
- my $params = { |
|
20 |
- id => scalar param('id'), |
|
21 |
- password => scalar param('password'), |
|
22 |
- }; |
|
23 |
- my $id = param('id'); |
|
22 |
+ # Validation |
|
23 |
+ my $params = $api->params; |
|
24 | 24 |
my $validator = $self->app->validator; |
25 | 25 |
my $password_check = sub { |
26 | 26 |
my $values = shift; |
27 | 27 |
|
28 | 28 |
my ($id, $password) = @$values; |
29 |
- my $password_md5 = md5_sum $password; |
|
30 | 29 |
|
31 | 30 |
my $config_json |
32 | 31 |
= $dbi->model('user')->select('config', id => $id)->value; |
... | ... |
@@ -35,9 +34,14 @@ |
35 | 34 |
|
36 | 35 |
my $config = $api->json($config_json); |
37 | 36 |
|
38 |
- return $config->{password} eq $password_md5; |
|
37 |
+ my $is_valid = $api->check_password( |
|
38 |
+ $password, |
|
39 |
+ $config->{salt}, |
|
40 |
+ $config->{password} |
|
41 |
+ ); |
|
42 |
+ |
|
43 |
+ return $is_valid; |
|
39 | 44 |
}; |
40 |
- |
|
41 | 45 |
my $rule = [ |
42 | 46 |
id => [ |
43 | 47 |
'any' |
... | ... |
@@ -51,36 +55,33 @@ |
51 | 55 |
$password_check |
52 | 56 |
] |
53 | 57 |
]; |
54 |
- my $vresult = $validator->validate($params, $rule); |
|
58 |
+ my $vresult = $self->app->validator->validate($params, $rule); |
|
55 | 59 |
|
56 | 60 |
if ($vresult->is_ok) { |
57 |
- my $valid_params = $vresult->data; |
|
58 |
- my $id = $valid_params->{id}; |
|
59 |
- my $password = $valid_params->{password}; |
|
60 |
- my $password_md5 = md5_sum $password; |
|
61 | 61 |
|
62 |
+ # Login success |
|
63 |
+ my $params = $vresult->data; |
|
64 |
+ my $id = $params->{id}; |
|
65 |
+ my $password = $params->{password}; |
|
62 | 66 |
my $config_json = $self->app->dbi->model('user')->select('config', id => $id)->value; |
63 | 67 |
my $config = $api->json($config_json); |
68 |
+ my $password_encrypted = $config->{password}; |
|
64 | 69 |
my $admin = $config->{admin}; |
65 | 70 |
session(user_id => $id); |
66 |
- session(user_password => $password_md5); |
|
71 |
+ session(user_password => $password_encrypted); |
|
67 | 72 |
|
73 |
+ # Go to admin page |
|
68 | 74 |
if ($admin) { |
69 | 75 |
$self->redirect_to('/_admin'); |
70 | 76 |
return 1; |
71 | 77 |
} |
78 |
+ # Go to user page |
|
72 | 79 |
else { |
73 | 80 |
$self->redirect_to("/$id"); |
74 | 81 |
return 1; |
75 | 82 |
} |
76 | 83 |
} |
77 |
- else { |
|
78 |
- $state = 'error'; |
|
79 |
- } |
|
80 |
- } elsif ($op eq 'logout') { |
|
81 |
- session(expires => 1); |
|
82 |
- $self->redirect_to('/'); |
|
83 |
- return 1; |
|
84 |
+ else { $error = 'User name or password is wrong' } |
|
84 | 85 |
} |
85 | 86 |
%> |
86 | 87 |
|
... | ... |
@@ -88,31 +89,46 @@ |
88 | 89 |
|
89 | 90 |
%= include '/include/header'; |
90 | 91 |
|
91 |
- % my $id = ''; |
|
92 |
- % if (flash('success')) { |
|
93 |
- <br> |
|
94 |
- <b><center>Start up success! Please login as admin user.</center></b> |
|
95 |
- % $id = flash('id'); |
|
96 |
- % } |
|
97 |
- |
|
98 |
- <div class="border-gray" style="padding-top:15px;padding-left:60px;width:300px;margin-left:auto;margin-right:auto"> |
|
99 |
- <form action="<%= url_for->query(op => 'login') %>" method="post"> |
|
100 |
- <div class="control-group"> |
|
101 |
- <label class="control-label" for="user-name">User name</label> |
|
102 |
- <div class="controls"> |
|
103 |
- <%= input_tag id => $id, type => 'text', placeholder => 'User', id =>'user-name'%> |
|
104 |
- </div> |
|
92 |
+ <div class="container"> |
|
93 |
+ % my $id = ''; |
|
94 |
+ % if (flash('admin_user_created')) { |
|
95 |
+ % $id = 'admin'; |
|
96 |
+ <div class="alert alert-success"> |
|
97 |
+ <button type="button" class="close" data-dismiss="alert">×</button> |
|
98 |
+ Admin user is created. Let's login as admin user. |
|
105 | 99 |
</div> |
106 |
- <div class="control-group"> |
|
107 |
- <label class="control-label" for="input-password">Password</label> |
|
108 |
- <div class="controls"> |
|
109 |
- <%= password_field 'password', id => 'input-password', placeholder => 'Password' %> |
|
110 |
- </div> |
|
100 |
+ % } |
|
101 |
+ |
|
102 |
+ % if ($error) { |
|
103 |
+ <div class="alert alert-error"> |
|
104 |
+ <button type="button" class="close" data-dismiss="alert">×</button> |
|
105 |
+ <div><%= $error %></div> |
|
111 | 106 |
</div> |
112 |
- <div class="control-group"> |
|
113 |
- <div class="controls"> |
|
114 |
- <button type="submit" class="btn">Sign in</button> |
|
107 |
+ % } |
|
108 |
+ |
|
109 |
+ <div class="well border-gray" |
|
110 |
+ style="background-color:white;padding-top:15px;padding-left:60px;width:300px;margin-left:auto;margin-right:auto" |
|
111 |
+ > |
|
112 |
+ <form action="<%= url_for->query(op => 'login') %>" method="post"> |
|
113 |
+ <div class="control-group"> |
|
114 |
+ <label class="control-label" for="user-name">User name</label> |
|
115 |
+ <div class="controls"> |
|
116 |
+ <%= input_tag id => $id, type => 'text', placeholder => 'User', id =>'user-name'%> |
|
117 |
+ </div> |
|
115 | 118 |
</div> |
116 |
- </div> |
|
117 |
- </form> |
|
119 |
+ <div class="control-group"> |
|
120 |
+ <label class="control-label" for="input-password">Password</label> |
|
121 |
+ <div class="controls"> |
|
122 |
+ <%= password_field 'password', id => 'input-password', placeholder => 'Password' %> |
|
123 |
+ </div> |
|
124 |
+ </div> |
|
125 |
+ <div class="control-group"> |
|
126 |
+ <div class="controls"> |
|
127 |
+ <button type="submit" class="btn">Sign in</button> |
|
128 |
+ </div> |
|
129 |
+ </div> |
|
130 |
+ </form> |
|
131 |
+ </div> |
|
118 | 132 |
</div> |
133 |
+ |
|
134 |
+ %= include '/include/footer'; |
... | ... |
@@ -0,0 +1,6 @@ |
1 |
+<% |
|
2 |
+ my $from = param('from') || '/'; |
|
3 |
+ session(expires => 1); |
|
4 |
+ $self->redirect_to($from); |
|
5 |
+ return 1; |
|
6 |
+%> |
... | ... |
@@ -1,129 +1,100 @@ |
1 | 1 |
<% |
2 |
- use Gitprep::API; |
|
3 | 2 |
use Mojo::Util 'md5_sum'; |
4 | 3 |
|
5 |
- my $api = Gitprep::API->new($self); |
|
4 |
+ # API |
|
5 |
+ my $api = gitprep_api; |
|
6 | 6 |
|
7 |
+ # Operator |
|
7 | 8 |
my $op = param('op') || ''; |
8 |
- my $state = 'start'; |
|
9 | 9 |
|
10 | 10 |
my $errors; |
11 | 11 |
if ($op eq 'create') { |
12 |
- $state = 'create'; |
|
13 | 12 |
|
14 |
- my $params = { |
|
15 |
- id => scalar param('id'), |
|
16 |
- password => scalar param('password'), |
|
17 |
- password2 => scalar param('password2') |
|
18 |
- }; |
|
19 |
- my $id = param('id'); |
|
20 |
- my $validator = $self->app->validator; |
|
21 |
- my $rule = [ |
|
22 |
- id => [ |
|
23 |
- ['not_blank' => 'Input admin user.'], |
|
24 |
- [{'regex' => qr/^[a-zA-Z0-9_]+$/} => 'Admin User contain invalid character.'], |
|
25 |
- [{'length' => {max => 20}} => 'Admin User is too long.'] |
|
26 |
- ], |
|
27 |
- password => [ |
|
28 |
- ['not_blank' => 'Input password.'], |
|
29 |
- ['ascii' => 'Password contain invalid character.'], |
|
30 |
- [{'length' => {max => 20}} => 'Password is too long.'] |
|
31 |
- ], |
|
32 |
- {password_check => [qw/password password2/]} |
|
33 |
- => {copy => 0} |
|
34 |
- => [ |
|
35 |
- ['duplication' => "Two password don't match"] |
|
36 |
- ] |
|
37 |
- ]; |
|
38 |
- my $vresult = $validator->validate($params, $rule); |
|
13 |
+ # Sleep to protect password atack |
|
14 |
+ sleep 3; |
|
39 | 15 |
|
40 |
- if ($vresult->is_ok) { |
|
41 |
- my $valid_params = $vresult->data; |
|
42 |
- my $id = delete $valid_params->{id}; |
|
43 |
- $valid_params->{admin} = 1; |
|
44 |
- $valid_params->{password} = md5_sum $valid_params->{password}; |
|
45 |
- my $config_json = $api->json($valid_params); |
|
46 |
- |
|
47 |
- $self->app->dbi->model('user')->insert({id => $id, config => $config_json}); |
|
48 |
- |
|
49 |
- $self->flash(success => 1); |
|
50 |
- $self->flash(id => $id); |
|
51 |
- $self->redirect_to('/_login'); |
|
16 |
+ # Check existence admin user |
|
17 |
+ my $admin_user = app->dbi->model('user')->select(id => 'admin')->one; |
|
18 |
+ if ($admin_user) { |
|
19 |
+ $errors = ['admin user already exists']; |
|
52 | 20 |
} |
53 | 21 |
else { |
54 |
- $state = 'error'; |
|
55 |
- $errors = $vresult->messages; |
|
22 |
+ # Validation |
|
23 |
+ my $params = $api->params; |
|
24 |
+ my $rule = [ |
|
25 |
+ password => [ |
|
26 |
+ ['not_blank' => 'Password is emplty'], |
|
27 |
+ ['ascii' => 'Password contain invalid character.'], |
|
28 |
+ [{'length' => {max => 20}} => 'Password is too long.'] |
|
29 |
+ ], |
|
30 |
+ {password_check => [qw/password password2/]} |
|
31 |
+ => {copy => 0} |
|
32 |
+ => [ |
|
33 |
+ ['duplication' => "Two password don't match"] |
|
34 |
+ ] |
|
35 |
+ ]; |
|
36 |
+ my $vresult = $self->app->validator->validate($params, $rule); |
|
37 |
+ |
|
38 |
+ if ($vresult->is_ok) { |
|
39 |
+ |
|
40 |
+ # Valida parameters |
|
41 |
+ my $params = $vresult->data; |
|
42 |
+ my $id = 'admin'; |
|
43 |
+ $params->{admin} = 1; |
|
44 |
+ my ($password_encryped, $salt) |
|
45 |
+ = $api->encrypt_password($params->{password}); |
|
46 |
+ $params->{password} = $password_encryped; |
|
47 |
+ $params->{salt} = $salt; |
|
48 |
+ my $config_json = $api->json($params); |
|
49 |
+ |
|
50 |
+ # Create admin user |
|
51 |
+ $self->app->dbi->model('user')->insert({id => $id, config => $config_json}); |
|
52 |
+ |
|
53 |
+ # Redirect |
|
54 |
+ $self->flash(admin_user_created => 1); |
|
55 |
+ $self->redirect_to('/_login'); |
|
56 |
+ } |
|
57 |
+ else { $errors = $vresult->messages } |
|
56 | 58 |
} |
57 | 59 |
} |
58 | 60 |
%> |
59 | 61 |
|
60 |
-%= stylesheet begin |
|
61 |
- .error { |
|
62 |
- margin-left:auto; |
|
63 |
- margin-right:auto; |
|
64 |
- width:300px; |
|
65 |
- color:red; |
|
66 |
- margin-bottom:10px; |
|
67 |
- } |
|
68 |
- .account_panel { |
|
69 |
- margin-top:50px; |
|
70 |
- margin-left:auto; |
|
71 |
- margin-right:auto; |
|
72 |
- width:500px; |
|
73 |
- background-color:#e6f1f6; |
|
74 |
- padding:30px; |
|
75 |
- border:1px solid #c5d5dd; |
|
76 |
- border-radius:7px; |
|
77 |
- } |
|
78 |
- .account { |
|
79 |
- margin-left:auto; |
|
80 |
- margin-right:auto; |
|
81 |
- width:300px; |
|
82 |
- margin-bottom:10px; |
|
83 |
- } |
|
84 |
- .account_panel .atitle { |
|
85 |
- font-size:130%; |
|
86 |
- maring-top:30px; |
|
87 |
- } |
|
88 |
- .submit { |
|
89 |
- text-align:center; |
|
90 |
- } |
|
91 |
- .submit input { |
|
92 |
- width:200px; |
|
93 |
- height:40px; |
|
94 |
- } |
|
95 |
-% end |
|
96 |
- |
|
97 | 62 |
% layout 'common'; |
98 |
-%= include '/css/common'; |
|
99 | 63 |
|
100 |
-% if ($state eq 'start' || $state eq 'error') { |
|
101 |
- <div class="account_panel"> |
|
102 |
- % if ($state eq 'error') { |
|
103 |
- <div class="error"> |
|
64 |
+ %= include '/include/header'; |
|
65 |
+ |
|
66 |
+ <div class="container"> |
|
67 |
+ % if ($errors) { |
|
68 |
+ <div class="alert alert-error"> |
|
69 |
+ <button type="button" class="close" data-dismiss="alert">×</button> |
|
104 | 70 |
% for my $error (@$errors) { |
105 | 71 |
<div><%= $error %></div> |
106 | 72 |
% } |
107 | 73 |
</div> |
108 | 74 |
% } |
109 |
- <form action="<%= url_for->query(op => 'create') %>" method="post"> |
|
110 |
- <div class="account"> |
|
111 |
- <table> |
|
112 |
- <tr class="auser"> |
|
113 |
- <td>Admin User: </td> |
|
114 |
- <td><%= input_tag id => 'admin' %></td> |
|
115 |
- </tr> |
|
116 |
- <tr class="apassword"> |
|
117 |
- <td>Password: </td> |
|
118 |
- <td><%= password_field 'password' %></td> |
|
119 |
- </tr> |
|
120 |
- <tr class="apassword"> |
|
121 |
- <td>(Again): </td> |
|
122 |
- <td><%= password_field 'password2' %></td> |
|
123 |
- </tr> |
|
124 |
- </table> |
|
125 |
- </div> |
|
126 |
- <div class="submit"><input type="submit" value="Start Git Prep!"></div> |
|
127 |
- </form> |
|
75 |
+ <div class="text-center"><h3>Create Admin User</h3></div> |
|
76 |
+ <div class="well" style="background-color:white;padding-top:15px;padding-left:60px;width:300px;margin-left:auto;margin-right:auto"> |
|
77 |
+ <form action="<%= url_for->query(op => 'create') %>" method="post"> |
|
78 |
+ <div class="control-group"> |
|
79 |
+ <label class="control-label" for="user-name">User name</label> |
|
80 |
+ <div> |
|
81 |
+ <b>admin</b> |
|
82 |
+ </div> |
|
83 |
+ </div> |
|
84 |
+ <div class="control-group"> |
|
85 |
+ <label class="control-label" for="input-password">Password</label> |
|
86 |
+ <div class="controls"> |
|
87 |
+ <%= password_field 'password', id => 'input-password', placeholder => 'Password' %> |
|
88 |
+ <%= password_field 'password2', id => 'input-password', placeholder => 'Password Again' %> |
|
89 |
+ </div> |
|
90 |
+ </div> |
|
91 |
+ <div class="control-group"> |
|
92 |
+ <div class="controls"> |
|
93 |
+ <button type="submit" class="btn">Create Admin User</button> |
|
94 |
+ </div> |
|
95 |
+ </div> |
|
96 |
+ </form> |
|
97 |
+ </div> |
|
128 | 98 |
</div> |
129 |
-% } |
|
99 |
+ |
|
100 |
+ %= include '/include/footer'; |
... | ... |
@@ -11,11 +11,14 @@ |
11 | 11 |
% if ($api->logined) { |
12 | 12 |
<div style="margin-top:5px"> |
13 | 13 |
<div> |
14 |
- % my $user = session('user_id'); |
|
14 |
+ % my $user = session('user_id') || ''; |
|
15 | 15 |
<i class="icon-user"></i><a href="<%= url_for("/$user") %>"><%= $user %></a> |
16 | 16 |
</div> |
17 |
- <a class="btn btn-small" href="<%= url_for("/_admin/create") %>">Create a new repo</a> |
|
18 |
- <a class="btn btn-small" href="<%= url_for("/_login?op=logout") %>">Sign out</a> |
|
17 |
+ % unless ($user eq 'admin') { |
|
18 |
+ <a class="btn btn-small" href="<%= url_for("/_admin/create") %>">Create a new repo</a> |
|
19 |
+ % } |
|
20 |
+ % my $url = url_with->to_abs; |
|
21 |
+ <a class="btn btn-small" href="<%= url_for("/_logout?from=$url") %>">Sign out</a> |
|
19 | 22 |
</div> |
20 | 23 |
% } else { |
21 | 24 |
<div style="margin-top:15px"> |
... | ... |
@@ -0,0 +1,114 @@ |
1 |
+<% |
|
2 |
+ use Mojo::Util 'md5_sum'; |
|
3 |
+ |
|
4 |
+ # API |
|
5 |
+ my $api = gitprep_api; |
|
6 |
+ |
|
7 |
+ # Operator |
|
8 |
+ my $op = param('op') || ''; |
|
9 |
+ |
|
10 |
+ # Error |
|
11 |
+ my $errors; |
|
12 |
+ |
|
13 |
+ # Reset password |
|
14 |
+ if ($op eq 'reset') { |
|
15 |
+ |
|
16 |
+ # Sleep to protect password atack |
|
17 |
+ sleep 3; |
|
18 |
+ |
|
19 |
+ # Check existence admin user |
|
20 |
+ my $admin_user = app->dbi->model('user')->select(id => 'admin')->one; |
|
21 |
+ |
|
22 |
+ # Reset password |
|
23 |
+ if ($admin_user) { |
|
24 |
+ # Validation |
|
25 |
+ my $params = $api->params; |
|
26 |
+ my $rule = [ |
|
27 |
+ password => [ |
|
28 |
+ ['not_blank' => 'Password is emplty'], |
|
29 |
+ ['ascii' => 'Password contain invalid character.'], |
|
30 |
+ [{'length' => {max => 20}} => 'Password is too long.'] |
|
31 |
+ ], |
|
32 |
+ {password_check => [qw/password password2/]} |
|
33 |
+ => {copy => 0} |
|
34 |
+ => [ |
|
35 |
+ ['duplication' => "Two password don't match"] |
|
36 |
+ ] |
|
37 |
+ ]; |
|
38 |
+ my $vresult = $self->app->validator->validate($params, $rule); |
|
39 |
+ |
|
40 |
+ if ($vresult->is_ok) { |
|
41 |
+ |
|
42 |
+ # Valid parameters |
|
43 |
+ my $valid_params = $vresult->data; |
|
44 |
+ my $id = 'admin'; |
|
45 |
+ my ($new_password, $salt) |
|
46 |
+ = $api->sulted_md5_sum($valid_params->{password}); |
|
47 |
+ |
|
48 |
+ # Create admin user |
|
49 |
+ my $dbi = app->dbi; |
|
50 |
+ |
|
51 |
+ my $config_json = $dbi->model('user')->select(id => $id)->one; |
|
52 |
+ if ($config) { |
|
53 |
+ my $config = $api->json($config_json); |
|
54 |
+ $config->{password} = $new_password; |
|
55 |
+ $config->{salt} = $salt; |
|
56 |
+ $self->app->dbi->model('user')->update({config => $config_json}, id => $id); |
|
57 |
+ } |
|
58 |
+ else { $errors = ['Internal Error'] } |
|
59 |
+ |
|
60 |
+ # Redirect |
|
61 |
+ flash(message => 'Password is reset'); |
|
62 |
+ $self->redirect_to('current'); |
|
63 |
+ } |
|
64 |
+ else { $errors = $vresult->messages } |
|
65 |
+ } |
|
66 |
+ else { $errors = ['admin user no exists'] } |
|
67 |
+ } |
|
68 |
+%> |
|
69 |
+ |
|
70 |
+% layout 'common'; |
|
71 |
+ |
|
72 |
+ %= include '/include/header'; |
|
73 |
+ |
|
74 |
+ <div class="container"> |
|
75 |
+ % if (flash($message)) { |
|
76 |
+ <div class="alert alert-success"> |
|
77 |
+ <button type="button" class="close" data-dismiss="alert">×</button> |
|
78 |
+ <div><%= $message %></div> |
|
79 |
+ % } |
|
80 |
+ |
|
81 |
+ % if ($errors) { |
|
82 |
+ <div class="alert alert-error"> |
|
83 |
+ <button type="button" class="close" data-dismiss="alert">×</button> |
|
84 |
+ % for my $error (@$errors) { |
|
85 |
+ <div><%= $error %></div> |
|
86 |
+ % } |
|
87 |
+ </div> |
|
88 |
+ % } |
|
89 |
+ <div class="text-center"><h3>Reset Admin Password</h3></div> |
|
90 |
+ <div class="well" style="background-color:white;padding-top:15px;padding-left:60px;width:300px;margin-left:auto;margin-right:auto"> |
|
91 |
+ <form action="<%= url_for->query(op => 'reset') %>" method="post"> |
|
92 |
+ <div class="control-group"> |
|
93 |
+ <label class="control-label" for="user-name">User name</label> |
|
94 |
+ <div> |
|
95 |
+ <b>admin</b> |
|
96 |
+ </div> |
|
97 |
+ </div> |
|
98 |
+ <div class="control-group"> |
|
99 |
+ <label class="control-label" for="input-password">Password</label> |
|
100 |
+ <div class="controls"> |
|
101 |
+ <%= password_field 'password', id => 'input-password', placeholder => 'Password' %> |
|
102 |
+ <%= password_field 'password2', id => 'input-password', placeholder => 'Password Again' %> |
|
103 |
+ </div> |
|
104 |
+ </div> |
|
105 |
+ <div class="control-group"> |
|
106 |
+ <div class="controls"> |
|
107 |
+ <button type="submit" class="btn">Reset Admin Password</button> |
|
108 |
+ </div> |
|
109 |
+ </div> |
|
110 |
+ </form> |
|
111 |
+ </div> |
|
112 |
+ </div> |
|
113 |
+ |
|
114 |
+ %= include '/include/footer'; |