Authentication

There are five supported authentication methods:

  • OAuth 2.0
  • Username/Password
  • Username/Token
  • Key
  • None

Depending on which method you are using, you must provide additional functions in your connector.

The following table indicates which functions you must define depending on the authentication type of your connector.

OAUTH2 USER_PASS/USER_TOKEN/KEY NONE
getAuthType() required required required
resetAuth() required required
isAuthValid() required required
authCallback() required
get3PAuthorizationUrls() required
setCredentials() required

getAuthType()

This function should return the authentication type for the connector.

OAUTH2

data-studio/auth.gs
/**
 * Gets the OAuth2 Auth type.
 * @return {object} The Auth type.
 */
function getAuthType() {
  return {
    type: 'OAUTH2'
  };
}

USER_PASS

data-studio/auth.gs
/**
 * Gets the OAuth2 Auth type.
 * @return {object} The Auth type.
 */
function getAuthType() {
  return {
    type: 'USER_PASS',
    helpUrl: 'https://www.example.org/connector-auth-help'
  };
}

USER_TOKEN

data-studio/auth.gs
/**
 * Gets the OAuth2 Auth type.
 * @return {object} The Auth type.
 */
function getAuthType() {
  return {
    type: 'USER_TOKEN',
    helpUrl: 'https://www.example.org/connector-auth-help'
  };
}

KEY

data-studio/auth.gs
/**
 * Gets the OAuth2 Auth type.
 * @return {object} The Auth type.
 */
function getAuthType() {
  return {
    type: 'KEY',
    helpUrl: 'https://www.example.org/connector-auth-help'
  };
}

NONE

data-studio/auth.gs
/**
 * Gets the OAuth2 Auth type.
 * @return {object} The Auth type.
 */
function getAuthType() {
  return {
    type: 'NONE'
  };
}

resetAuth()

This function will clear any credentials stored for the user for the third-party service.

OAUTH2

data-studio/auth.gs
/**
 * Resets the auth service.
 */
function resetAuth() {
  getOAuthService().reset();
}

USER_PASS

data-studio/auth.gs
/**
 * Resets the auth service.
 */
function resetAuth() {
  var userProperties = PropertiesService.getUserProperties();
  userProperties.deleteProperty('dscc.username');
  userProperties.deleteProperty('dscc.password');
}

USER_TOKEN

data-studio/auth.gs
/**
 * Resets the auth service.
 */
function resetAuth() {
  var user_tokenProperties = PropertiesService.getUserProperties();
  user_tokenProperties.deleteProperty('dscc.username');
  user_tokenProperties.deleteProperty('dscc.password');
}

KEY

data-studio/auth.gs
/**
 * Resets the auth service.
 */
function resetAuth() {
  var userProperties = PropertiesService.getUserProperties();
  userProperties.deleteProperty('dscc.key');
}

isAuthValid()

This function is called to determine if the authentication for the third-party service is valid. If authentication is valid then it is expected that calls to getData() and getSchema() will not fail due to unauthorized access. If the auth is not valid then the user may receive a notification to start the authorization flow.

OAUTH2

data-studio/auth.gs
/**
 * Returns true if the auth service has access.
 * @return {boolean} True if the auth service has access.
 */
function isAuthValid() {
  return getOAuthService().hasAccess();
}

USER_PASS

data-studio/auth.gs
/**
 * Returns true if the auth service has access.
 * @return {boolean} True if the auth service has access.
 */
function isAuthValid() {
  var userProperties = PropertiesService.getUserProperties();
  var userName = userProperties.getProperty('dscc.username');
  var password = userProperties.getProperty('dscc.password');
  // This assumes you have a validateCredentials function that
  // can validate if the userName and password are correct.
  return validateCredentials(userName, password);
}

USER_TOKEN

data-studio/auth.gs
/**
 * Returns true if the auth service has access.
 * @return {boolean} True if the auth service has access.
 */
function isAuthValid() {
  var userProperties = PropertiesService.getUserProperties();
  var userName = userProperties.getProperty('dscc.username');
  var token = userProperties.getProperty('dscc.token');
  // This assumes you have a validateCredentials function that
  // can validate if the userName and token are correct.
  return validateCredentials(userName, token);
}

KEY

data-studio/auth.gs
/**
 * Returns true if the auth service has access.
 * @return {boolean} True if the auth service has access.
 */
function isAuthValid() {
  var userProperties = PropertiesService.getUserProperties();
  var key = userProperties.getProperty('dscc.key');
  // This assumes you have a validateKey function that can validate
  // if the key is valid.
  return validateKey(key);
}

