Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / ui / web / ui_public_keys_view.js @ ac07ff0d

History | View | Annotate | Download (9.9 kB)

1
// Copyright 2013 GRNET S.A. All rights reserved.
2
// 
3
// Redistribution and use in source and binary forms, with or
4
// without modification, are permitted provided that the following
5
// conditions are met:
6
// 
7
//   1. Redistributions of source code must retain the above
8
//      copyright notice, this list of conditions and the following
9
//      disclaimer.
10
// 
11
//   2. Redistributions in binary form must reproduce the above
12
//      copyright notice, this list of conditions and the following
13
//      disclaimer in the documentation and/or other materials
14
//      provided with the distribution.
15
// 
16
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
// POSSIBILITY OF SUCH DAMAGE.
28
// 
29
// The views and conclusions contained in the software and
30
// documentation are those of the authors and should not be
31
// interpreted as representing official policies, either expressed
32
// or implied, of GRNET S.A.
33
// 
34

    
35
;(function(root){
36
    
37
    // root
38
    var root = root;
39
    
40
    // setup namepsaces
41
    var snf = root.synnefo = root.synnefo || {};
42
    var models = snf.models = snf.models || {}
43
    var storage = snf.storage = snf.storage || {};
44
    var ui = snf.ui = snf.ui || {};
45
    var util = snf.util || {};
46
    var views = snf.views = snf.views || {}
47

    
48
    // shortcuts
49
    var bb = root.Backbone;
50
    
51
    // logging
52
    var logger = new snf.logging.logger("SNF-VIEWS");
53
    var debug = _.bind(logger.debug, logger);
54
      
55
    views.PublicKeyCreateView = views.Overlay.extend({
56
        view_id: "public_key_create_view",
57
        
58
        content_selector: "#public-key-create-content",
59
        css_class: 'overlay-public-key-create overlay-info',
60
        overlay_id: "public_key_create_view",
61

    
62
        subtitle: "",
63
        title: "Create new SSH key",
64
        
65
        initialize: function() {
66
            views.PublicKeyCreateView.__super__.initialize.apply(this, arguments);
67
            this.form = this.$("form.model-form");
68
            this.submit = this.$(".form-actions .submit");
69
            this.cancel = this.$(".form-actions .cancel");
70
            this.close = this.$(".form-actions .close");
71
            this.error = this.$(".error-msg");
72
            this.model_actions = this.$(".model-actions");
73
            this.form_actions_cont = this.$(".form-actions");
74
            this.form_actions = this.$(".form-actions .form-action");
75

    
76
            this.input_name = this.form.find(".input-name");
77
            this.input_key = this.form.find("textarea");
78
            this.input_file = this.form.find(".content-input-file");
79
            
80
            this.generate_action = this.$(".model-action.generate");
81
            this.generate_msg = this.$(".generate-msg");
82
            this.generate_download = this.generate_msg.find(".download");
83
            this.generate_success = this.generate_msg.find(".success");
84

    
85
            this.generating = false;
86
            this.in_progress = false;
87
            this.init_handlers();
88
        },
89

    
90
        _init_reader: function() {
91
          var opts = {
92
            dragClass: "drag",
93
            accept: false,
94
            readAsDefault: 'BinaryString',
95
            on: {
96
              loadend: _.bind(function(e, file) {
97
                this.input_key.val(e.target.result);
98
                this.validate_form();
99
              }, this),
100
              error: function() {}
101
            }
102
          }
103
          FileReaderJS.setupInput(this.input_file.get(0), opts);
104
        },
105
        
106
        validate_form: function() {
107
          this.form.find(".error").removeClass("error");
108
          this.form.find(".errors").empty();
109

    
110
          var name = _.trim(this.input_name.val());
111
          var key = _.trim(this.input_key.val());
112
          var error = false;
113

    
114
          if (!name) {
115
            this.input_name.parent().addClass("error");
116
            error = true;
117
          }
118

    
119
          if (!key) {
120
            this.input_key.parent().addClass("error");
121
            error = true;
122
          } else {
123
            try {
124
              key = snf.util.validatePublicKey(key);
125
            } catch (err) {
126
              this.input_key.parent().addClass("error");
127
              this.input_key.parent().find(".errors").append("<span class='error'>"+err+"</span>");
128
              error = true;
129
            }
130
          }
131

    
132
          if (error) { return false }
133
          return { key: key, name: name }
134
        },
135

    
136
        _reset_form: function() {
137
          this.input_name.val("");
138
          this.input_key.val("");
139
          this.input_file.val("");
140
          this.form.find(".error").removeClass("error");
141
          this.form.find(".errors").empty();
142
          this.form.show();
143
          this.generate_msg.hide();
144
          this.form_actions.show();
145
          this.input_file.show();
146
          this.close.hide();
147
          this.error.hide();
148
          this.model_actions.show();
149
        },
150

    
151
        beforeOpen: function() {
152
          this.private_key = undefined;
153
          this._reset_form();
154
          this._init_reader();
155
          this.unset_in_progress();
156
        },
157
        
158
        init_handlers: function() {
159
          this.cancel.click(_.bind(function() { this.hide(); }, this));
160
          this.close.click(_.bind(function() { this.hide(); }, this));
161
          this.generate_action.click(_.bind(this.generate, this));
162
          this.generate_download.click(_.bind(this.download_key, this));
163
          this.form.submit(_.bind(function(e){
164
            e.preventDefault();
165
            this.submit_key(_.bind(function() {
166
              this.hide();
167
            }, this))
168
          }, this));
169
          this.submit.click(_.bind(function() {
170
            this.form.submit();
171
          }, this));
172
        },
173
        
174
        set_in_progress: function() {
175
          this.in_progress = true;
176
          this.submit.addClass("in-progress");
177
        },
178

    
179
        unset_in_progress: function() {
180
          this.in_progress = false;
181
          this.submit.removeClass("in-progress");
182
        },
183

    
184
        submit_key: function(cb) {
185
          var data = this.validate_form();
186
          if (!data) { return }
187
          this.set_in_progress();
188
          var params = {
189
            complete: _.bind(function() {
190
              synnefo.storage.keys.fetch();
191
              this.unset_in_progress();
192
              cb && cb();
193
            }, this)
194
          };
195

    
196
          synnefo.storage.keys.create({
197
            content: data.key, 
198
            name: data.name,
199
          }, params);
200
        },
201

    
202
        download_key: function() {
203
          try {
204
            var blob = new Blob([this.private_key], {
205
              type: "application/x-perm-key;charset=utf-8"
206
            });
207
            saveAs(blob, "id_rsa");
208
          } catch (err) {
209
            alert(this.private_key);
210
          }
211
        },
212

    
213
        generate: function() {
214
          this.error.hide();
215
          this.generate_msg.hide();
216

    
217
          if (this.generating) { return }
218
          
219
          this.generating = true;
220
          this.generate_action.addClass("in-progress");
221
          
222
          var success = _.bind(function(key) {
223
            this.generating = false;
224
            this.generate_action.removeClass("in-progress");
225
            this.input_name.val("Generated ssh key");
226
            this.input_key.val(key.public);
227
            this.generate_msg.show();
228
            this.private_key = key.private;
229
            this.form.hide();
230
            this.form_actions.hide();
231
            this.close.show();
232
            this.model_actions.hide();
233
            this.submit_key();
234
          }, this);
235
          var error = _.bind(function() {
236
            this.generating = false;
237
            this.generate_action.removeClass("in-progress");
238
            this.generate_progress.hide();
239
            this.private_key = undefined;
240
            this.show_error();
241
          }, this);
242
          var key = storage.keys.generate_new(success, error);
243
        },
244

    
245
        show_error: function(msg) {
246
          msg = msg === undefined ? "Something went wrong. Please try again later." : msg;
247
          if (msg) { this.error.find("p").html(msg) }
248
          this.error.show();
249
        }
250
    });
251

    
252
    views.PublicKeyView = views.ext.ModelView.extend({
253
      tpl: '#public-key-view-tpl',
254
      post_init_element: function() {
255
        this.content = this.$(".content-cont");
256
        this.content.hide();
257
        this.content_toggler = this.$(".cont-toggler");
258
        this.content_toggler.click(this.toggle_content);
259
        this.content_visible = false;
260
      },
261

    
262
      toggle_content: function() {
263
        if (!this.content_visible) {
264
          this.content.slideDown();
265
          this.content_visible = true;
266
          this.content_toggler.addClass("open");
267
        } else {
268
          this.content.slideUp();
269
          this.content_visible = false;
270
          this.content_toggler.removeClass("open");
271
        }
272
      },
273

    
274
      remove_key: function() {
275
        this.model.actions.reset_pending();
276
        this.model.remove(function() {
277
            synnefo.storage.keys.fetch();
278
        });
279
      }
280
    });
281
    
282
    views.PublicKeysCollectionView = views.ext.CollectionView.extend({
283
      collection: storage.keys,
284
      collection_name: 'keys',
285
      model_view_cls: views.PublicKeyView,
286
      create_view_cls: views.PublicKeyCreateView
287
    });
288

    
289
    views.PublicKeysPaneView = views.ext.PaneView.extend({
290
      id: "pane",
291
      el: '#public-keys-pane',
292
      collection_view_cls: views.PublicKeysCollectionView,
293
      collection_view_selector: '#public-keys-list-view'
294
    });
295

    
296
})(this);
297