internal Extension.Auth.OAuth2Token getToken() { try { // check to see if the token is valid if (!Extension.Auth.OAuth2Utilities.isTokenExpired(ref log, token)) { // returning global token log.Debug("Returning global token object, as it is valid."); return(this.token); } else { // exchange OAuth2 code for new token, as it is invalid log.Debug("Exchanging the OAuth2 code for a new token, as it has expired."); this.token = Extension.Auth.OAuth2Utilities.refreshToken(ref log, token); // return the new token log.Debug("Returning new, refreshed token."); return(this.token); } } catch (System.Exception ex) { // an error occured and was not able to get token log.Error(ex); System.Windows.Forms.MessageBox.Show("Unable to retrieve a short-lived authentication token from your Google Account. Please sign-in and try again."); this.clearToken(); return(null); } }
internal void publishRaiseAuthenticationStateChangeEvent(bool isAuthorized, Extension.Auth.OAuth2Token token) { if (isAuthorized) { OnRaiseAuthenticationStateChangeEvent(new Extension.Auth.AuthenticationStateChangeEventArgs(isAuthorized, token)); } else { OnRaiseAuthenticationStateChangeEvent(new Extension.Auth.AuthenticationStateChangeEventArgs(isAuthorized)); } }
internal void clearToken() { // clear the OAuth2 Token from the user's profile Extension.Auth.OAuth2Utilities.clearToken(ref log); // clear the global token this.token = null; // raise an Authentication event OnRaiseAuthenticationStateChangeEvent(new Extension.Auth.AuthenticationStateChangeEventArgs(false, null)); // raise a selection state change event too, for buttons dependent on selection OnRaiseSelectionChangeEvent(new Extension.SelectionChangeEventArgs(false)); }
/* * A utility class used to initialize the token object stored * in a user's profile (occures when a user is signed-in but opens a new * window) */ public static OAuth2Token getToken(ref ILog log) { log.Debug("getToken starting."); // surround by try/catch just in case there is an issue fetching a token try { // establish a new OAuth2Token object log.Debug("Establishing a new OAuth2 Token Object."); OAuth2Token token = new OAuth2Token(); // fill the OAuth2 Token Object with properties from the user's profile log.Debug("Retrieving the user's settings profile and updating the OAuth2 Token object."); token.access_token = Properties.Settings.Default.oauth2_user_access_token; log.Debug("access_token= " + token.access_token); token.expires_in = Properties.Settings.Default.oauth2_user_expires_in; log.Debug("expires_in= " + token.expires_in); token.expires_on = Properties.Settings.Default.oauth2_user_expires_on; log.Debug("expires_on= " + token.expires_on); token.token_type = Properties.Settings.Default.oauth2_user_token_type; log.Debug("token_type= " + token.token_type); token.refresh_token = Properties.Settings.Default.oauth2_user_refresh_token; log.Debug("refresh_token= " + token.refresh_token); // return the token log.Debug("Returning the token object."); return token; } catch (System.Exception ex) { // an error occured, log the error log.Error(ex); // throw the error to the requesting function throw new System.Exception(Properties.Resources.auth_getToken_error_unknown); } }
internal void setToken(Extension.Auth.OAuth2Token token) { // replace the global token object log.Debug("Replacing the global token object with a new one"); this.token = token; }
// constructor containing only the initial state public AuthenticationStateChangeEventArgs(bool isAuthorized) { this._isAuthorized = isAuthorized; this._token = null; }
/* * Utility function to trade in a code snippet for a valid OAuth 2.0 token */ public static OAuth2Token tradeCodeForToken(ref ILog log, string code, bool isViewOnly) { log.Debug("Attempting to trade in a code snippet for an OAuth 2.0 access token."); log.Debug("code=" + code); // attempt to trade in the code snippet for token try { // build a request Url to trade the code for a shortlived token log.Debug("Buliding the base URL to trade in the code for a token."); string oAuthTokenUrl = Properties.Settings.Default.oauth2_settings_token_url; log.Debug(oAuthTokenUrl); // build the query string for the trade log.Debug("Building the query portion of the URL"); string query = ""; // set the code parameter of the query log.Debug("code=" + code); query += "code=" + code; // set the client_id parameter of the query log.Debug("client_id=" + Properties.Settings.Default.oauth2_settings_clientId); query += "&client_id=" + Properties.Settings.Default.oauth2_settings_clientId; // set the client_secret parameter of the query log.Debug("client_secret=" + Properties.Settings.Default.oauth2_settings_client_secret); query += "&client_secret=" + Properties.Settings.Default.oauth2_settings_client_secret; // TODO: Encode and decode client secret // set the redirect_uri parameter of the query log.Debug("redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob"); query += "&redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob"; // set the grant_type paramter of the query log.Debug("grant_type=" + "authorization_code"); query += "&grant_type=" + "authorization_code"; // create a URI of the url and query string log.Debug("Creating a URI object using the base URL"); Uri oAuthTokenExchangeUri = new Uri(oAuthTokenUrl); log.Debug(oAuthTokenExchangeUri); // create a byte array to hold the contents of the post log.Debug("Encoding the query portion of the POST."); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); byte[] payload = encoding.GetBytes(query); // setup an HTTP Web Request method log.Debug("Creating a new HttpWebRequest object to make the POST request."); WebRequest tokenWebRequest = HttpWebRequest.Create(oAuthTokenExchangeUri); // set the request method to POST log.Debug("Setting the HTTP method to POST"); tokenWebRequest.Method = "POST"; // set the content type log.Debug("Setting the content type to \"application/x-www-form-urlencoded\""); tokenWebRequest.ContentType = "application/x-www-form-urlencoded"; // set the user agent, for trouble shooting log.Debug("Setting the user agent for this request for identification."); ((HttpWebRequest)tokenWebRequest).UserAgent = "Google Maps Engine Connector for ArcGIS"; // set the content length log.Debug("Setting the content length of the POST payload/body."); tokenWebRequest.ContentLength = payload.Length; // TODO: Handle local proxy servers // get the request stream to write the query bytes to log.Debug("Getting the data stream for this POST request."); System.IO.Stream dataStream = tokenWebRequest.GetRequestStream(); // write the query payload to the data stream log.Debug("Attempting to write the payload to the POST stream."); dataStream.Write(payload, 0, payload.Length); // close the data stream log.Debug("Closing the POST data stream."); dataStream.Close(); // get the HTTP response log.Debug("Fetching the HTTP response from this request."); using (WebResponse tokenWebResponse = tokenWebRequest.GetResponse()) { // verify the response status was OK log.Debug("Checking the HTTP status of the response to make sure it is valid."); log.Debug("StatusCode=" + ((HttpWebResponse)tokenWebResponse).StatusCode); if (((HttpWebResponse)tokenWebResponse).StatusCode == HttpStatusCode.OK) { // setup a stream reader to read the response from the server log.Debug("Establishing a data reader to retreive the server response."); System.IO.StreamReader reader = new System.IO.StreamReader(tokenWebResponse.GetResponseStream()); // read the response into a local variable log.Debug("Reading to the end of the server's response."); string response = reader.ReadToEnd(); // close the response stream from the server log.Debug("Closing the server response object."); tokenWebResponse.Close(); // deserialize response into a token object log.Debug("Deserializing (JSON to C# object) the server's response"); OAuth2Token token = DeserializeResponseToken(ref log, response); log.Debug("Deserialization complete and token object created."); // set the requested and validated scopes log.Debug("Setting the requested scopes."); token.isViewOnly = isViewOnly; // store the token in the users profile log.Debug("Save and set the token object in the user's profile."); setToken(ref log, token); // setup a token object (decode from JSON to object) log.Debug("Returning the valid token object decoded."); return(token); } else { // log an error log.Debug("The response from the server was not OK."); // throw a new exception throw new System.Exception(Properties.Resources.auth_tokenexchange_error_404); } } } catch (System.Exception ex) { // log an error log.Error(ex); // throw an unknown error throw new System.Exception(Properties.Resources.auth_tokenexchange_error_unknown); } }
public GoogleMapsEngineToolsExtensionForArcGIS() { // initialize and configure log4net, reading from Xml .config file log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config")); log.Info("The extension is initializing."); // set the extension object to this log.Debug("Setting the extension object to this."); s_extension = this; // The Google Maps Engine Tools Extension for ArcMap is initializing // This occures when the extension is loaded or referenced for the first time // The extension is set for delayed loading, so this may happen at Map Load or later, for instance // when the user goes to the Tools > Extension menu // initialize the OAuth2 token object log.Debug("Initializing the OAuth2 token object."); token = null; // Step 1: Check to see if the extension is enabled log.Debug("Checking to see if the extension is enabled."); if (this.State == ESRI.ArcGIS.Desktop.AddIns.ExtensionState.Enabled) { log.Debug("The extension is enabled."); // raise an extension changed event OnRaiseExtensionStateChangeEvent(new Extension.StateChangeEventArgs(true)); // check to see if there is a valid token stored for this user log.Debug("Checking to see if the token object exists in the user's profile."); if (Extension.Auth.OAuth2Utilities.doesTokenExist(ref log)) { log.Debug("Token exists."); // retrieve token from the user's profile for use log.Debug("Getting token object from user's proflie."); token = Extension.Auth.OAuth2Utilities.getToken(ref log); } // check to see if there is an update to the Extension //TODO: Spin off a seperate thread to do this // create an update check object log.Debug("Creating an update check object."); Extension.Update.ExtensionUpdateCheck updateCheck = new Extension.Update.ExtensionUpdateCheck(); // check to see if there is an update available log.Debug("Checking to see if there is an update available."); if (updateCheck.isUpdateAvailable()) { log.Debug("isUpdateAvailable = true"); // create a dialog to inform the user of an update log.Debug("Showing the user an OK/Cancel dialog to notify them of an update."); if (System.Windows.Forms.MessageBox.Show("An update to the Google Maps Engine Tools for ArcGIS is avaiable. Would you like to update the Add-in now?" , "Update Available (" + updateCheck.getLocalVersion().ToString() + " < " + updateCheck.getServerVersion().ToString() + ")" , System.Windows.Forms.MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK) { // launch browser at the URL provided in the update check log.Debug("Launching the browser to the update URL, as the user selected OK."); System.Diagnostics.Process.Start(updateCheck.getUpdateURI()); } } } else { // the extension is not enabled or is unavailable log.Debug("The extension is disabled or unavailable (" + this.State + ")."); } }
internal void clearToken() { // clear the OAuth2 Token from the user's profile Extension.Auth.OAuth2Utilities.clearToken(ref log); // clear the global token this.token = null; // raise an Authentication event OnRaiseAuthenticationStateChangeEvent(new Extension.Auth.AuthenticationStateChangeEventArgs(false, true, null)); // raise a selection state change event too, for buttons dependent on selection OnRaiseSelectionChangeEvent(new Extension.SelectionChangeEventArgs(false)); }
public static OAuth2Token refreshToken(ref ILog log, OAuth2Token token) { // if the user has a valid code log.Debug("Attempting to determine if the token already exists."); if (doesTokenExist(ref log)) { log.Debug("Token exist."); // trade in the code for an updated temporary token //return tradeCodeForToken(ref log, Properties.Settings.Default.oauth2_user_code); log.Debug("Returning the result from a refresh trade in."); return tradeRefreshForToken(ref log, Properties.Settings.Default.oauth2_user_refresh_token, Properties.Settings.Default.oauth2_user_isViewOnly); } else { log.Debug("Does not exist."); // clear the token from the user's profile log.Debug("Clearing the token from the users profile."); clearToken(ref log); // throw an error message throw new System.Exception(Properties.Resources.auth_refreshToken_error_tokendoesntexist); } }
/* * Utility funciton used to check if the in-memory token object * is expired or not */ public static bool isTokenExpired(ref ILog log, OAuth2Token token) { // verify the following parameters /// Valid OAuth2 Code Exists /// Valid OAuth2 Temporary Token Exists /// Valid OAuth2 Temporary Token has not expired if (token != null && token.access_token != null && token.expires_in > 0 && token.access_token.Length > 0 && token.expires_on > System.DateTime.UtcNow) return false; else return true; }
// constructor containing both the OAuth token object and a initial state public AuthenticationStateChangeEventArgs(bool isAuthorized, OAuth2Token token) { this. _isAuthorized = isAuthorized; this._token = token; }
// constructor containing only the initial state public AuthenticationStateChangeEventArgs(bool isAuthorized, bool isViewOnly) { this._isAuthorized = isAuthorized; this._token = null; this._isViewOnly = isViewOnly; }
public static OAuth2Token tradeRefreshForToken(ref ILog log, string code, bool isViewOnly) { // attempting to trade in a refresh code for an auth token log.Debug("Attempting to trade in a refresh code for another auth code."); log.Debug("code=" + code); // attempt to trade in try { // build a request Url to trade the code for a shortlived token log.Debug("Building a base URL to exchange token for code."); string oAuthTokenUrl = Properties.Settings.Default.oauth2_settings_token_url; // build the query string for the trade log.Debug("Establishing the new query parameters for request."); string query = ""; // set the client_id parameter of the query log.Debug("client_id=" + Properties.Settings.Default.oauth2_settings_clientId); query += "client_id=" + Properties.Settings.Default.oauth2_settings_clientId; // set the client_secret parameter of the query log.Debug("client_secret=" + Properties.Settings.Default.oauth2_settings_client_secret); query += "&client_secret=" + Properties.Settings.Default.oauth2_settings_client_secret; // TODO: Encode and decode client secret // set the refresh_token = to the code log.Debug("refresh_token=" + code); query += "&refresh_token=" + code; // set the grant_type paramter of the query log.Debug("grant_type=" + "refresh_token"); query += "&grant_type=" + "refresh_token"; // create a URI of the url and query string log.Debug("Building a new URI object for this request."); Uri oAuthTokenExchangeUri = new Uri(oAuthTokenUrl); // create a byte array to hold the contents of the post log.Debug("Encoding the payload (HTTP Post) into bytes."); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); byte[] payload = encoding.GetBytes(query); // setup an HTTP Web Request method log.Debug("Creating a new HTTP WebRequest object to make the request."); WebRequest tokenWebRequest = HttpWebRequest.Create(oAuthTokenExchangeUri); // set the request method to POST log.Debug("Setting the HTTP method to POST."); tokenWebRequest.Method = "POST"; // set the content type log.Debug("Setting the contentType for this request to \"application/x-www-form-urlencoded\""); tokenWebRequest.ContentType = "application/x-www-form-urlencoded"; // set the user agent, for trouble shooting log.Debug("Setting the user agent for this request for identification."); ((HttpWebRequest)tokenWebRequest).UserAgent = "Google Maps Engine Connector for ArcGIS"; // set the content length log.Debug("Setting the HTTP Post content length to " + payload.Length); tokenWebRequest.ContentLength = payload.Length; // TODO: Handle local proxy servers // get the request stream to write the query bytes to log.Debug("Creating a new stream object to write the HTTP PoST body to the request."); System.IO.Stream dataStream = tokenWebRequest.GetRequestStream(); // write the query payload to the data stream log.Debug("Writing the HTTP POST payload the request."); dataStream.Write(payload, 0, payload.Length); // close the data stream log.Debug("Closing the HTTP POST data stream."); dataStream.Close(); // get the HTTP response log.Debug("Creating a new response object from the server."); using (WebResponse tokenWebResponse = tokenWebRequest.GetResponse()) { // verify the response status was OK log.Debug("Attempting to determine if the response from the server was OK."); log.Debug("StatusCode=" + ((HttpWebResponse)tokenWebResponse).StatusCode); if (((HttpWebResponse)tokenWebResponse).StatusCode == HttpStatusCode.OK) { log.Debug("Response from the server was OK."); // setup a stream reader to read the response from the server log.Debug("Creating a stream reader object to read the server response payload."); System.IO.StreamReader reader = new System.IO.StreamReader(tokenWebResponse.GetResponseStream()); // read the response into a local variable log.Debug("Reading to the end of the content."); string response = reader.ReadToEnd(); // close the response stream from the server log.Debug("Closing the response object."); tokenWebResponse.Close(); // deserialize response into a token object log.Debug("Deserializing the server response into a local Token object."); OAuth2Token token = DeserializeResponseToken(ref log, response); // update refresh_token to the current code, as it does not come back in the // refresh token response, only as apart of the code exchange log.Debug("Updating the refresh token to code used in this refresh request."); token.refresh_token = code; // store the token in the users profile log.Debug("Storing/saving the token to the user's profile"); setToken(ref log, token); // setup a token object (decode from JSON to object) log.Debug("Returning the token."); return(token); } else { // log an error log.Debug("The response from the server was not OK."); // throw a new exception throw new System.Exception(Properties.Resources.auth_refreshexchange_error_404); } } } catch (System.Exception ex) { // log an error log.Error(ex); // throw an unknown error throw new System.Exception(Properties.Resources.auth_refreshexchange_error_unknown); } }
/* * Utility function used to set/save the OAuth 2.0 in the user's profile for * longer term storage */ public static void setToken(ref ILog log, OAuth2Token token) { log.Debug("setToken start."); // surround with try/catch in case there is an issue setting the values in the user's profile try { // update the user's profile with the Token Object log.Debug("Updating the user's profile based on the OAuth2Token object."); Properties.Settings.Default.oauth2_user_access_token = token.access_token; log.Debug("oauth2_user_access_token= " + token.access_token); Properties.Settings.Default.oauth2_user_expires_in = token.expires_in; log.Debug("oauth2_user_expires_in= " + token.expires_in); Properties.Settings.Default.oauth2_user_expires_on = token.expires_on; log.Debug("oauth2_user_expires_on= " + token.expires_on); Properties.Settings.Default.oauth2_user_token_type = token.token_type; log.Debug("oauth2_user_token_type= " + token.token_type); Properties.Settings.Default.oauth2_user_refresh_token = token.refresh_token; log.Debug("oauth2_user_refresh_token= " + token.refresh_token); Properties.Settings.Default.oauth2_user_isViewOnly = token.isViewOnly; log.Debug("oauth2_user_isViewOnly= " + token.isViewOnly); // save the user's profile log.Debug("Saving the user's settings profile."); Properties.Settings.Default.Save(); } catch (System.Exception ex) { // there was an error saving the token to the user's profile log.Error(ex); // throw the error to the requestor throw new System.Exception(Properties.Resources.auth_setToken_error_unknown); } }
internal Extension.Auth.OAuth2Token getToken() { try { // check to see if the token is valid if (!Extension.Auth.OAuth2Utilities.isTokenExpired(ref log, token)) { // returning global token log.Debug("Returning global token object, as it is valid."); return this.token; } else { // exchange OAuth2 code for new token, as it is invalid log.Debug("Exchanging the OAuth2 code for a new token, as it has expired."); this.token = Extension.Auth.OAuth2Utilities.refreshToken(ref log, token); // return the new token log.Debug("Returning new, refreshed token."); return this.token; } } catch (System.Exception ex) { // an error occured and was not able to get token log.Error(ex); System.Windows.Forms.MessageBox.Show("Unable to retrieve a short-lived authentication token from your Google Account. Please sign-in and try again."); this.clearToken(); return null; } }
// constructor containing both the OAuth token object and a initial state public AuthenticationStateChangeEventArgs(bool isAuthorized, OAuth2Token token) { this._isAuthorized = isAuthorized; this._token = token; }