OAUTH2

Add and setup OAuth2 for Apps Script Library

Follow the setup instructions for the OAuth2 for Apps Script library to add it to your connector project. Then follow the first step in the usage guide to create an OAuth2 service in your connector project. Your OAuth2 service can have any valid function name but make sure to use the same name while referring to the OAuth2 service in your code.

For example, an OAuth2 service named exampleService:

data-studio/auth.gs
/**
 * Returns the OAuth Service
 * @return {Service} The OAuth Service
 */
function getOAuthService() {
  return OAuth2.createService('exampleService')
    .setAuthorizationBaseUrl('...')
    .setTokenUrl('...')
    .setClientId('...')
    .setClientSecret('...')
    .setPropertyStore(PropertiesService.getUserProperties())
    .setCallbackFunction('authCallback')
    .setScope('...');
};

authCallback()

This function is called to complete the OAuth 2.0 flow. The callback response from the third-party auth service is provided as an argument and should be handled by this function.

Example of handling the OAuth 2.0 callback using the OAuth2 for Apps Script library:

data-studio/auth.gs
/**
 * The OAuth callback.
 * @param {function} request The OAuth service callback handler.
 * @return {HtmlOutput} The HTML output.
 */
function authCallback(request) {
  var authorized = getOAuthService().handleCallback(request);
  if (authorized) {
    return HtmlService.createHtmlOutput('Success! You can close this tab.');
  } else {
    return HtmlService.createHtmlOutput('Denied. You can close this tab');
  };
};

get3PAuthorizationUrls()

This function is called to get the URL that is required to initiate the auth flow for the third-party service. If isAuthValid returns false then the URL returned will be displayed to the user as a button or link so that they can authorize access to the third-party service. See the reference for get3PAuthorizationUrls().

Example of returning the authorization Url using the OAuth2 for Apps Script library:

data-studio/auth.gs
/**
 * Gets the 3P authorization URL.
 * @return {string} The authorization URL.
 * @see https://developers.google.com/apps-script/reference/script/authorization-info
 */
function get3PAuthorizationUrls() {
  return getOAuthService().getAuthorizationUrl();
}

USER_PASS, USER_TOKEN, and KEY

The following is only needed for the USER_PASS, USER_TOKEN, and KEY authentication flows.

setCredentials()

setCredentials is called after the user enters either their credential information on the community connector configuration page. You should use the Properties Service to save the credentials on a per-user basis using UserProperties.

USER_PASS

data-studio/auth.gs
/**
 * Sets the credentials.
 * @param {Request} request The set credentials request.
 * @return {object} An object with an errorCode.
 */
function setCredentials(request) {
  var creds = request.userPass;
  var username = creds.username;
  var password = creds.password;

  // Optional
  // Check if the provided username and password are valid through a
  // call to your service. You would have to have a `checkForValidCreds`
  // function defined for this to work.
  var validCreds = checkForValidCreds(username, password);
  if (!validCreds) {
    return {
      errorCode: 'INVALID_CREDENTIALS'
    };
  }
  var userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty('dscc.username', username);
  userProperties.setProperty('dscc.password', password);
  return {
    errorCode: 'NONE'
  };
}

USER_TOKEN

data-studio/auth.gs
/**
 * Sets the credentials.
 * @param {Request} request The set credentials request.
 * @return {object} An object with an errorCode.
 */
function setCredentials(request) {
  var creds = request.userToken;
  var username = creds.username;
  var token = creds.token;

  // Optional
  // Check if the provided username and token are valid through a
  // call to your service. You would have to have a `checkForValidCreds`
  // function defined for this to work.
  var validCreds = checkForValidCreds(username, token);
  if (!validCreds) {
    return {
      errorCode: 'INVALID_CREDENTIALS'
    };
  }
  var userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty('dscc.username', username);
  userProperties.setProperty('dscc.token', token);
  return {
    errorCode: 'NONE'
  };
}

KEY

data-studio/auth.gs
/**
 * Sets the credentials.
 * @param {Request} request The set credentials request.
 * @return {object} An object with an errorCode.
 */
function setCredentials(request) {
  var key = request.key;

  // Optional
  // Check if the provided key is valid through a call to your service.
  // You would have to have a `checkForValidKey` function defined for
  // this to work.
  var validKey = checkForValidKey(key);
  if (!validKey) {
    return {
      errorCode: 'INVALID_CREDENTIALS'
    };
  }
  var userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty('dscc.key', key);
  return {
    errorCode: 'NONE'
  };
}