Provisioning API: scripting password changes, and password strength assessment

138 views
Skip to first unread message

Max Noel

unread,
Jan 17, 2012, 4:23:29 PM1/17/12
to google-app...@googlegroups.com

Hi,

I'm currently working on an internal web application (and a script or two) to allow our employees to change their password for both Google Apps and our own internal services (which rely on LDAP for authentication -- so each user has one common password across everything). The user will choose their new password from this web app, and the app will, in turn, change the password in Google Apps and other services.

Now, to do that on the GApps side, we're looking at using the user provisioning API (if there's a better way we're not aware of, don't hesitate to tell me). However, we're running into the following problems:

  • Using 2-legged OAuth with the domain's consumer key (http://code.google.com/apis/gdata/docs/auth/oauth.html#2LeggedOAuth), I can read, but not change, user data. http://support.google.com/a/bin/answer.py?hl=en&answer=162105 does indeed give the https://apps-apis.google.com/a/feeds/user/#readonly scope for read-only user data access (which works fine), but nothing for read/write access (removing the #readonly doesn't work). Is read-write user data access at all possible with 2-legged OAuth, and if so, how?
  • Assuming 2-legged OAuth isn't possible, our fallback is to use ClientLogin and create a special user with a very specific set of admin privileges: that is, change the passwords of other, non-admin, users (we've found that using ClientLogin, we can't use a normal user's credentials to change that user's own password). However, using the control panel's "Organization & Users  > Privileges" screen, the only way of allowing a user (user_a) to change (not reset, force to a specific value) another user's (user_b's) password is to grant user_a super-admin privileges. Which, as you can imagine, we're fairly reluctant to do for a user whose credentials will be used by automated scripts. Is there another way?
  • http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#AuthProcess mentions that ClientLogin may respond with a CAPTCHA challenge. Under which conditions does it do that?
  • Testing shows that the gdata.apps.client.AppsClient.UpdateUser method rejects passwords that are considered too weak (e.g. "aaa") with error code 1402 (InvalidPassword). Is there an API somewhere that allows us to determine whether a password is strong enough without attempting to change it?
Thanks for your attention,

-- Max

Shraddha Gupta

unread,
Jan 18, 2012, 7:07:43 AM1/18/12
to google-app...@googlegroups.com
Hello Max,

You are right that User Provisioning API is used to update the password for the users in the Google Apps domain.

Lets go through your problems one by one:
  • Only read access is possible by 2-legged OAuth in the Provisioning API.
  • You don't need to use ClientLogin. Infact, we recommend not to use ClientLogin. 
          Please use 3-legged OAuth with the Provisioning API. But then you will require to get the new passwords and save them before you run a script to update passwords from your end.
          As 3-legged OAuth requires the admin to authorize the request, the script must be executed by the admin as it requires admin to be logged in.

         The other way that you can implement this application is by using the Apps Script.
         You can get the passwords for users in a spreadsheet and associate a script with it. The script will take entries from the spreadsheet and update the passwords for all users listed.
         You can refer the Apps Script documentation for Domain Services. This blog post explains how you can use the Domain service with Apps Script.
  • CAPTCHA challenge usually occurs in ClientLogin if you authorize the service multiple times. Authorize the service just once and use the authorized service in all your methods.
  • The passwords must be a minimum of 8 characters in length and maximum 100. The Limits section of the Provisioning API Developers Guide lists these limits. In your application, you can add a precondition for the passwords entered and only accept the correct length passwords.
We recommend the use of 3-legged authorization for your application. Feel free to post again for any other queries.

Thank you,
Shraddha Gupta
Developer Programs Engineer
Hyderabad, Google India.



--
You received this message because you are subscribed to the Google Groups "Google Apps Domain Information and Management APIs" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-apps-mgmt-apis/-/zalim9blG6EJ.
To post to this group, send email to google-app...@googlegroups.com.
To unsubscribe from this group, send email to google-apps-mgmt...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-apps-mgmt-apis?hl=en.

Max Noel

unread,
Jan 18, 2012, 10:57:29 AM1/18/12
to google-app...@googlegroups.com
On Wednesday, January 18, 2012 7:07:43 AM UTC-5, Shraddha Gupta wrote:
Hello Max,

You are right that User Provisioning API is used to update the password for the users in the Google Apps domain.

Lets go through your problems one by one:
  • Only read access is possible by 2-legged OAuth in the Provisioning API.
  • You don't need to use ClientLogin. Infact, we recommend not to use ClientLogin. 
          Please use 3-legged OAuth with the Provisioning API. But then you will require to get the new passwords and save them before you run a script to update passwords from your end.
          As 3-legged OAuth requires the admin to authorize the request, the script must be executed by the admin as it requires admin to be logged in.


