Showing 5 changed files with 122 additions and 111 deletions
+1 -1
templates/auto/_admin/user/create.html.ep
... ...
@@ -99,6 +99,6 @@
99 99
         </div>
100 100
       </form>
101 101
     </div>
102
-    <div class="text-center" style="margin-bottom:20px"><big><a href="<%= url_for('/_admin/users') %>">See Users</a></big></div>
102
+    <div class="text-center" style="margin-bottom:20px"><big><a href="<%= url_for('/_admin/users') %>">Users</a></big></div>
103 103
   </div>
104 104
   %= include '/include/footer';
-99
templates/auto/_admin/user/delete.html.ep
... ...
@@ -1,99 +0,0 @@
1
-<%
2
-  my $api = gitprep_api;
3
-  
4
-  my $user = param('user');
5
-  my $op = param('op') || '';
6
-  
7
-  my $errors;
8
-  if ($op eq 'delete') {
9
-
10
-    unless ($api->logined) {
11
-      return $self->render_exception;
12
-    }
13
-
14
-    # Validation
15
-    my $params = $api->params;
16
-    my $validator = $self->app->validator;
17
-    my $rule = [
18
-      user => [
19
-        ['not_blank' => 'User name is empty.'],
20
-        [{'regex' => qr/^[a-zA-Z0-9_]+$/} => 'User name contain invalid character.'],
21
-        [{'length' => {max => 20}} => 'User name is too long.']
22
-      ]
23
-    ];
24
-    my $vresult = $validator->validate($params, $rule);
25
-    
26
-    if ($vresult->is_ok) {
27
-      
28
-      # Valid parameters
29
-      my $params = $vresult->data;
30
-      my $user = $params->{user};
31
-      
32
-      # Delete user
33
-      eval { app->manager->delete_user($user) };
34
-      if ($@) {
35
-        app->log->error($@);
36
-        $errors = ['Internal Error'];
37
-      }
38
-      else {
39
-        $self->flash(user_deleted => 1);
40
-        $self->flash(user => $user);
41
-        $self->redirect_to('/_admin/users');
42
-      }
43
-    }
44
-    else { $errors = $vresult->messages }
45
-  }
46
-%>
47
-
48
-% layout 'common';
49
-
50
-  %= include '/include/header';
51
-
52
-  <div class="container">
53
-    <div class="alert">
54
-      <button type="button" class="close" data-dismiss="alert">&times;</button>
55
-      <p>
56
-        <big>
57
-          <big>
58
-            If you click delete button, user and all of user's repositories is deleted.
59
-            Be careful!
60
-          </big>
61
-        </big>
62
-      </p>
63
-    </div>
64
-
65
-    % my $id = '';
66
-    % if (flash('success')) {
67
-      <div class="alert alert-success">
68
-        <button type="button" class="close" data-dismiss="alert">&times;</button>
69
-        Success: User <b><%= flash('user') %></b> is deleted.
70
-      </div>
71
-    % }
72
-    
73
-    % if ($errors) {
74
-      <div class="alert">
75
-        <button type="button" class="close" data-dismiss="alert">&times;</button>
76
-        % for my $error (@$errors) {
77
-          <p><%= $error %></p>
78
-        % }
79
-      </div>
80
-    % }
81
-    
82
-    <div class="text-center"><h3>Delete User</h3></div>
83
-    <div class="well" style="background:white;padding-top:15px;padding-left:60px;width:300px;margin-left:auto;margin-right:auto">
84
-      <form action="<%= url_for->query(op => 'delete') %>" method="post">
85
-        <div class="control-group">
86
-          <label class="control-label" for="user-name">User name</label>
87
-          <b><big><big><%= $user %></big></big></b>
88
-        </div>
89
-        %= hidden_field user => $user;
90
-        <div class="control-group">
91
-          <div class="controls">
92
-            <button type="submit" class="btn">Delete user and repositories</button>
93
-          </div>
94
-        </div>
95
-      </form>
96
-    </div>
97
-    <div class="text-center" style="margin-bottom:20px"><big><a href="<%= url_for('/_admin/users') %>">Users</a></big></div>
98
-  </div>
99
-  %= include '/include/footer';
+79 -5
templates/auto/_admin/users.html.ep
... ...
@@ -1,16 +1,86 @@
1 1
 <%
2
+  my $op = param('op') || '';
3
+  my $api = gitprep_api;
4
+  
5
+  my $errors;
6
+  if ($op eq 'delete' && lc $self->req->method eq 'post') {
7
+
8
+    # Validation
9
+    my $params = $api->params;
10
+    my $validator = $self->app->validator;
11
+    my $rule = [
12
+      user => [
13
+        ['not_blank' => 'User name is empty.'],
14
+        [{'regex' => qr/^[a-zA-Z0-9_]+$/} => 'User name contains invalid character.'],
15
+        [{'length' => {max => 20}} => 'User name is too long.']
16
+      ]
17
+    ];
18
+    my $vresult = $validator->validate($params, $rule);
19
+    
20
+    if ($vresult->is_ok) {
21
+      
22
+      # Valid parameters
23
+      my $params = $vresult->data;
24
+      my $user = $params->{user};
25
+      
26
+      # Delete user
27
+      eval { app->manager->delete_user($user) };
28
+      if ($@) {
29
+        app->log->error($@);
30
+        $errors = ['Internal Error'];
31
+      }
32
+      else {
33
+        $self->flash(message => "User $user is deleted");
34
+        $self->redirect_to('current');
35
+      }
36
+    }
37
+    else { $errors = $vresult->messages }
38
+  }
39
+  
2 40
   my $users = app->manager->users;
