Custom user fields: Usernames are generated from the user’s first name, last name and a set of (optional) custom fields, i.e. second last name, student ID, department, nickname, etc.
Locked suggestions: Suggested usernames will remain locked (unavailable to other users) until they expire or are explicitly unlocked.
SSL support: All REST calls can be encrypted using SSL
Any programming language: You can choose any programming language and platform that supports REST calls. Almost any language and platform do.
What methods does this API offer
suggest: returns a list of username suggestions based on first name, last name and a set of custom fields.
create: creates a Google Apps account.
select: unlocks username suggestions that will no longer be used.
See the API Overview section to learn more about how to invoke these methods.
Quick start
Ready? Try the demos!
This API needs Java, but don’t worry you don’t need to develop your client in Java. You can use any language and platform you like (Python, JavaScript, PHP, C#, ObjectiveC, Go, etc.) as long as it can do REST calls.
This will start the RESTful API service on port 8080. If you already have a server running on port 8080, change it to another port, e.g. 8888.
4. Open a demo
Awesome! You can now start getting usernames suggestions and creating Google Apps accounts in your domain.
See the Note below if you used a different port from 8080
Open any of the index.html demos under the demos/ folder:
Demo
Sample
self-provisioning-demo Each user selects and creates their own account
bulk-provisioning-demo All accounts are created in bulk
csv-provisioning-demo All accounts are created in bulk from a CSV input
Note: If you used a different port from 8080, open first the JavaScript .js file inside the demo folder and update
var API_HOST = 'http://localhost:8080';
to point to the right port. For example:
var API_HOST = 'http://localhost:8888';
Both demos will initially show the configuration parameters that are relevant to the client. For example:
This screen will disappear after a couple of seconds.
You can change these parameters in the config.properties file and use this screen to verify the current configuration. Follow the next step to see how.
Now kill the Java process (Ctrl+C or Cmd+C) in the terminal and start the RESTful API service again (step 3). This will load the new patterns configuration, which will result in different usernames being generated.
Open the self-provisioning-demo\index.html demo and notice how the generated usernames are now different. They now follow the new patterns set in the config file. The configuration section explains how to patterns work.
Next, you can try changing other accounts.UsernameGeneration properties. For example, updating the following properties:
This API is developed in Java and can be invoked from any language and platform that can do REST API calls. The username cache is an H2 database, so you will see a usernames(*).mv.db file when running the API.
Only usernames are cached, no names or other user’s data is ever stored. The H2 Console Application can be used to inspect the cache.
The cache can be disabled with the cachedUsernames property. When disabled it will do Admin SDK API calls. When enabled, the cache will refresh periodically (see the cacheExpirationHours property).
API overview and sample code
suggest method
Description: Method that suggests available usernames in a domain. Uses the configuration file (see configuration) to determine:
Note: All suggested usernames will remain locked until they expire (see suggestedUsernamesTimeout) or the select method is called.
| REST API | Java API |
———— | ————- | —————-
Method | rest/suggest | apps.provisioning.server.account.UsernameManager.suggestParameters | JSON map with the following fields:
firstname the user’s first name
lastname the user’s last name
The JSON map might include customizable fields. For example:
secondLastname
nickname
| userData: A java.util.HashMap<String, String>with the following fields:
firstname the user’s first name
lastname the user’s last name
The HashMap might include customizable fields. For example:
secondLastname
nickname
Returns | In case of success, it returns a JSON serialized array with username suggestions, in case of error it returns a JSON serialized map with the "errorMessage" index explaining the error. | A java.util.ArrayList<String> of suggestions. Throws an Exception in case of an error.
Sample code for suggest
REST API
var url = 'http://localhost:8080/rest/suggest';
var parameters = '{' +
'"firstname": "Carlos",' +
'"lastname": "Alvarez",' +
'"secondLastname": "Martinez"' +
'}';
var xhr = new XMLHttpRequest();
xhr.onload = function() {
alert(this.responseText);
};
xhr.open('POST', url, true);
xhr.send(parameters);
Description: Selects the given username from the given suggestions. This will unlock all the suggestions, except the selected one (if any).
| REST API | Java API |
———— | ————- | —————-
Method | rest/select | apps.provisioning.server.account.UsernameManager.selectParameters | JSON map with the following fields:
username the selected username
suggestions a list of suggestions
|
suggestions an ArrayList<String> of suggested usernames
selectedUsername the selected username
Returns | In case of success, it returns a JSON serialized array with username suggestions, in case of error it returns a JSON serialized map with the "errorMessage" index explaining the error. | void Throws an Exception if an error occurs.
Sample code for select
REST API
var url = 'http://localhost:8080/rest/select';
var parameters = '{"username":"carlos.alvarez", "suggestions":["carlos.alvarez","carlosalvarez","c.alvarez"]}';
var xhr = new XMLHttpRequest();
xhr.onload = function() {
alert(this.responseText);
};
xhr.open('POST', url, true);
xhr.send(parameters);
Description: Creates a Google Apps account in the provided Google Apps Domain (see domain).
| REST API | Java API |
———— | ————- | —————-
Method | rest/create | apps.provisioning.server.account.UsernameManager.createParameters | JSON map with the following fields:
username account’s username
firstname user’s first name
lastname user’s last name
password account’s password
|
username account’s username
firstname user’s first name
lastname user’s last name
password account’s password
Returns | In case of success, it returns a JSON serialized array with username suggestions, in case of error it returns a JSON serialized map with the "errorMessage" index explaining the error. | void Throws an Exception if an error occurs.
Account provisioning for Google Apps follows the same [AdminSDK Directory API limits] (https://developers.google.com/admin-sdk/directory/v1/limits). Each call to create, select and suggest consumes a different number of Directory API calls:
Description: A username cache can be used to check if a username already exists. This prevents reaching AdminSDK API calls/day limit. If cachedUsernames is set to YES username availability will be checked against the cache. If set to NO it will be checked against the Google Directory (using a Directory API call).
Possible values: YES and NO
accounts.UsernameGeneration.cacheExpirationHours
Description: Defines the expiration time in hours of the usernames cache. After expiration, the application refreshes the username cache. For reference, refreshing an account with 1 million users takes approximately 35 minutes.
Possible values: Integers larger or equal to 1
Default: 24
accounts.UsernameGeneration.numberOfSuggestions
Description: The number of username suggestions to be returned for each call to suggest.
Possible values: Integer between 1 and 10 (inclusive)
Description: The amount of time (in seconds) that suggested usernames will remain locked (unavailable to another client).
Possible values: Integer greater than 0.
Default: 120 (2 minutes)
accounts.UsernameGeneration.patterns
Description: A pattern is something that looks like [firstname][lastname]. This pattern indicates the API that we want to generate a username with “the firstname followed by the lastname”. Now, if that username happens to be taken the API will need another pattern. Therefore, a list of multiple patterns is recommended. For example:
This will first try to generate a username with “the firstname followed by the lastname” if that is taken then it will try to generate a username with “the lastname followed by the firstname”.
So far so good?
Great. Now, say we want to generate a username with “the nickname followed by the lastname” of a person. We’d simply do:
It is not mandatory to pass nickname (or any custom field) for all users. If nickname is not provided for a user the API will skip that pattern and move on to the next one.
firstname and lastname are mandatory. Even if the pattern doesn’t make use of them.
Taking the first char(acters) of a field
Now say that for someone named John Smith we’d like to generate a username jsmith. We’d do it with the following pattern:
[C1_firstname][lastname]
C1 indicates that the API should take the first character of firstname. If we’d like to take the first two characters then we’d do:
[C2_firstname][lastname]
This same method applies for custom fields. For example, if we wanted to split the first character of the nickname we’d do:
[C1_nickname]
Adding a counter to a pattern
Now, say we have so many people named “John Smith” in a school district that we ran out of patterns. We could then define a pattern that adds a number at the end of the username:
[firstname][lastname][#]
[#] indicates that a number will be added to the username. For example: johnsmith3. This numeric value will start at 1 and continue adding until a username is available.
Note: The use of [#] should be the last resort as this counter can become hard to remember, e.g. johnsmith3816. A list of multiple patterns without [#] is encouraged before using a pattern with [#].
Adding separators to usernames
A common practice is to separate usernames with a period (.), an underscore (_) or a dash (-). These separators can be added to patterns. Example:
[firstname].[lastname]
would generate the username john.smith
Adding a string to a pattern
Same as the separators, it is possible to add a static string to username suggestions. For example, the pattern:
[lastname]_nyc
would generate the username smith_nyc
What if the API runs out of patterns?
The following pattern is used as the last resort:
[C9_firstname][C9_lastname][#]
patterns example
Given the following user data map, customFields and patterns:
```json
{
"firstname": "Carlos",
"lastname": "Álvarez",
"region": "CA",
"group": "5A"
}
```
To generate a appsProvisioning-0.0.1.jar file under ./target:
From bash
From the project’s root folder, run:
mvn clean install -Dmaven.test.skip=true
From Eclipse
Right click on the project
Run As > Maven build…
Under Goals: use clean install
Check the Skip test checkbox
Note: Tests create and remove Google Apps accounts in a test domain. Therefore, they are discouraged unless you plan to submit a change that affects those tests.
Feedback
If you have any questions or feedback, please let us know in the forum!
Impressions
This API logs the number of calls to suggest, create and select per Google Apps domain. No other information is ever collected. This helps us justify adding more resources and support to this API.
License
Account provisioning for Google Apps is licensed under Apache 2.0. Full license text is available in the LICENSE file.
This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.
Account provisioning for Google Apps
Account provisioning for Google Apps is an open source API to:
It can be used in a website where users create their own accounts…
a script that creates accounts in bulk…
or via a CSV input…
Usernames are generated automatically via configurable patterns. Sample images are taken from the included demos. Give them a try here!
This API can be installed as a RESTful service (to be invoked from almost any programming language and platform) or as a Java library.
Who should use it
Google Apps deployments where new usernames need to be created. Deployments that need to sync existing usernames can use [Google Apps Directory Sync] (https://support.google.com/a/answer/106368?hl=en) or [Google Apps School Directory Sync] (https://support.google.com/a/answer/6027781?hl=en).
Why you should use it
What methods does this API offer
suggest: returns a list of username suggestions based on first name, last name and a set of custom fields.create: creates a Google Apps account.select: unlocks username suggestions that will no longer be used.Quick start
Ready? Try the demos!
This API needs Java, but don’t worry you don’t need to develop your client in Java. You can use any language and platform you like (Python, JavaScript, PHP, C#, ObjectiveC, Go, etc.) as long as it can do REST calls.
1. Check your Java version
In the terminal run:
If you see:
java version "1.7.X"or a newer version you are ready to go. If not, install Java 7 or a newer verion.2. Set your Google Apps domain configuration
Follow the steps in the Google Apps domain configuration guide to configure your domain to work with this API.
3. Start the RESTful API service
Move the
config.propertiesand thep12file (created in the previoius step) to thebin/folder.In the terminal, run:
4. Open a demo
Awesome! You can now start getting usernames suggestions and creating Google Apps accounts in your domain.
Open any of the
index.htmldemos under thedemos/folder:Each user selects and creates their own account
All accounts are created in bulk
All accounts are created in bulk from a CSV input
Note: If you used a different port from 8080, open first the JavaScript
.jsfile inside the demo folder and updateto point to the right port. For example:
Both demos will initially show the configuration parameters that are relevant to the client. For example:
You can change these parameters in the
config.propertiesfile and use this screen to verify the current configuration. Follow the next step to see how.5. Play with the configuration
Now that you have the demos up and running is a great time to learn how usernames are generated.
config.propertiesfile and look for theaccounts.UsernameGeneration.patternsproperty.Now kill the Java process (
Ctrl+CorCmd+C) in the terminal and start the RESTful API service again (step 3). This will load the newpatternsconfiguration, which will result in different usernames being generated.Open the
self-provisioning-demo\index.htmldemo and notice how the generated usernames are now different. They now follow the new patterns set in the config file. The configuration section explains how to patterns work.Next, you can try changing other
accounts.UsernameGenerationproperties. For example, updating the following properties:This will result in:
Next steps
Index
System overview
This API is developed in Java and can be invoked from any language and platform that can do REST API calls. The username cache is an H2 database, so you will see a
usernames(*).mv.dbfile when running the API.The cache can be disabled with the
cachedUsernamesproperty. When disabled it will do Admin SDK API calls. When enabled, the cache will refresh periodically (see thecacheExpirationHoursproperty).API overview and sample code
suggestmethodDescription: Method that suggests available usernames in a domain. Uses the configuration file (see configuration) to determine:
numberofsuggestionspatternsdomainNote: All suggested usernames will remain locked until they expire (see
suggestedUsernamesTimeout) or theselectmethod is called.| REST API | Java API | ———— | ————- | —————- Method |
rest/suggest|apps.provisioning.server.account.UsernameManager.suggestParameters | JSON map with the following fields:
The JSON map might include customizable fields. For example:firstnamethe user’s first namelastnamethe user’s last name
|secondLastnamenicknameuserData: Ajava.util.HashMap<String, String>with the following fields:
The HashMap might include customizable fields. For example:firstnamethe user’s first namelastnamethe user’s last name
Returns | In case of success, it returns a JSON serialized array with username suggestions, in case of error it returns a JSON serialized map with thesecondLastnamenickname"errorMessage"index explaining the error. | Ajava.util.ArrayList<String>of suggestions. Throws anExceptionin case of an error.Sample code for
suggestREST API
Java API
Result
Note:
The following
config.properties(see configuration) was used for this example:selectmethodDescription: Selects the given username from the given suggestions. This will unlock all the suggestions, except the selected one (if any).
| REST API | Java API | ———— | ————- | —————- Method |
rest/select|apps.provisioning.server.account.UsernameManager.selectParameters | JSON map with the following fields:
|usernamethe selected usernamesuggestionsa list of suggestions
Returns | In case of success, it returns a JSON serialized array with username suggestions, in case of error it returns a JSON serialized map with thesuggestionsanArrayList<String>of suggested usernamesselectedUsernamethe selected username"errorMessage"index explaining the error. |voidThrows an
Exceptionif an error occurs.Sample code for
selectREST API
Result
Java API
createmethodDescription: Creates a Google Apps account in the provided Google Apps Domain (see
domain).| REST API | Java API | ———— | ————- | —————- Method |
rest/create|apps.provisioning.server.account.UsernameManager.createParameters | JSON map with the following fields:
|usernameaccount’s usernamefirstnameuser’s first namelastnameuser’s last namepasswordaccount’s password
Returns | In case of success, it returns a JSON serialized array with username suggestions, in case of error it returns a JSON serialized map with theusernameaccount’s usernamefirstnameuser’s first namelastnameuser’s last namepasswordaccount’s password"errorMessage"index explaining the error. |voidThrows an
Exceptionif an error occurs.Sample code for
createREST API
Result
Java API
API limits
Account provisioning for Google Apps follows the same [AdminSDK Directory API limits] (https://developers.google.com/admin-sdk/directory/v1/limits). Each call to
create,selectandsuggestconsumes a different number of Directory API calls:create: 1 API callselect: 0 API callssuggest:cachedUsernames=YES): 0 API callscachedUsernames=NO): number of API calls is equal or larger than thenumberOfSuggestionspropertyConfiguration properties
The configuration is set in the
config.propertiesfile. Configuration properties are divided in four categories:accounts.UsernameGeneration.apis.GoogleAPIs.db.h2.security.ssl.Username generation properties
accounts.UsernameGeneration.cachedUsernamesDescription: A username cache can be used to check if a username already exists. This prevents reaching AdminSDK API calls/day limit. If
cachedUsernamesis set toYESusername availability will be checked against the cache. If set toNOit will be checked against the Google Directory (using a Directory API call).Possible values:
YESandNOaccounts.UsernameGeneration.cacheExpirationHoursDescription: Defines the expiration time in hours of the usernames cache. After expiration, the application refreshes the username cache. For reference, refreshing an account with 1 million users takes approximately 35 minutes.
Possible values: Integers larger or equal to 1
Default:
24accounts.UsernameGeneration.numberOfSuggestionsDescription: The number of username suggestions to be returned for each call to
suggest.Possible values: Integer between 1 and 10 (inclusive)
Default:
3accounts.UsernameGeneration.suggestedUsernamesTimeoutDescription: The amount of time (in seconds) that suggested usernames will remain locked (unavailable to another client).
Possible values: Integer greater than 0.
Default:
120(2 minutes)accounts.UsernameGeneration.patternsDescription: A pattern is something that looks like
[firstname][lastname]. This pattern indicates the API that we want to generate a username with “the firstname followed by the lastname”. Now, if that username happens to be taken the API will need another pattern. Therefore, a list of multiple patterns is recommended. For example:This will first try to generate a username with “the firstname followed by the lastname” if that is taken then it will try to generate a username with “the lastname followed by the firstname”.
So far so good?
Great. Now, say we want to generate a username with “the nickname followed by the lastname” of a person. We’d simply do:
What’s
[nickname]you might ask?Well,
nicknameis a field that should be passed to thesuggestmethod. For example:This will generate the username
jonnybravo.NOTE:
nickname(or any custom field) for all users. Ifnicknameis not provided for a user the API will skip that pattern and move on to the next one.firstnameandlastnameare mandatory. Even if the pattern doesn’t make use of them.Taking the first char(acters) of a field
Now say that for someone named John Smith we’d like to generate a username
jsmith. We’d do it with the following pattern:C1 indicates that the API should take the first character of firstname. If we’d like to take the first two characters then we’d do:
This same method applies for custom fields. For example, if we wanted to split the first character of the
nicknamewe’d do:Adding a counter to a pattern
Now, say we have so many people named “John Smith” in a school district that we ran out of patterns. We could then define a pattern that adds a number at the end of the username:
[#] indicates that a number will be added to the username. For example:
johnsmith3. This numeric value will start at 1 and continue adding until a username is available.Note: The use of [#] should be the last resort as this counter can become hard to remember, e.g.
johnsmith3816. A list of multiple patterns without [#] is encouraged before using a pattern with [#].Adding separators to usernames
A common practice is to separate usernames with a period (.), an underscore (_) or a dash (-). These separators can be added to patterns. Example:
would generate the username
john.smithAdding a string to a pattern
Same as the separators, it is possible to add a static string to username suggestions. For example, the pattern:
would generate the username
smith_nycWhat if the API runs out of patterns?
The following pattern is used as the last resort:
[C9_firstname][C9_lastname][#]patternsexampleGiven the following user data map, customFields and patterns: ```json { "firstname": "Carlos", "lastname": "Álvarez", "region": "CA", "group": "5A" } ```
Then consecutive calls to the suggest method will return (in that order):
[firstname].[lastname][C1_firstname].[lastname][firstname][lastname]_[region][firstname][lastname]_[group][lastname]_nyc[firstname][lastname][#][firstname][lastname][#][firstname][lastname][#][firstname][lastname][#]Google API properties
Follow the steps in the Google Apps domain configuration guide to configure these properties.
apis.GoogleAPIs.domainDescription: The Google Apps domain
Example:
apis.GoogleAPIs.domain=yourdomain.comapis.GoogleAPIs.authUserDescription: Admin user who created the project in the Google Developer Console.
Example:
apis.GoogleAPIs.authUser=admin@yourdomain.comapis.GoogleAPIs.keyPathDescription: Path to the file that stores the Google private key. Can be generated following the steps in: https://cloud.google.com/storage/docs/authentication#service_accounts
Example:
apis.GoogleAPIs.keyPath=./service_account_key.p12apis.GoogleAPIs.serviceAccountEmailDescription: Internal user for server side applications. Can be generated following the steps in: https://cloud.google.com/storage/docs/authentication#service_accounts
Note: You should enable API scopes in the Google Admin Console. This scopes can be registered following the steps in: https://support.google.com/a/answer/162106?hl=en
The following scope to the service account should be added: https://www.googleapis.com/auth/admin.directory.user
Example:
apis.GoogleAPIs.serviceAccountEmail=1234567890123-abcdefghijklmnopqrstuvwxz01234567@developer.gserviceaccount.comapis.GoogleAPIs.appNameDescription: This value is the project name in the Google Developer Console. Can be obtained following the steps in: https://developers.google.com/console/help/new/#creatingdeletingprojects
Example:
apis.GoogleAPIs.appName=My projectCache location properties
db.h2.nameDescription: The name of the H2 database
.mv.dbfile.Default:
usernamesdb.h2.pathDescription: The path where the H2 database (
.mv.dbfile) will be created.Default:
./SSL properties
security.ssl.useSSLDescription: Enables HTTPS support over SSL.
Possible values:
YESandNODefault:
NOsecurity.ssl.keyStorePathDescription: The path where the KeyStore (
jksfile) is located. This can be generated executing:security.ssl.keyStorePasswordDescription: The KeyStore password. Password provided when the
jksfile was generated.security.ssl.keyManagerPasswordDescription: Commonly the same as
keyStorePassword. Can be different if it is not a self-generated certificate.Building
Requirements
Build steps
To generate a
appsProvisioning-0.0.1.jarfile under ./target:From bash
From the project’s root folder, run:
From Eclipse
clean installFeedback
If you have any questions or feedback, please let us know in the forum!
Impressions
This API logs the number of calls to
suggest,createandselectper Google Apps domain. No other information is ever collected. This helps us justify adding more resources and support to this API.License
Account provisioning for Google Apps is licensed under Apache 2.0. Full license text is available in the LICENSE file.
This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.
Contributing
See CONTRIBUTING.
A good starting point to look at the Java code is
you can navigate through each of the methods:
suggest,selectandcreate.