I see. However, http://code.google.com/apis/gdata/docs/auth/oauth.html#Examples says that "To authorize a request token, your application must redirect the user to the OAuthAuthorizeToken URL, which prompts them to log into their Google account." (the user being, in this case, an admin -- right?).

I see two issues with this:
  • How do I do that when the program that's running is not a webapp, but a barely interactive script?
  • On the webapp side, it's not an admin performing the password change operation. It's the users themselves, without admins being involved -- it's a simple "change my password" link. Wouldn't three-legged OAuth require them to sign in to an admin's account in order to perform the change? Or is there something I don't understand properly?

 
  • CAPTCHA challenge usually occurs in ClientLogin if you authorize the service multiple times. Authorize the service just once and use the authorized service in all your methods.
  • The passwords must be a minimum of 8 characters in length and maximum 100. The Limits section of the Provisioning API Developers Guide lists these limits. In your application, you can add a precondition for the passwords entered and only accept the correct length passwords.

Great, thanks!

-- Max 

Shraddha Gupta

unread,
Jan 18, 2012, 11:24:11 AM1/18/12
to google-app...@googlegroups.com
Hi Max,

In 3-legged OAuth user have to visit the authorization URL to grant access to the application and have to be logged in as admin.

When your application is an interactive script, then you can have the script to print the URL that you can visit and authorize. In this case redirection will not occur but you will manually paste the URL in your browser.

Refer to this sample in Python that uses OAuth 2.0 for a desktop application (not a web application). In this application, user is given the authorization URL to visit. This article explains steps for using OAuth with the Provisioning API.

As 3-legged authorization requires the admin to authorize, the users wont be able to authorize to change their passwords.
That is why, I recommended using Apps Script. You can get the new password from your application and save it in a Google Spreadsheet in the admin's account. If you have an Apps Script associated with spreadsheet, then you can trigger the script every time the content of spreadsheet changes so that script updates the password of the user.

If you dont want to go for Apps Script, then you can get the new passwords from the users and save them. Later run the script from your account to update the passwords. But this will not result in immediate change when the new password is given by the user to your application but will change when you run the script on the saved passwords from your end.

Thank you,
Shraddha Gupta
Developer Programs Engineer
Hyderabad, Google India.




-- Max 

--
You received this message because you are subscribed to the Google Groups "Google Apps Domain Information and Management APIs" group.

Max Noel

unread,
Jan 18, 2012, 12:47:34 PM1/18/12
to google-app...@googlegroups.com
On Wednesday, January 18, 2012 11:24:11 AM UTC-5, Shraddha Gupta wrote:
As 3-legged authorization requires the admin to authorize, the users wont be able to authorize to change their passwords.
That is why, I recommended using Apps Script. You can get the new password from your application and save it in a Google Spreadsheet in the admin's account. If you have an Apps Script associated with spreadsheet, then you can trigger the script every time the content of spreadsheet changes so that script updates the password of the user.


All right, I'll have a look at Apps Script -- that's probably what I'll go with in the end. Thanks for your advice.

A few questions, though:
  • Are the scripts' triggers run in an asynchronous or synchronous fashion? That is, is there a way of updating the spreadsheet then waiting until the trigger has been run (and finding the results thereof -- did any errors occur during the password change attempt at the UserManager level?) so that I may tell the user whether the password change was successful or not?
  • How long does an onEdit trigger take to be fired? Until all the processing is done, the user's new password is in plaintext in a spreadsheet and I'm not really comfortable with that.
  • All in all, Apps Scipt is a fairly awkward way of doing what I want. Is there a reason why 2-legged OAuth only has read-only access to the user DB? Are there any plans to give it read/write access?
-- Max

Max Noel

unread,
Jan 18, 2012, 4:51:45 PM1/18/12
to google-app...@googlegroups.com
Also, what privileges do I need to grant the user the Apps Script is running as, in order to allow usage of the UserManager class? In my preliminary tests, all calls to this class (from an onEdit trigger) fail with "Authorization is required to perform that action."

-- Max

David Haley

unread,
Jan 18, 2012, 8:11:53 PM1/18/12
to google-app...@googlegroups.com

Hi Max,

Try running the script from the script editor directly just once - it will prompt you for that authorization which will be reused when run from the trigger.

Cheers,
David Haley | Google Enterprise | Sales Engineer
Sent from my Android phone

On Jan 18, 2012 1:51 PM, "Max Noel" <maxf...@gmail.com> wrote:
Also, what privileges do I need to grant the user the Apps Script is running as, in order to allow usage of the UserManager class? In my preliminary tests, all calls to this class (from an onEdit trigger) fail with "Authorization is required to perform that action."

-- Max

