Skip to content

Instantly share code, notes, and snippets.

@gsainio
Created August 23, 2013 18:20
Show Gist options
  • Save gsainio/6322375 to your computer and use it in GitHub Desktop.
Save gsainio/6322375 to your computer and use it in GitHub Desktop.
Sample perl code to use service accounts and oauth2 with Google's Admin SDK API.
#!/usr/public/bin/perl -w
use strict;
use JSON;
use JSON::WebToken;
use LWP::UserAgent;
use HTML::Entities;
my $private_key_string = q[-----BEGIN PRIVATE KEY-----
PEM CONTENTS GO HERE
-----END PRIVATE KEY-----
];
my $time = time;
# https://developers.google.com/accounts/docs/OAuth2ServiceAccount
my $jwt = JSON::WebToken->encode({
# your service account id here
iss => 'XXXXXX@developer.gserviceaccount.com',
scope => 'https://www.googleapis.com/auth/admin.directory.user',
aud => 'https://accounts.google.com/o/oauth2/token',
exp => $time + 3600,
iat => $time,
# To access the google admin sdk with a service account
# the service account must act on behalf of an account
# that has admin privileges on the domain
# Otherwise the token will be returned but API calls
# will generate a 403
prn => 'admin@your-domain.com',
}, $private_key_string, 'RS256', {typ => 'JWT'}
);
# Now post it to google
my $ua = LWP::UserAgent->new();
my $response = $ua->post('https://accounts.google.com/o/oauth2/token',
{grant_type => encode_entities('urn:ietf:params:oauth:grant-type:jwt-bearer'),
assertion => $jwt});
unless($response->is_success()) {
die($response->code, "\n", $response->content, "\n");
}
my $data = decode_json($response->content);
# The token is added to the HTTP authentication header as a bearer
my $api_ua = LWP::UserAgent->new();
$api_ua->default_header(Authorization => 'Bearer ' . $data->{access_token});
# get the details for a user
my $api_response = $api_ua->get('https://www.googleapis.com/admin/directory/v1/users/' .encode_entities('user@your-domain.com'));
if($api_response->is_success) {
my $api_data = decode_json($api_response->content);
use Data::Dumper;
print Dumper($api_data);
} else {
print "Error:\n";
print "Code was ", $api_response->code, "\n";
print "Msg: ", $api_response->message, "\n";
print $api_response->content, "\n";
die;
}
@nneul
Copy link

nneul commented Oct 16, 2014

"your service account id here" - this is the client email address, NOT the client id. If using the json key, it's the "client_email" field.

@jjtoth
Copy link

jjtoth commented Apr 8, 2015

The URL to post to is now 'https://www.googleapis.com/oauth2/v3/token". (Which is in there twice -- probably better if it was in a variable.)

@ncronin1
Copy link

This is a very useful piece of code.
I’m a sporadic PERL user and have been attempting to use JSON::WebToken to update users in Google. All of the OAUTH set up works fine but my JSON payload never gets executed. I get a 200 OK status but not updates.

my $jwt = JSON::WebToken->encode({email => 'user053@tcd.ie',
ipWhitelisted => JSON::true
}, $private_key_string, 'RS256', {typ => 'JWT'});

my $service_url = 'https://www.googleapis.com/admin/directory/v1/users/user0532@tcd.ie';

my $req = new HTTP::Request('PATCH',$service_url);
$req-> content($jwt);

my $api_response = $api_ua->request($req);

print "result: \n" . $api_response->status_line . "\n";

Also it’s unclear how I would code nested JSON e.g.

my $jwt = JSON::WebToken->encode({email => 'user053@tcd.ie',
ipWhitelisted => JSON::true,
name => {familyName => ‘blah’, givenName => ‘blah’},
}, $private_key_string, 'RS256', {typ => 'JWT'});

It’s probably my lack of PERL knowledge but any help would be appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment