Showing 7 changed files with 150 additions and 52 deletions
BIN
data/gitprep
Binary file not shown.
+5 -1
lib/Gitprep.pm
... ...
@@ -119,6 +119,7 @@ sub startup {
119 119
   # Model
120 120
   my $models = [
121 121
     {table => 'user', primary_key => 'id'},
122
+    {table => 'ssh_public_key', primary_key => ['user_id', 'key']},
122 123
     {table => 'project', primary_key => ['user_id', 'name']},
123 124
     {table => 'number', primary_key => 'key'},
124 125
     {table => 'collaboration', primary_key => ['user_id', 'project_name', 'collaborator_id']}
... ...
@@ -185,6 +186,9 @@ sub startup {
185 186
       
186 187
       # Custom routes
187 188
       {
189
+        # Show ssh keys
190
+        $r->get('/:user.keys' => template '/user-keys');
191
+        
188 192
         # User
189 193
         my $r = $r->route('/:user');
190 194
         {
... ...
@@ -195,7 +199,7 @@ sub startup {
195 199
           $r->get('/_settings' => template '/user-settings');
196 200
           
197 201
           # SSH keys
198
-          $r->get('/_settings/ssh' => template '/user-settings/ssh');
202
+          $r->any('/_settings/ssh' => template '/user-settings/ssh');
199 203
         }
200 204
 
201 205
         # Smart HTTP
+30 -1
lib/Gitprep/Manager.pm
... ...
@@ -306,7 +306,7 @@ EOS
306 306
     $dbi->execute($sql);
307 307
   };
308 308
 
309
-  # Create usert columns
309
+  # Create user columns
310 310
   my $user_columns = [
311 311
     "admin not null default '0'",
312 312
     "password not null default ''",
... ...
@@ -323,6 +323,35 @@ EOS
323 323
     $self->app->log->error($error);
324 324
     croak $error;
325 325
   }
326
+
327
+  # Create ssh_public_key table
328
+  eval {
329
+    my $sql = <<"EOS";
330
+create table ssh_public_key (
331
+  row_id integer primary key autoincrement,
332
+  user_id not null default '',
333
+  key not null default '',
334
+  unique(user_id, key)
335
+);
336
+EOS
337
+    $dbi->execute($sql);
338
+  };
339
+
340
+  # Create ssh_public_key columns
341
+  my $ssh_public_key_columns = [
342
+    "title not null default ''",
343
+  ];
344
+  for my $column (@$ssh_public_key_columns) {
345
+    eval { $dbi->execute("alter table ssh_public_key add column $column") };
346
+  }
347
+  
348
+  # Check ssh_public_key table
349
+  eval { $dbi->select([qw/row_id user_id key title/], table => 'ssh_public_key') };
350
+  if ($@) {
351
+    my $error = "Can't create ssh_public_key table properly: $@";
352
+    $self->app->log->error($error);
353
+    croak $error;
354
+  }
326 355
   
327 356
   # Create project table
328 357
   eval {
+1 -1
templates/include/errors.html.ep
... ...
@@ -5,7 +5,7 @@
5 5
   <div class="alert alert-error">
6 6
     <button type="button" class="close" data-dismiss="alert">&times;</button>
7 7
     % for my $error (@$errors) {
8
-      <p><%= $error %></p>
8
+      <p style="margin:0;padding:0"><%= $error %></p>
9 9
     % }
10 10
   </div>
11 11
 % }
+11
templates/user-keys.html.ep
... ...
@@ -0,0 +1,11 @@
1
+<%
2
+  my $user = param('user');
3
+  my $keys = app->dbi->model('ssh_public_key')->select(where => {user_id => $user})->all;
4
+  warn dumper $keys;
5
+  my $keys_str = '';
6
+  for my $key (@$keys) {
7
+    $keys_str .= "$key->{key}\n";
8
+  }
9
+  $self->render(text => $keys_str);
10
+  return;
11
+%>
+103 -49
templates/user-settings/ssh.html.ep
... ...
@@ -12,37 +12,103 @@
12 12
     return;
13 13
   }
14 14
   
15
-  my $keys = [
16
-    {
17
-      key => 'key1',
18
-      hash => '7d:d7:ec:86:f6:96:cf:8f:63:07:79:01:f4:cb:f7:78',
19
-      mtime => 'Last used on May 16, 2014'
20
-    },
21
-    {
22
-      key => 'key1',
23
-      hash => '7d:d7:ec:86:f6:96:cf:8f:63:07:79:01:f4:cb:f7:78',
24
-      mtime => 'Last used on May 16, 2014'
25
-    },
26
-  ];
27
-%>
28
-
29
-% layout 'common', title => 'Your Profile';
30
-
31
-  %= javascript begin
32
-    $(document).ready(function () {
33
-      $('#show-add-key-form').on('click', function () {
34
-        var display = $('#add-key-form').css('display');
15
+  # Process form
16
+  my $errors;
17
+  if (lc $self->req->method eq 'post') {
18
+    # Add ssh key
19
+    if ($op eq 'add') {
20
+      
21
+      # Paramters
22
+      my $params = $api->params;
23
+      
24
+      # Rule
25
+      my $rule = [
26
+        title => [
27
+          ['not_blank' => 'title is empty'],
28
+          ['ascii' => 'title contains invalid character'],
29
+        ],
30
+        key => [
31
+          ['not_blank' => 'key is empty'],
32
+          sub {
33
+            my ($original_key, $args, $vc) = @_;
34
+            
35
+            my $type;
36
+            my $original_key_edit;
37
+            if ($original_key =~ /^(ssh-rsa|ssh-dss|ecdsa-sha2-nistp25|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521) +(\S+)/) {
38
+              $type = $1;
39
+              $original_key_edit = $2;
40
+            }
41
+            
42
+            if ($type) {
43
+              if ($vc->constraints->{ascii}->($original_key_edit)) {
44
+                my $key = "$type $original_key_edit";
45
+                
46
+                my $row = app->dbi->model('ssh_public_key')->select(id => [$user, $key])->one;
47
+                
48
+                if ($row) {
49
+                  return {result => 0, message => 'Key already exists'};
50
+                }
51
+                else {
52
+                  return {result => 1, output => $key}
53
+                }
54
+              }
55
+              else {
56
+                return {
57
+                  result => 0,
58
+                  message => "Key contains invalid character."
59
+                }
60
+              }
61
+            }
62
+            else {
63
+              return {
64
+                result => 0,
65
+                message => "Key is invalid. It must begin with 'ssh-rsa', 'ssh-dss', 'ecdsa-sha2-nistp256',"
66
+                  . "'ecdsa-sha2-nistp384', or 'ecdsa-sha2-nistp521'. Check that you're copying the public half of the key"
67
+              };
68
+            }
69
+          }
70
+        ]
71
+      ];
72
+      
73
+      # Validation
74
+      my $vresult = app->vc->validate($params, $rule);
75
+      
76
+      # Register ssh key
77
+      if ($vresult->is_ok) {
78
+        my $safe_params = $vresult->data;
79
+        my $title = $safe_params->{title};
80
+        my $key = $safe_params->{key};
81
+        
82
+        my $p = {
83
+          user_id => $user,
84
+          title => $title,
85
+          key => $key
86
+        };
87
+        eval {
88
+          app->dbi->model('ssh_public_key')->insert($p);
89
+        };
35 90
         
36
-        if (display === 'block') {
37
-          $('#add-key-form').css('display', 'none');
91
+        if (my $e = $@) {
92
+          app->log->error(url_for . ":$e");
93
+          $errors = ['Internal error'];
38 94
         }
39 95
         else {
40
-          $('#add-key-form').css('display', 'block');
96
+          flash('message' => 'Success: ssh key is added');
97
+          $self->redirect_to('current');
98
+          return;
41 99
         }
42
-      });
43
-    });
44
-  % end
100
+      }
101
+      else {
102
+        $errors = $vresult->messages;
103
+      }
104
+    }
105
+  }
45 106
   
107
+  my $keys = app->dbi->model('ssh_public_key')->select(where => {user_id => $user})->all;
108
+%>
109
+
110
+% layout 'common', title => 'SSH keys';
111
+
46 112
   %= include '/include/header';
47 113
   
48 114
   <div class="container">
... ...
@@ -64,18 +130,12 @@
64 130
           </ul>
65 131
         </div>
66 132
         <div class="span10">
67
-          <div class="border-gray bk-gray-light radius-top" style="padding:5px;font-weight:bold;font-size:17px">
68
-            <div class="row">
69
-              <div class="span7" style="width:600px">
70
-                <div style="font-size:15px;padding:5px">
71
-                  SSH Keys
72
-                </div>
73
-              </div>
74
-              <div class="span2">
75
-                <div style="text-align:right">
76
-                  <a id="show-add-key-form" class="btn" href="javascript:void(0)">Add SSH Key</a>
77
-                </div>
78
-              </div>
133
+          <%= include '/include/errors', errors => $errors %>
134
+          <%= include '/include/message', message => flash('message') %>
135
+          
136
+          <div class="border-gray bk-gray-light radius-top" style="padding:5px;">
137
+            <div style="padding:5px">
138
+              <span style="font-size:15px;font-weight:bold;">SSH Keys</span> (<a href="<%= url_for("/$user.keys") %>">see</a>)
79 139
             </div>
80 140
           </div>
81 141
           <div style="margin-bottom:30px">
... ...
@@ -89,19 +149,13 @@
89 149
                     <div class="span7" style="width:600px">
90 150
                       <div style="font-size:15px;padding:10px">
91 151
                         <div>
92
-                          <b><%= $key->{key} %></b>
93
-                        </div>
94
-                        <div class="muted">
95
-                          <%= $key->{hash} %>
96
-                        </div>
97
-                        <div>
98
-                          <%= $key->{mtime} %>
152
+                          <b><%= $key->{title} %></b>
99 153
                         </div>
100 154
                       </div>
101 155
                     </div>
102 156
                     <div class="span2">
103
-                      <div style="padding-top:20px;text-align:right">
104
-                        <a class="btn btn-danger" href="<%= url_for("/reset-password")->query(user => $user) %>">Delete</a>
157
+                      <div style="padding:5px;text-align:right">
158
+                        <a class="btn btn-danger" href="javascript:void(0)">Delete</a>
105 159
                       </div>
106 160
                     </div>
107 161
                   </div>
... ...
@@ -114,14 +168,14 @@
114 168
             % }
115 169
           </div>
116 170
           
117
-          <div id="add-key-form" style="display:none">
171
+          <div>
118 172
             <div class="border-gray bk-gray-light radius-top" style="padding:5px;font-weight:bold;font-size:17px">
119 173
               <div style="font-size:15px;padding:5px">
120 174
                 Add an SSH Key
121 175
               </div>
122 176
             </div>
123 177
             <div class="border-gray" style="margin-bottom:30px;border-top:none;padding:10px">
124
-              <form>
178
+              <form action="<%= url_for->query(op => 'add') %>" method="post" %>
125 179
                 <div style="margin-bottom:5px">
126 180
                   Title
127 181
                 </div>
BIN
xt/basic.db
Binary file not shown.