3 41
 %>
4 42
 
5 43
 % layout 'common';
6 44
 
45
+  %= javascript begin
46
+    $(document).ready(function () {
47
+      
48
+      // Confirm delete
49
+      $('.delete-btn').on('click', function () {
50
+        var user = $(this).attr('user');
51
+        
52
+        var input = window.prompt(
53
+          'Are you really delete user "' + user
54
+          + '". User and user\'s all repositories are deleted. Please input user name.'
55
+        );
56
+        
57
+        if (user === input) {
58
+          return true;
59
+        }
60
+        else {
61
+          return false;
62
+        }
63
+      });
64
+    });
65
+  % end
66
+
7 67
   %= include '/include/header';
8 68
 
9 69
   <div class="container">
10
-    % if (flash('user_deleted')) {
70
+
71
+    % if (my $message = flash('message')) {
11 72
       <div class="alert alert-success">
12 73
         <button type="button" class="close" data-dismiss="alert">&times;</button>
13
-        Success: User <b><%= flash('user') %></b> is deleted.
74
+        %= $message;
75
+      </div>
76
+    % }
77
+    
78
+    % if ($errors) {
79
+      <div class="alert">
80
+        <button type="button" class="close" data-dismiss="alert">&times;</button>
81
+        % for my $error (@$errors) {
82
+          <p><%= $error %></p>
83
+        % }
14 84
       </div>
15 85
     % }
16 86
     
... ...
@@ -25,8 +95,11 @@
25 95
               <a href="#"><%= $uid %></a>
26 96
             </td>
27 97
             <td style="text-align:right">
28
-              <a class="btn btn-mini" href="<%= url_for('/reset-password')->query(user => $uid, mode => 'admin') %>">Reset Password</a>
29
-              <a class="btn btn-mini" href="<%= url_for("/_admin/user/delete?user=$uid") %>">Delete</a>
98
+              <a class="btn btn-mini" href="<%= url_for('/reset-password')->query(user => $uid) %>">Reset Password</a>
99
+              <form style="display:inline-block" action="<%= url_for->query(op => 'delete') %>" method="post">
100
+                %= hidden_field user => $uid;
101
+                <input type="submit" class="btn btn-mini delete-btn" user="<%= $uid %>" value="Delete">
102
+              </form>
30 103
             </td>
31 104
           </tr>
32 105
         % }
... ...
@@ -35,4 +108,5 @@
35 108
   </div>
36 109
   <div class="text-center" style="margin-bottom:20px"><big><a href="<%= url_for('/_admin') %>">Admin page</a></big></div>
37 110
   
38
-  %= include '/include/footer';
111
+  %= include '/include/footer';
112
+  
+2 -2
templates/auto/reset-password.html.ep
... ...
@@ -35,8 +35,8 @@
35 35
     my $params = $api->params;
36 36
     my $rule = [
37 37
       password => [
38
-        ['not_blank' => 'Password is emplty'],
39
-        ['ascii' => 'Password contain invalid character.'],
38
+        ['not_blank' => 'Password is empty.'],
39
+        ['ascii' => 'Password contains invalid character.'],
40 40
         [{'length' => {max => 20}} => 'Password is too long.']
41 41
       ],
42 42
       {password_check => [qw/password password2/]}
+40 -4
xt/admin.t
... ...
@@ -137,10 +137,46 @@ note 'Login as admin user';
137 137
     # Create user
138 138
     $t->post_ok('/_admin/user/create?op=create', form => {id => 'kimoto', password => 'a', password2 => 'a'})
139 139
       ->content_like(qr/Success.*created/);
140
+  }
141
+    
142
+  note 'Admin Users page';
143
+  $t->get_ok('/_admin/users')
144
+    ->content_like(qr/Admin Users/)
145
+    ->content_like(qr/kimoto/);
146
+  
147
+  note 'Reset password page';
148
+  {
149
+    # Page access
150
+    $t->get_ok('/reset-password?user=kimoto')
151
+      ->content_like(qr/Reset Password/)
152
+      ->content_like(qr/kimoto/)
153
+    ;
154
+    
155
+    # Password is empty
156
+    $t->post_ok('/reset-password?user=kimoto&op=reset', form => {password => ''})
157
+      ->content_like(qr/Password is empty/)
158
+    ;
159
+
160
+    # Password contains invalid character
161
+    $t->post_ok('/reset-password?user=kimoto&op=reset', form => {password => "\t"})
162
+      ->content_like(qr/Password contains invalid character/)
163
+    ;
164
+
165
+    # Password is too long
166
+    $t->post_ok('/reset-password?user=kimoto&op=reset', form => {password => 'a' x 21})
167
+      ->content_like(qr/Password is too long/)
168
+    ;
169
+    
170
+    # Two password don't match
171
+    $t->post_ok('/reset-password?user=kimoto&op=reset', form => {password => 'a', password2 => 'b'})
172
+      ->content_like(qr/Two password/)
173
+    ;
174
+
175
+    # Reset password
176
+    $t->post_ok('/reset-password?user=kimoto&op=reset', form => {password => 'a', password2 => 'a'})
177
+      ->content_like(qr/Success.*changed/)
178
+    ;
179
+    
140 180
     
141
-    # Admin Users page
142
-    $t->get_ok('/_admin/users')
143
-      ->content_like(qr/Admin Users/)
144
-      ->content_like(qr/kimoto/);
145 181
   }
146 182
 }