Commit 1a89154bf63ff680bb5022ef0ffc3ba15ad03b1e

Persona and OAuth experiments with the new swtstore APIs

  - Add swtstore login using OAuth 2.0. This uses the new swtstore APIs.
  - The code has still to be cleaned up. This commit refers to a client
    implementation for the swtstore APIs.
setup.py
(1 / 0)
  
77
88requires = [
99 'Flask',
10 'requests'
1011]
1112
1213setup(name='Swtr',
swtr.explain
(58 / 0)
  
1== High-level components and data flow of the swtr application ==
2
3> The document is written in an informal way.
4
5Table of contents
61. Introduction
72. Design
83. Configuration
94. Deployment
10
111. Introduction
12
13swtr is the cannonical swt maker + swt swagger application.
14That means, the swtr application can be used to -
15a) interact with resources on an existing web page(like
16text, images, video etc), annotate them, and make swts out of the annotations
17and post the swts to a swt store.
18b) fetch existing swts about an existing web page and display/render them based
19on a combination of - the type of swt (the context), and configuration
20parameters set by the user.
21
222. Design
23
24swtr is designed entirely to be a client-side javascript app.
25the components of the swtr app can be divided like-
26i) text annotation module - an interface to the user to select and annotate
27text.
28 1. creates an interface for the user to select any text on the webpage.
29 2. when user has selected text - gives two options - edit/renarrate or comment/annotate.
30 3.1 if user selects comment, the module provides a text box to enter user's
31 comment, keeping the selected text by the user in context.
32 3.2 if the user selects edit, the module provides an editor keeping the
33 selected text by the user in context.
34 4. In both the above case, the editor window has options to save the changes
35 or cancel them.
36 5.1 If the user cancels, all the changes made by the user is discarded and
37 previous version of the page is kept.
38 5.2 If the user saves her changes, the new edit or comment is updated in the
39 DOM of the browser to visually reflect the changes, and also the changes
40 are cached in a local data store.
41
42ii) image annotation module - an interface to the user to select arbitrary
43parts of an image in rectange shape and add textual comments to them. Later
44this can be extended to add support for audio, video comments.
45 1. provides an interface to click on any image on the webpage and bring it to
46 center focus to make it annotatable. We use the annotorious project to do
47 the image annotation.
48 2. Once an annotation to the image has been made, the module can provide the
49 user with options to cancel or save the changes.
50 3.1 If the user cancels, all the changes made by the user is discarded (i.e
51 annotations removed).
52 3.2 If the user saves her changes, this module retrieves the annotations via
53 the annotorious' API and stores them in the local data store.
54
55iii) map annotation module
56iv) controller
57v) swt maker
58vi) swt swagger
  
11#!/usr/bin/python
22
33import flask
4from flask import session
45import conf
6import requests
7import json
58
69app = flask.Flask(__name__)
710
11app.config['secret_key'] = "asdkasdiq2jedmaid0q2238uwadscksnc"
12app.secret_key = "asdkasdiq2jedmaid0q2238uwadscksnc"
13
14appID = 'YrYc9oMO7fT0avRUAtbRO1cLvoOUUI08BAuqOAJc'
15appSecret = 'r9BIYjYOPotMQUOoI98DmH7Eu1M4zg6cMeLay7LOlSsrF1KhKZ'
16
817@app.route('/', methods=['GET'])
918def index():
10 return flask.render_template('index.html',
11 url=flask.request.args.get('where'),
12 conf=conf)
19 auth_tok = None
20 if flask.request.args.get('code'):
21 payload = {
22 'scopes': 'email sweet',
23 'client_secret': appSecret,
24 'code': flask.request.args.get('code'),
25 'redirect_uri': 'http://localhost:5000/',
26 'grant_type': 'authorization_code',
27 'client_id': appID
28 }
29 resp = requests.post('http://localhost:5001/oauth/token', data=payload)
30 auth_tok = json.loads(resp.text)
31 print auth_tok
32 if auth_tok.has_key('error'):
33 print auth_tok['error']
34 return flask.make_response(auth_tok['error'], 200)
1335
36 session['auth_tok'] = auth_tok
37
38 if 'auth_tok' in session:
39 auth_tok = session['auth_tok']
40 else:
41 auth_tok = {'access_token': '', 'refresh_token': ''}
42
43 print auth_tok
44 return flask.render_template('index.html',
45 access_token=auth_tok['access_token'],
46 refresh_token=auth_tok['refresh_token'],
47 url=flask.request.args.get('where'),
48 conf=conf)
1449
1550if __name__ == '__main__':
1651 app.run(debug=conf.debug, host=conf.HOST, port=conf.PORT)
  
