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