--
You received this message because you are subscribed to the Google Groups "Google Apps Domain Information and Management APIs" group.

Shraddha Gupta

unread,
Jan 19, 2012, 4:25:59 AM1/19/12
to google-app...@googlegroups.com
Hello Max,

The scripts trigger in an asynchronous way. 
You can add code in your script to update a field in spreadsheet on success of the request.
Also, on success you can remove the saved password from your spreadsheet and inform the user that his password is updated.

onEdit trigger is fired immediately, so you have to wait only for the time taken to complete the operation. You can save the password in some encrypted form in your spreadsheet and  decode it in the script itself.

There are no plans for now to give read/write access with 2-legged OAuth for the Provisioning API. This is for the better security of the domain data.

The script fails to run due to lack of authorization.
You require to authorize first by running the script from the script editor as David said. After authorization, the script will trigger itself.

Thank you,
Shraddha Gupta
Developer Programs Engineer
Hyderabad, Google India.



Max Noel

unread,
Jan 19, 2012, 10:06:48 AM1/19/12
to google-app...@googlegroups.com
All right, it works now. Thank you guys. One final question: is there a way to interactively debug, or at least capture the logging output of, script functions run from triggers (e.g. onEdit)?

Simply running onEdit from the script editor isn't possible, because the "event" argument is undefined in that case (unless I missed something?). I'm hoping there's a better way than attempting a few appendRows calls in the function and reading the e-mail reports when they error out, because as you can imagine it's fairly inefficient and uncomfortable.

-- Max

Shraddha Gupta

unread,
Jan 19, 2012, 10:42:50 AM1/19/12
to Jagot, google-app...@googlegroups.com
Hi Jagot,

It is possible to get the refresh token and use it to get an access token.
When working on GData APIs this is true for a single run of application.
If the application is running for a long time, such that the access token expires in between, then you can refresh your access token.

For the new APIs, it is possible to once authorize and save the refresh token for subsequent runs.

Workaround for working on GData libraries with the refresh token can be:
You may get the OAuth 2.0 token using the new library and save the refresh token. The new library provides the support for saving the token.
Then you can use this token with the GData client library.
Refer this sample that uses the two libraries together.

Shraddha Gupta
Developer Programs Engineer
Hyderabad, Google India.



On Thu, Jan 19, 2012 at 8:10 PM, Jagot <bi...@bluejaguar.co.za> wrote:
Shraddha,

Can you not use the 3-legged OAuth with an admin user and save the
refresh token. When a user then comes back, you can use the refresh
token to get an access token and continue to change the password. Is
this possible?

Shraddha Gupta

unread,
Jan 19, 2012, 11:40:36 AM1/19/12
to google-app...@googlegroups.com
Hello Max,

There is a step-by-step debugger in Script Editor. It can be used interactively.

You can logging output, the best option would be to just create a plain text file and append text to it inside the function that is ran on the trigger.
You can do that in combination with Logger.getLog().

Thank you,
Shraddha Gupta
Developer Programs Engineer
Hyderabad, Google India.




-- Max

--
You received this message because you are subscribed to the Google Groups "Google Apps Domain Information and Management APIs" group.

Max Noel

unread,
Jan 19, 2012, 4:59:47 PM1/19/12
to google-app...@googlegroups.com
On Thursday, January 19, 2012 11:40:36 AM UTC-5, Shraddha Gupta wrote:
Hello Max,

There is a step-by-step debugger in Script Editor. It can be used interactively.

You can logging output, the best option would be to just create a plain text file and append text to it inside the function that is ran on the trigger.
You can do that in combination with Logger.getLog().


Yeah, but that only works when I'm launching the function myself from the script editor (by clicking the "debug" button)... What about when my function is called by the onEdit trigger?

Also, right now I'm running into another problem where it appears that programatically adding lines to the spreadsheet (via the gdata.spreadsheets.client.SpreadsheetsClient.add_list_entry method in the Python API) does not fire the onEdit trigger. The changes I make manually in the spreadsheet app correctly trigger it, but when the modifications are done by my Python program, I can see my changes appearing but the onEdit function isn't called.

Do you know what might be causing that problem, and if so, how it can be solved?

-- Max

Shraddha Gupta

unread,
Jan 20, 2012, 1:58:53 AM1/20/12
to google-app...@googlegroups.com
Hello Max,

Please post your queries on Apps Script forum for Apps Script issues to get the best possible solutions.
Sorry for the inconvenience.

Thank you,
Shraddha Gupta
Developer Programs Engineer
Hyderabad, Google India.




-- Max

--
You received this message because you are subscribed to the Google Groups "Google Apps Domain Information and Management APIs" group.
Reply all
Reply to author
Forward
0 new messages