1/**
2 * Uncompressed source can be found at https://login.persona.org/include.orig.js
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8(function(){var a;navigator.mozId?navigator.id=navigator.mozId:function(){var a,b=function(){function f(a){return Array.isArray?Array.isArray(a):a.constructor.toString().indexOf("Array")!=-1}function e(a,b,d){var e=c[b][d];for(var f=0;f<e.length;f++)e[f].win===a&&e.splice(f,1);c[b][d].length===0&&delete c[b][d]}function d(a,b,d,e){function f(b){for(var c=0;c<b.length;c++)if(b[c].win===a)return!0;return!1}var g=!1;if(b==="*")for(var h in c){if(!c.hasOwnProperty(h))continue;if(h==="*")continue;if(typeof c[h][d]=="object"){g=f(c[h][d]);if(g)break}}else c["*"]&&c["*"][d]&&(g=f(c["*"][d])),!g&&c[b]&&c[b][d]&&(g=f(c[b][d]));if(g)throw"A channel is already bound to the same window which overlaps with origin '"+b+"' and has scope '"+d+"'";typeof c[b]!="object"&&(c[b]={}),typeof c[b][d]!="object"&&(c[b][d]=[]),c[b][d].push({win:a,handler:e})}"use strict";var b=Math.floor(Math.random()*1000001),c={},g={},h=function(a){try{var b=JSON.parse(a.data);if(typeof b!="object"||b===null)throw"malformed"}catch(a){return}var d=a.source,e=a.origin,f,h,i;if(typeof b.method=="string"){var j=b.method.split("::");j.length==2?(f=j[0],i=j[1]):i=b.method}typeof b.id!="undefined"&&(h=b.id);if(typeof i=="string"){var k=!1;if(c[e]&&c[e][f])for(var l=0;l<c[e][f].length;l++)if(c[e][f][l].win===d){c[e][f][l].handler(e,i,b),k=!0;break}if(!k&&c["*"]&&c["*"][f])for(var l=0;l<c["*"][f].length;l++)if(c["*"][f][l].win===d){c["*"][f][l].handler(e,i,b);break}}else typeof h!="undefined"&&g[h]&&g[h](e,i,b)};window.addEventListener?window.addEventListener("message",h,!1):window.attachEvent&&window.attachEvent("onmessage",h);return{build:function(c){var h=function(a){if(c.debugOutput&&window.console&&window.console.log){try{typeof a!="string"&&(a=JSON.stringify(a))}catch(b){}console.log("["+k+"] "+a)}};if(!window.postMessage)throw"jschannel cannot run this browser, no postMessage";if(!window.JSON||!window.JSON.stringify||!window.JSON.parse)throw"jschannel cannot run this browser, no JSON parsing/serialization";if(typeof c!="object")throw"Channel build invoked without a proper object argument";if(!c.window||!c.window.postMessage)throw"Channel.build() called without a valid window argument";if(window===c.window)throw"target window is same as present window -- not allowed";var i=!1;if(typeof c.origin=="string"){var j;c.origin==="*"?i=!0:null!==(j=c.origin.match(/^https?:\/\/(?:[-a-zA-Z0-9_\.])+(?::\d+)?/))&&(c.origin=j[0].toLowerCase(),i=!0)}if(!i)throw"Channel.build() called with an invalid origin";if(typeof c.scope!="undefined"){if(typeof c.scope!="string")throw"scope, when specified, must be a string";if(c.scope.split("::").length>1)throw"scope may not contain double colons: '::'"}var k=function(){var a="",b="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";for(var c=0;c<5;c++)a+=b.charAt(Math.floor(Math.random()*b.length));return a}(),l={},m={},n={},o=!1,p=[],q=function(a,b,c){var d=!1,e=!1;return{origin:b,invoke:function(b,d){if(!n[a])throw"attempting to invoke a callback of a nonexistent transaction: "+a;var e=!1;for(var f=0;f<c.length;f++)if(b===c[f]){e=!0;break}if(!e)throw"request supports no such callback '"+b+"'";u({id:a,callback:b,params:d})},error:function(b,c){e=!0;if(!n[a])throw"error called for nonexistent message: "+a;delete n[a],u({id:a,error:b,message:c})},complete:function(b){e=!0;if(!n[a])throw"complete called for nonexistent message: "+a;delete n[a],u({id:a,result:b})},delayReturn:function(a){typeof a=="boolean"&&(d=a===!0);return d},completed:function(){return e}}},r=function(a,b,c){return window.setTimeout(function(){if(m[a]){var d="timeout ("+b+"ms) exceeded on method '"+c+"'";(1,m[a].error)("timeout_error",d),delete m[a],delete g[a]}},b)},s=function(b,d,e){if(typeof c.gotMessageObserver=="function")try{c.gotMessageObserver(b,e)}catch(i){h("gotMessageObserver() raised an exception: "+i.toString())}if(e.id&&d){if(l[d]){var j=q(e.id,b,e.callbacks?e.callbacks:[]);n[e.id]={};try{if(e.callbacks&&f(e.callbacks)&&e.callbacks.length>0)for(var k=0;k<e.callbacks.length;k++){var o=e.callbacks[k],p=e.params,r=o.split("/");for(var s=0;s<r.length-1;s++){var t=r[s];typeof p[t]!="object"&&(p[t]={}),p=p[t]}p[r[r.length-1]]=function(){var a=o;return function(b){return j.invoke(a,b)}}()}var u=l[d](j,e.params);!j.delayReturn()&&!j.completed()&&j.complete(u)}catch(i){var v="runtime_error",w=null;typeof i=="string"?w=i:typeof i=="object"&&(i&&f(i)&&i.length==2?(v=i[0],w=i[1]):typeof i.error=="string"&&(v=i.error,i.message?typeof i.message=="string"?w=i.message:i=i.message:w=""));if(w===null)try{w=JSON.stringify(i),typeof w=="undefined"&&(w=i.toString())}catch(x){w=i.toString()}j.error(v,w)}}}else e.id&&e.callback?!m[e.id]||!m[e.id].callbacks||!m[e.id].callbacks[e.callback]?h("ignoring invalid callback, id:"+e.id+" ("+e.callback+")"):m[e.id].callbacks[e.callback](e.params):e.id?m[e.id]?(e.error?(1,m[e.id].error)(e.error,e.message):e.result!==a?(1,m[e.id].success)(e.result):(1,m[e.id].success)(),delete m[e.id],delete g[e.id]):h("ignoring invalid response: "+e.id):d&&l[d]&&l[d]({origin:b},e.params)};d(c.window,c.origin,typeof c.scope=="string"?c.scope:"",s);var t=function(a){typeof c.scope=="string"&&c.scope.length&&(a=[c.scope,a].join("::"));return a},u=function(a,b){if(!a)throw"postMessage called with null message";var d=o?"post ":"queue ";h(d+" message: "+JSON.stringify(a));if(!b&&!o)p.push(a);else{if(typeof c.postMessageObserver=="function")try{c.postMessageObserver(c.origin,a)}catch(e){h("postMessageObserver() raised an exception: "+e.toString())}c.window.postMessage(JSON.stringify(a),c.origin)}},v=function(a,b){h("ready msg received");if(o)throw"received ready message while in ready state. help!";b==="ping"?k+="-R":k+="-L",w.unbind("__ready"),o=!0,h("ready msg accepted."),b==="ping"&&w.notify({method:"__ready",params:"pong"});while(p.length)u(p.pop());typeof c.onReady=="function"&&c.onReady(w)},w={unbind:function(a){if(l[a]){if(delete l[a])return!0;throw"can't delete method: "+a}return!1},bind:function(a,b){if(!a||typeof a!="string")throw"'method' argument to bind must be string";if(!b||typeof b!="function")throw"callback missing from bind params";if(l[a])throw"method '"+a+"' is already bound!";l[a]=b;return this},call:function(a){if(!a)throw"missing arguments to call function";if(!a.method||typeof a.method!="string")throw"'method' argument to call must be string";if(!a.success||typeof a.success!="function")throw"'success' callback missing from call";var c={},d=[],e=function(a,b){if(typeof b=="object")for(var f in b){if(!b.hasOwnProperty(f))continue;var g=a+(a.length?"/":"")+f;typeof b[f]=="function"?(c[g]=b[f],d.push(g),delete b[f]):typeof b[f]=="object"&&e(g,b[f])}};e("",a.params);var f={id:b,method:t(a.method),params:a.params};d.length&&(f.callbacks=d),a.timeout&&r(b,a.timeout,t(a.method)),m[b]={callbacks:c,error:a.error,success:a.success},g[b]=s,b++,u(f)},notify:function(a){if(!a)throw"missing arguments to notify function";if(!a.method||typeof a.method!="string")throw"'method' argument to notify must be string";u({method:t(a.method),params:a.params})},destroy:function(){e(c.window,c.origin,typeof c.scope=="string"?c.scope:""),window.removeEventListener?window.removeEventListener("message",s,!1):window.detachEvent&&window.detachEvent("onmessage",s),o=!1,l={},n={},m={},c.origin=null,p=[],h("channel destroyed"),k=""}};w.bind("__ready",v),setTimeout(function(){},0);return w}}}();WinChan=function(){function j(){var a=window.location,c=window.opener.frames,d=a.protocol+"//"+a.host;for(var e=c.length-1;e>=0;e--)try{if(c[e].location.href.indexOf(d)===0&&c[e].name===b)return c[e]}catch(f){}return}function i(a){/^https?:\/\//.test(a)||(a=window.location.href);var b=/^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(a);return b?b[1]:a}function h(){return window.JSON&&window.JSON.stringify&&window.JSON.parse&&window.postMessage}function g(){try{var a=navigator.userAgent;return a.indexOf("Fennec/")!=-1||a.indexOf("Firefox/")!=-1&&a.indexOf("Android")!=-1}catch(b){}return!1}function f(){var a=-1,b=navigator.userAgent;if(navigator.appName==="Microsoft Internet Explorer"){var c=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");c.exec(b)!=null&&(a=parseFloat(RegExp.$1))}else if(b.indexOf("Trident")>-1){var c=new RegExp("rv:([0-9]{2,2}[.0-9]{0,})");c.exec(b)!==null&&(a=parseFloat(RegExp.$1))}return a>=8}function e(a,b,c){a.detachEvent?a.detachEvent("on"+b,c):a.removeEventListener&&a.removeEventListener(b,c,!1)}function d(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener&&a.addEventListener(b,c,!1)}var b="__winchan_relay_frame",c="die",k=f();return h()?{open:function(f,h){function s(a){if(a.origin===m)try{var b=JSON.parse(a.data);b.a==="ready"?n.postMessage(q,m):b.a==="error"?(r(),h&&(h(b.d),h=null)):b.a==="response"&&(r(),h&&(h(null,b.d),h=null))}catch(c){}}function r(){l&&document.body.removeChild(l),l=a,p&&(p=clearInterval(p)),e(window,"message",s),e(window,"unload",r);if(o)try{o.close()}catch(b){n.postMessage(c,m)}o=n=a}if(!h)throw"missing required callback argument";var j;f.url||(j="missing required 'url' parameter"),f.relay_url||(j="missing required 'relay_url' parameter"),j&&setTimeout(function(){h(j)},0),f.window_name||(f.window_name=null);if(!f.window_features||g())f.window_features=a;var l,m=i(f.url);if(m!==i(f.relay_url))return setTimeout(function(){h("invalid arguments: origin of url and relay_url must match")},0);var n;k&&(l=document.createElement("iframe"),l.setAttribute("src",f.relay_url),l.style.display="none",l.setAttribute("name",b),document.body.appendChild(l),n=l.contentWindow);var o=window.open(f.url,f.window_name,f.window_features);n||(n=o);var p=setInterval(function(){o&&o.closed&&(r(),h&&(h("unknown closed window"),h=null))},500),q=JSON.stringify({a:"request",d:f.params});d(window,"unload",r),d(window,"message",s);return{close:r,focus:function(){if(o)try{o.focus()}catch(a){}}}},onOpen:function(b){function l(a){if(a.data===c)try{window.close()}catch(b){}}function i(c){var d;try{d=JSON.parse(c.data)}catch(g){}!!d&&d.a==="request"&&(e(window,"message",i),f=c.origin,b&&setTimeout(function(){b(f,d.d,function(c){b=a,h({a:"response",d:c})})},0))}function h(a){a=JSON.stringify(a),k?g.doPost(a,f):g.postMessage(a,f)}var f="*",g=k?j():window.opener;if(!g)throw"can't find relay frame";d(k?g:window,"message",i),d(k?g:window,"message",l);try{h({a:"ready"})}catch(m){d(g,"load",function(a){h({a:"ready"})})}var n=function(){try{e(k?g:window,"message",l)}catch(c){}b&&h({a:"error",d:"client closed window"}),b=a;try{window.close()}catch(d){}};d(window,"unload",n);return{detach:function(){e(window,"unload",n)}}}}:{open:function(a,b,c,d){setTimeout(function(){d("unsupported browser")},0)},onOpen:function(a){setTimeout(function(){a("unsupported browser")},0)}}}();var c=function(){function l(){return c}function k(){c=g()||h()||i()||j();return!c}function j(){if(!(window.JSON&&window.JSON.stringify&&window.JSON.parse))return"JSON_NOT_SUPPORTED"}function i(){if(!a.postMessage)return"POSTMESSAGE_NOT_SUPPORTED"}function h(){try{var b="localStorage"in a&&a.localStorage!==null;if(b)a.localStorage.setItem("test","true"),a.localStorage.removeItem("test");else return"LOCALSTORAGE_NOT_SUPPORTED"}catch(c){return"LOCALSTORAGE_DISABLED"}}function g(){return f()}function f(){var a=e(),b=a>-1&&a<8;if(b)return"BAD_IE_VERSION"}function e(){var a=-1;if(b.appName=="Microsoft Internet Explorer"){var c=b.userAgent,d=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");d.exec(c)!=null&&(a=parseFloat(RegExp.$1))}return a}function d(c,d){b=c,a=d}var a=window,b=navigator,c;return{setTestEnv:d,isSupported:k,getNoSupportReason:l}}();navigator.id||(navigator.id={});if(!navigator.id.request||navigator.id._shimmed){var d="https://login.persona.org",e=navigator.userAgent,f=e.indexOf("Fennec/")!=-1||e.indexOf("Firefox/")!=-1&&e.indexOf("Android")!=-1,g=f?a:"menubar=0,location=1,resizable=1,scrollbars=1,status=0,width=700,height=375",h=e.match(/CriOS/)||e.match(/Windows Phone/),i="WATCH_NEEDED",j="__persona_dialog",k,l={login:null,logout:null,match:null,ready:null},m,n=a;function o(b){b!==!0;if(n===a)n=b;else if(n!=b)throw new Error("you cannot combine the navigator.id.watch() API with navigator.id.getVerifiedEmail() or navigator.id.get()this site should instead use navigator.id.request() and navigator.id.watch()")}var p,q=!1,r=c.isSupported();function s(a){document.addEventListener?document.addEventListener("DOMContentLoaded",function b(){document.removeEventListener("DOMContentLoaded",b),a()},!1):document.attachEvent&&document.readyState&&document.attachEvent("onreadystatechange",function c(){var b=document.readyState;if(b==="loaded"||b==="complete"||b==="interactive")document.detachEvent("onreadystatechange",c),a()})}function t(){if(!!r){var c=window.document;if(!c.body){q||(s(t),q=!0);return}try{if(!p){var e=c.createElement("iframe");e.style.display="none",c.body.appendChild(e),e.src=d+"/communication_iframe",p=b.build({window:e.contentWindow,origin:d,scope:"mozid_ni",onReady:function(){p.call({method:"loaded",success:function(){l.ready&&l.ready()},error:function(){}})}}),p.bind("logout",function(a,b){l.logout&&l.logout()}),p.bind("login",function(a,b){l.login&&l.login(b)}),p.bind("match",function(a,b){l.match&&l.match()}),u(m)&&p.notify({method:"loggedInUser",params:m})}}catch(f){p=a}}}function u(a){return typeof a!="undefined"}function v(a){try{console.warn(a)}catch(b){}}function w(a,b){if(u(a[b])){v(b+" has been deprecated");return!0}}function x(a,b,c){if(u(a[b])&&u(a[c]))throw new Error("you cannot supply *both* "+b+" and "+c);w(a,b)&&(a[c]=a[b],delete a[b])}function y(a){if(typeof a=="object"){if(a.onlogin&&typeof a.onlogin!="function"||a.onlogout&&typeof a.onlogout!="function"||a.onmatch&&typeof a.onmatch!="function"||a.onready&&typeof a.onready!="function")throw new Error("non-function where function expected in parameters to navigator.id.watch()");if(!a.onlogin)throw new Error("'onlogin' is a required argument to navigator.id.watch()");if(!a.onlogout)throw new Error("'onlogout' is a required argument to navigator.id.watch()");l.login=a.onlogin||null,l.logout=a.onlogout||null,l.match=a.onmatch||null,l.ready=a.onready||null,x(a,"loggedInEmail","loggedInUser"),m=a.loggedInUser,t()}}var z;function A(){var a=z;a==="request"&&(l.ready?a="watch_with_onready":a="watch_without_onready");return a}function B(b){function r(){if(p)return p.call({method:"redirect_flow",params:JSON.stringify(b),success:function(){window.location=d+"/sign_in"}})}function n(){var a=c.getNoSupportReason();if(!a&&!e)return i}function m(){return c.isSupported()&&e}w(b,"requiredEmail"),x(b,"tosURL","termsOfService"),x(b,"privacyURL","privacyPolicy"),b.termsOfService&&!b.privacyPolicy&&v("termsOfService ignored unless privacyPolicy also defined"),b.privacyPolicy&&!b.termsOfService&&v("privacyPolicy ignored unless termsOfService also defined"),b.rp_api=A();var e=!h||z==="request";z=null,b.start_time=(new Date).getTime();if(k)try{k.focus()}catch(f){}else{if(!m()){var o=n(),q="unsupported_dialog";o==="LOCALSTORAGE_DISABLED"?q="cookies_disabled":o===i&&(q="unsupported_dialog_without_watch"),k=window.open(d+"/"+q,j,g);return}p&&p.notify({method:"dialog_running"});if(h)return r();k=WinChan.open({url:d+"/sign_in",relay_url:d+"/relay",window_features:g,window_name:j,params:{method:"get",params:b}},function(c,d){if(p){!c&&d&&d.email&&p.notify({method:"loggedInUser",params:d.email});var e=!(c||d&&d.assertion);p.notify({method:"dialog_complete",params:e})}k=a;if(!c&&d&&d.assertion)try{l.login&&l.login(d.assertion)}catch(f){console.log(f);throw f}if(c==="client closed window"||!d)b&&b.oncancel&&b.oncancel(),delete b.oncancel})}}navigator.id={request:function(a){if(this!=navigator.id)throw new Error("all navigator.id calls must be made on the navigator.id object");if(!l.login)throw new Error("navigator.id.watch must be called before navigator.id.request");a=a||{},o(!1),z="request",a.returnTo||(a.returnTo=document.location.pathname);return B(a)},watch:function(a){if(this!=navigator.id)throw new Error("all navigator.id calls must be made on the navigator.id object");o(!1),y(a)},logout:function(a){if(this!=navigator.id)throw new Error("all navigator.id calls must be made on the navigator.id object");t(),p&&p.notify({method:"logout"}),typeof a=="function"&&(v("navigator.id.logout callback argument has been deprecated."),setTimeout(a,0))},get:function(b,c){var d={};c=c||{},d.privacyPolicy=c.privacyPolicy||a,d.termsOfService=c.termsOfService||a,d.privacyURL=c.privacyURL||a,d.tosURL=c.tosURL||a,d.siteName=c.siteName||a,d.siteLogo=c.siteLogo||a,d.backgroundColor=c.backgroundColor||a,d.experimental_emailHint=c.experimental_emailHint||a,z=z||"get";w(c,"silent")?b&&setTimeout(function(){b(null)},0):(o(!0),y({onlogin:function(a){b&&(b(a),b=null)},onlogout:function(){}}),d.oncancel=function(){b&&(b(null),b=null),l.login=l.logout=l.match=l.ready=null},B(d))},getVerifiedEmail:function(a){v("navigator.id.getVerifiedEmail has been deprecated"),o(!0),z="getVerifiedEmail",navigator.id.get(a)},_shimmed:!0}}}()})()
  
1(function(window) {
2
3 var Oauth = function(options) {
4 // all necessary params provided?
5 if(!options.hasOwnProperty('app_id') || !options.hasOwnProperty('app_secret') ||
6 !options.hasOwnProperty('redirect_uri') || !options.hasOwnProperty('scopes') ||
7 !options.hasOwnProperty('endpoint')) {
8
9 throw new Error('All of the - app_id, app_secret, redirect_uri, scopes'+
10 ', endpoint - parameters must be provided');
11 return;
12 }
13 // check for string types
14 for(key in options) {
15 if(typeof options[key] !== 'string') {
16 throw new Error('All parameters should be of string type');
17 return false;
18 }
19 }
20
21 this.app_id = options.app_id;
22 this.app_secret = options.app_secret;
23 this.redirect_uri = options.redirect_uri;
24 this.scopes = options.scopes.split(',');
25 this.endpoint = options.endpoint;
26 // if scopes returns empty array - that means scopes was not provided in
27 // correct format - i.e comma seperated values
28 if(!this.scopes.length) {
29 throw new Error('scopes paramater must be a string of comma seperated scopes');
30 return;
31 }
32
33 return this;
34 };
35
36 // callback function to click handler
37 Oauth.prototype.login = function(event) {
38 event.preventDefault();
39 this.authorize();
40 };
41
42 Oauth.prototype.authorize = function() {
43 var qs = 'scope=' + this.scopes.join('+') + '&' +
44 'redirect_uri=' + encodeURIComponent(this.redirect_uri) + '&' +
45 'response_type=code&'+
46 'client_id=' + this.app_id;
47
48 window.location.href = this.endpoint + '?' + qs;
49 };
50
51 window.Oauth = Oauth;
52})(window);
  
1010
1111 $.ajaxSetup({
1212 xhrFields: {
13 // we need this to send cookies to cross-domain requests
1314 withCredentials: true
1415 },
16 //some browsers won't make cross-domain ajax until it is explicitly set
1517 crossDomain: true
1618 });
19 swtr.handleOAuth();
1720 };
1821
22 swtr.handleOAuth = function() {
23 if(swtr.access_token) {
24 $('#signinview').html('Signing you in..');
25 $.ajax({
26 url: 'http://localhost:5001/api/users/me?access_token='+
27 swtr.access_token,
28 success: function(data) {
29 swtr.appView.userLoggedIn(data.username);
30 }
31 });
32 }
33 };
34
1935 /* Model for Image Annotation Sweets */
2036 var ImgAnnoSwt = Backbone.Model.extend({
2137 defaults: {
6767 throw Error('"where" option must be passed to get sweets of a URI');
6868 return false;
6969 }
70 if(!swtr.access_token) {
71 throw new Error('Access Token required to get query that API');
72 }
7073 // setting up params
7174 var where = options.where,
7275 who = options.who || null;
73 url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' + where;
76 url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' +
77 encodeURIComponent(where) + '&access_token=' + swtr.access_token;
7478 if(who) {
7579 url += '&who=' + who;
7680 }
103103 var new_sweets = this.getNew();
104104 var dummy_collection = new Backbone.Collection(new_sweets);
105105
106 if(!swtr.access_token) {
107 throw new Error('Access Token is required to sweet');
108 return;
109 }
110
111 var url = swtr.swtstoreURL() + swtr.endpoints.post +
112 '?access_token=' + swtr.access_token;
113
106114 this.sync('create', dummy_collection, {
107 url: swtr.swtstoreURL() + swtr.endpoints.post,
115 url: url,
108116 success: function() {
109117 if(typeof options.success === 'function') {
110118 options.success.apply(this, arguments);
194194 swtr.appView.$overlay.hide();
195195 swtr.appView.helpview.step(6);
196196 },
197 error: function(jqxhr, error) {
198 console.log(jqxhr, error);
197 error: function(jqxhr, error, text) {
198 console.log(jqxhr, error, text);
199199 }
200200 });
201201 this.cleanUp();
230230 else {
231231 this.helpview.step(1);
232232 }
233
234 this.oauth = new Oauth({
235 app_id: 'YrYc9oMO7fT0avRUAtbRO1cLvoOUUI08BAuqOAJc',
236 app_secret: 'r9BIYjYOPotMQUOoI98DmH7Eu1M4zg6cMeLay7LOlSsrF1KhKZ',
237 endpoint: 'http://localhost:5001/oauth/authorize',
238 redirect_uri: 'http://localhost:5000/',
239 scopes: 'email,sweet'
240 });
233241 },
234242 setImage: function() {
235243 anno.reset();
265265 swtr.sweets.getAll({
266266 where: this.imgURL,
267267 success: function(data) {
268 console.log(data);
268269 if(_.isArray(data)) {
270 console.log('data is array');
269271 swtr.sweets.add(data);
270272 _.each(data, function(swt) {
271273 swt.how['editable'] = false;
314314 },
315315 getSignInCredentials: function(event) {
316316 event.preventDefault();
317 navigator.id.request();
318 /*if(swtr.who === 'Guest' && !$('#username').length) {
319 var template = _.template($('#signin-credentials-template').html());
320 $('#signin-msg').html(template());
321 }
322 else if($('#username').length && $('#username').val()) {
323 var username = $('#username').val();
324 var password = $('#password').val();
325 this.signIn(username, password);
326 }*/
317 this.oauth.authorize();
327318 return false;
328319 },
329320 signIn: function(username, password) {
340340 }
341341 });
342342 },
343 userLoggedIn: function(userData) {
344 swtr.who = userData.username;
345 var text = 'You are signed in as <b>' + swtr.who+ '</b>';
343 userLoggedIn: function(token) {
344 swtr.who = token;
345 var text = 'You are signed in as <b>' + swtr.who + '</b>';
346346 $('#signinview').html(text);
347347 },
348348 userLoggedOut: function() {
392392 //swtr.AppView = AppView;
393393
394394 // Persona callbacks
395 navigator.id.watch({
395 /*navigator.id.watch({
396396 //when an user logs in
397397 onlogin: function(assertion) {
398398 //verify assertion and login the user
423423 }
424424 });
425425 }
426 });
426 });*/
427427
428428})(swtr);
  
5252 <script>
5353 window.swtr = window.swtr || {};
5454 swtr.swtstoreURL = function() { return '{{ conf.swtstoreURL }}'; }
55 swtr.endpoints = {'get': '/sweets/q', 'post': '/sweets', 'auth':
55 swtr.endpoints = {'get': '/api/sweets/q', 'post': '/api/sweets', 'auth':
5656 '/authenticate', 'login': '/auth/login', 'logout': '/auth/logout'};
57 swtr.access_token = '{{ access_token }}';
58 swtr.refresh_token = '{{ refresh_token }}';
5759 window.onload = function() {
5860 swtr.init();
5961 };
6666 <script src="{{ url_for('static', filename='js/lib/backbone-1.0.0.min.js') }}"></script>
6767 <script src="{{ url_for('static', filename='js/lib/annotorious.debug.js') }}"></script>
6868 <!--script src="https://login.persona.org/include.js"></script-->
69 <script src="{{ url_for('static', filename='js/lib/mozilla.persona.include.js') }}"></script>
69 <!--script src="{{ url_for('static',
70 filename='js/lib/mozilla.persona.include.js') }}"></script-->
71 <script src="{{ url_for('static', filename='js/oauth.js') }}"></script>
7072 <script src="{{ url_for('static', filename='js/swtmaker.js') }}"></script>
7173
7274 <script type="text/template" id="sweet-template">