Merge branch 'master' of github.com:systemed/potlatch2
[potlatch2.git] / net / systemeD / potlatch2 / save / OAuthPanel.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:TitleWindow
3     xmlns:fx="http://ns.adobe.com/mxml/2009"
4         xmlns:mx="library://ns.adobe.com/flex/mx"
5         layout="vertical"
6         horizontalAlign="center" title="Authorisation Required"
7         creationComplete="getRequestToken()"
8         height="290">
9         
10         <mx:ViewStack id="contentStack" width="100%" height="100%">
11         
12         <mx:VBox id="okPanel" width="100%" height="100%">
13           <mx:Text width="100%" text="{getAuthText()}"/>
14           <mx:VBox width="100%" id="gotLinkBox" visible="false">
15             <mx:Text width="100%">
16               <mx:text>
17                 Click the link below to open a web page where
18                 you will be asked to authorise access to this app.
19               </mx:text>
20             </mx:Text>
21             <mx:LinkButton id="link"
22                 label="http://oauth.dev.openstreetmap.org/oauth/authorize?somekey"
23                 click="openURL(authoriseURL); tryAccessButton.enabled=true;"/>
24             <mx:Text id="authorized" width="100%">
25               <mx:text>Once you've authorised the access click the 'Try Access' button below</mx:text> <!-- ' -->
26             </mx:Text>
27             <mx:Text styleName="failText" visible="false" id="deniedLabel">
28               <mx:text><![CDATA[<b>Access was denied, please check, and try again</b>]]></mx:text>
29             </mx:Text>
30             <mx:HBox width="100%" horizontalAlign="right">
31               <mx:CheckBox id="rememberMe" label="Remember authorisation" selected="true"/>
32             </mx:HBox>
33           </mx:VBox>
34         </mx:VBox>
35         
36         <mx:VBox id="permFailPanel" width="100%" height="100%">
37           <mx:Text id="permFail" styleName="failText" width="100%" condenseWhite="true">
38             <mx:htmlText><![CDATA[
39               <p>The server refused this application's credentials -- an authorisation link
40               could not be obtained.
41               </p><p>
42               <b>OAuth access will not be possible.</b>
43               </p><p>
44               Please contact application vendor to find out what's going on.
45             ]]></mx:htmlText>
46           </mx:Text>
47         </mx:VBox>
48         
49         <mx:VBox id="tempFailPanel" width="100%" height="100%">
50           <mx:Text id="tempFail" width="100%">
51             <mx:text>
52               There was a problem contacting the server to get authorisation.
53               This may be a temporary error, try again later.
54             </mx:text>
55           </mx:Text>
56         </mx:VBox>
57         
58         </mx:ViewStack>
59         
60         <mx:ControlBar horizontalAlign="right">
61         
62             <mx:ProgressBar id="progress" label="Contacting server..." labelPlacement="top"
63                 indeterminate="true"/>
64         <mx:Spacer width="100%"/>
65
66             <mx:Button id="cancelButton" label="Cancel" click="PopUpManager.removePopUp(this);" styleName="titleWindowButton" />
67             <mx:Button id="tryAccessButton" label="Try Access" click="getAccessToken()" enabled="false" styleName="titleWindowButton" />
68         </mx:ControlBar>
69         
70         <fx:Script><![CDATA[
71                 import flash.display.InteractiveObject;
72         import flash.events.Event;
73         import flash.net.*;
74                 import flash.system.Capabilities;
75         import mx.managers.PopUpManager;
76         import net.systemeD.halcyon.connection.*;
77         import org.iotashan.oauth.*;
78                 import flash.external.ExternalInterface;
79
80         private var connection:Connection;
81         private var requestToken:OAuthToken;
82         private var _accessToken:OAuthToken;
83         private var authoriseURL:String;
84         private var lastHTTPStatus:int = 0;
85         private var waiting:Boolean = false;
86         
87         public static var ACCESS_TOKEN_EVENT:String = "gotAccessToken";
88         
89         private function getAuthText():String {
90             return "To save data you must authorise this application to edit "+
91                     connection.serverName + " on your behalf.";
92         }
93         
94                 public function setConnection(connection:Connection):void {
95                         this.connection=connection;
96                         if (waiting) { waiting=false; getRequestToken(); }
97                 }
98
99         private function openURL(url:String):void {
100                         if (ExternalInterface.available) {
101                                 var winH:int = 560;
102                                 var winW:int = 600;
103                                 var leftPos:int  = (Capabilities.screenResolutionX - winW) / 2;
104                                 var topPos:int = (Capabilities.screenResolutionY - winH) / 2;
105                                 ExternalInterface.call( "window.open", url,"oAuthWin","height=" + winH + ",width=" + winW +",top=" + topPos + ", left=" + leftPos +", toolbar=no,scrollbars=no,status=no,location=no,menubar=no,directories=no");
106                                 }               
107                         else
108                         {
109                                 var urlRequest:URLRequest = new URLRequest(url);
110                                 navigateToURL(urlRequest,"_blank");
111                         }
112                 }
113         
114         private function getRequestToken():void {
115             if (!connection) { waiting=true; return; }  // in case the connection hasn't been set yet
116
117             var sig:IOAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();
118             var consumer:OAuthConsumer = getConsumer();
119             var url:String = connection.getParam("oauth_request_url", "http://127.0.0.1:3000/oauth/request_token");
120             
121             var params:Object = new Object();
122             var oauthRequest:OAuthRequest = new OAuthRequest("GET", url, params, consumer, null);
123             var urlStr:Object = oauthRequest.buildRequest(sig, OAuthRequest.RESULT_TYPE_URL_STRING)
124
125                         //register the "pressTry" function so the oAuth callback page can try to advance the editor directly to the next step
126             if (ExternalInterface.available) {
127                 ExternalInterface.addCallback("pressTry", pressTry);
128             }
129                         
130             // build the actual request
131             var urlReq:URLRequest = new URLRequest(String(urlStr));
132             var loader:URLLoader = new URLLoader();
133             loader.addEventListener(Event.COMPLETE, loadedRequestToken);
134             loader.addEventListener(IOErrorEvent.IO_ERROR, requestTokenError);
135             loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, recordStatus);
136             loader.load(urlReq);
137         }
138         
139         private function recordStatus(event:HTTPStatusEvent):void {
140             lastHTTPStatus = event.status;
141         }
142         
143         private function requestTokenError(event:IOErrorEvent):void {
144             trace("error occured... last status was: "+lastHTTPStatus);
145             
146             if ( lastHTTPStatus == 401 ) {
147                 // this means authorisation was refused -- refused at this stage
148                 // means our consumer token is broken
149                 contentStack.selectedChild = permFailPanel;
150             } else {
151                 contentStack.selectedChild = tempFailPanel;
152             }
153             progress.visible = false;
154         }
155         
156         private function loadedRequestToken(event:Event):void {
157             trace("Yay! response: "+URLLoader(event.target).data);
158             requestToken = getResponseToken(URLLoader(event.target));
159             
160             var url:String = connection.getParam("oauth_auth_url", "http://127.0.0.1:3000/oauth/authorize");            
161             link.label = url;
162                         authoriseURL = url + "?oauth_token="+requestToken.key;
163                         progress.visible = false;
164             gotLinkBox.visible = true;
165         }
166
167         private function getResponseToken(loader:URLLoader):OAuthToken {
168             var vars:URLVariables = new URLVariables(loader.data);
169             
170             // build out request token
171             var token:OAuthToken = new OAuthToken(
172                 String(vars["oauth_token"]),
173                 String(vars["oauth_token_secret"]));
174             return token;
175         }
176         
177         private function getAccessToken():void {
178             var sig:IOAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();
179             var consumer:OAuthConsumer = getConsumer();
180             var url:String = connection.getParam("oauth_access_url", "http://127.0.0.1:3000/oauth/access_token");
181
182             var oauthRequest:OAuthRequest = new OAuthRequest("GET", url, null, consumer, requestToken);
183             var urlStr:Object = oauthRequest.buildRequest(sig, OAuthRequest.RESULT_TYPE_URL_STRING)
184
185             var urlReq:URLRequest = new URLRequest(String(urlStr));
186             var loader:URLLoader = new URLLoader();
187             loader.addEventListener(Event.COMPLETE, loadedAccessToken);
188             loader.addEventListener(IOErrorEvent.IO_ERROR, accessTokenError);
189             loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, recordStatus);
190             loader.load(urlReq);
191             
192             progress.label = "Checking access";
193             progress.visible = true;  
194         }
195         
196         private function loadedAccessToken(event:Event):void {
197             trace("Yay! response: "+URLLoader(event.target).data);
198             progress.label = "Received Access";
199             progress.indeterminate = false;
200             progress.setProgress(100,100);
201             PopUpManager.removePopUp(this);
202             
203             _accessToken = getResponseToken(URLLoader(event.target));
204             connection.setAuthToken(_accessToken);
205             dispatchEvent(new Event(ACCESS_TOKEN_EVENT));
206         }
207         
208         public function get accessToken():OAuthToken {
209             return _accessToken;
210         }
211         
212         public function get shouldRemember():Boolean {
213             return rememberMe.selected;
214         }
215         
216         private function accessTokenError(event:IOErrorEvent):void {
217             if ( lastHTTPStatus == 401 ) {
218                 deniedLabel.htmlText = "<b>Access was denied, please check, and try again</b>";
219             } else {
220                 deniedLabel.htmlText = "<b>Error occurred</b> ("+lastHTTPStatus+"): please try again";
221             }
222             deniedLabel.visible = true;
223         }
224         
225         private function getConsumer():OAuthConsumer {
226             var key:String = connection.getParam("oauth_consumer_key", "");
227             var secret:String = connection.getParam("oauth_consumer_secret", "");
228             return new OAuthConsumer(key, secret);
229         }
230                 
231                 public function pressTry():void {
232                         getAccessToken();
233                 }
234         
235         ]]></fx:Script>
236 </mx:TitleWindow>
237