Commit 80631186064bd17aa5d2e8898c3bfb822c171f88

Add sign in functionality

  Right now this app, authenticates with the sweet store. The sweet store
implements a very naive authentication. It does not even send back a session
token! It only sends back a 200 if the auth was successful else a 403. Based on
that the client has to set some auth token. This should improve. The sweet
store can send back a session token which the client can store in its cookie,
which results in smoother auth mechanism. Right now there is no auth as such.
Sweet store sends back 200 if the auth was successful, and then subsequent
requests are made by the client injecting the 'who' parameter, and the server
accepts and agrees with the client. Here the client can tamper with the
username or 'who'. The correct way is, when the auth is successful, sweet store
sends back a auth token, which the client stores in the cookie. And subsequent
sweet store requests are made along with that cookie. Then the sweet store
should identify the username or 'who' from the cookie.
  
11#swt-maker {
22}
3#signinview {
4 margin 0 20px;
5 padding: 10px;
6 text-align: center;
7}
38#img-annotation-wrapper {
49 margin: 30px auto 0 auto;
510 /*border: 1px solid black;*/
  
149149 //TODO: move this to a annotation view or something
150150 anno.removeAll();
151151 _.each(swtr.sweets.models, function(swt) {
152 swt.get('how')['editable'] = false;
152 if(!_.has(swt.get('how'), 'editable')) {
153 swt.get('how')['editable'] = false;
154 swt.get('how').text += '\n - by ' + swt.get('who');
155 }
153156 anno.addAnnotation(swt.get('how'));
154157 });
155158 //console.log(swtr.sweets.toJSON());
164164 }
165165 });
166166 this.cleanUp();
167 return false;
167168 },
168169 cleanUp: function() {
169 console.log('cleaning up');
170 //console.log('cleaning up');
170171 $(this.el).hide();
171172 }
172173 });
176176 el: $('#swt-maker'),
177177 events: {
178178 'click #img-url-submit': 'setImage',
179 'click #sweet': 'sweet'
179 'click #sweet': 'sweet',
180 'click #signin-credentials': 'getSignInCredentials'
180181 },
181182 initialize: function() {
182183 //var allElements = $('body *');
218218 getExistingAnnotations: function() {
219219 this.helpview.step(0);
220220 this.$overlay.show();
221 console.log('getting existing annotations of ', this.imgURL);
221 //console.log('getting existing annotations of ', this.imgURL);
222222 swtr.sweets.getAll({
223223 where: this.imgURL,
224224 success: function(data) {
226226 swtr.sweets.add(data);
227227 _.each(data, function(swt) {
228228 swt.how['editable'] = false;
229 swt.how.text+= '\n - by ' + swt.who;
229 swt.how.text += '\n - by ' + swt.who;
230230 anno.addAnnotation(swt.how);
231231 });
232232 swtr.appView.$overlay.hide();
235235 },
236236 error: function(jqxhr, error, statusText) {
237237 if(jqxhr.status === 404) { //annotations don't exist for this image
238 console.log('annotations don\'t exist for this image. Create one!');
238 //console.log('annotations don\'t exist for this image. Create one!');
239239 }
240240 swtr.appView.$overlay.hide();
241241 swtr.appView.helpview.step(2);
266266 this.getSweets();
267267 this.showSweets();
268268 return false;
269 },
270 getSignInCredentials: function(event) {
271 event.preventDefault();
272 if(swtr.who === 'Guest' && !$('#username').length) {
273 var template = _.template($('#signin-credentials-template').html());
274 $('#signin-msg').html(template());
275 }
276 else if($('#username').length && $('#username').val()) {
277 var username = $('#username').val();
278 var password = $('#password').val();
279 this.signIn(username, password);
280 }
281 return false;
282 },
283 signIn: function(username, password) {
284 this.$overlay.show();
285 $.ajax({
286 url: swtr.swtstoreURL() + swtr.endpoints.auth,
287 type: 'POST',
288 data: {user: username, hash: password},
289 success: function(data) {
290 swtr.appView.$overlay.hide();
291 swtr.who = username;
292 $('#signinview').html('You are signed in.');
293 },
294 error: function(jqxhr, status, error) {
295 swtr.appView.$overlay.hide();
296 if(error === 'FORBIDDEN') {
297 $('#signin-msg').html('Error signing in. Please check your username and password. ');
298 }
299 else {
300 $('#signin-msg').html('Error signin in. Please try again.');
301 }
302 }
303 });
269304 }
270305 });
271306
335335 break;
336336 }
337337 $(this.el).html(text);
338 $(window).scrollTop(0, 0);
338339 }
339340 });
340341
  
1616
1717 <div id="swt-maker" class="container">
1818 <div id="helpview" class="alert alert-info"></div>
19 <div class="row" id="signinview">
20 <form class="form-inline" role="form">
21 <span id="signin-msg">You are not signed in. </span>
22 <button class="btn btn-sm btn-primary" id="signin-credentials">
23 Sign In
24 </button>
25 </form>
26 </div>
1927 <div id="img-input">
2028 <div class="form-group">
2129 <input type="text" placeholder="Enter URL of the image"
5252 <script>
5353 window.swtr = window.swtr || {};
5454 swtr.swtstoreURL = function() { return '{{ conf.swtstoreURL }}'; }
55 swtr.endpoints = {'get': '/sweets/q', 'post': '/sweets'};
55 swtr.endpoints = {'get': '/sweets/q', 'post': '/sweets', 'auth':
56 '/authenticate'};
5657 window.onload = function() {
5758 swtr.init();
5859 };
7171 /<a href="<%= where %>"><%= where.substr(0, 30) + '...' %></a>
7272 <%= how %>
7373 </li>
74 </script>
75 <script type="text/template" id="signin-credentials-template">
76 <div class="form-group">
77 <label class="sr-only" for="username">Username</label>
78 <input type="text" class="form-control" id="username" placeholder="Enter username">
79 </div>
80 <div class="form-group">
81 <label class="sr-only" for="password">Password</label>
82 <input type="password" class="form-control" id="password" placeholder="Password">
83 </div>
7484 </script>
7585 </body>
7686</html>