[vuser] r582 committed - Add support for updating users and changing user passwords.

0 views
Skip to first unread message

codesite...@google.com

unread,
Nov 28, 2009, 11:24:30 PM11/28/09
to vuser-...@googlegroups.com
Revision: 582
Author: perlstalker
Date: Sat Nov 28 20:23:58 2009
Log: Add support for updating users and changing user passwords.

http://code.google.com/p/vuser/source/detail?r=582

Modified:
/VUser-Google-ProvisioningAPI/trunk/lib/VUser/Google/Provisioning/V2_0.pm

/VUser-Google-ProvisioningAPI/trunk/lib/VUser/Google/ProvisioningAPI/V2_0/UserEntry.pm
/VUser-Google-ProvisioningAPI/trunk/t/tests/My/Test/Class.pm

/VUser-Google-ProvisioningAPI/trunk/t/tests/Test/VUser/Google/Provisioning/V2_0.pm

=======================================
---
/VUser-Google-ProvisioningAPI/trunk/lib/VUser/Google/Provisioning/V2_0.pm
Fri Nov 27 22:27:35 2009
+++
/VUser-Google-ProvisioningAPI/trunk/lib/VUser/Google/Provisioning/V2_0.pm
Sat Nov 28 20:23:58 2009
@@ -191,7 +191,94 @@
return @entries;
}

+# %options
+# userName*
+# givenName
+# familyName
+# password
+# hashFunctioName (SHA-1|MD5)
+# suspended (bool)
+# quota (in MB)
+# changePasswordAtNextLogin (bool)
sub UpdateUser {
+ my $self = shift;
+
+ my %options = ();
+
+ if (ref $_[0]
+ and $_[0]->isa('VUser::Google::Provisioning::UserEntry')) {
+ %options = $_[0]->as_hash;
+ }
+ else {
+ %options = @_;
+ }
+
+ die "Can't update user: userName not set\n" unless
$options{'userName'};
+
+ my $url = $self->base_url.$self->google->domain
+ ."/user/2.0/$options{userName}";
+
+ my $post = '<?xml version="1.0" encoding="UTF-8"?>
+<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:apps="http://schemas.google.com/apps/2006">
+ <atom:category scheme="http://schemas.google.com/g/2005#kind"
+ term="http://schemas.google.com/apps/2006#user"/>
+';
+
+ ## update user info (login tag)
+ if ($options{password}
+ or defined $options{suspended}
+ or defined $options{changePasswordAtNextLogin}
+ ) {
+ $post .= '<apps:login';
+
+ if (defined $options{password}) {
+ $post .= ' password="';
+ $post .= $self->_escape_quotes($options{'password'});
+ $post .= '"';
+
+ if (defined $options{hashFunctionName}) {
+ $post .= ' hashFunctionName="';
+ $post .= $options{hashFunctionName};
+ $post .= '"';
+ }
+ }
+
+ if (defined $options{suspended}) {
+ $post .= ' suspended="'.$self->_as_bool($options{suspended}).'"';
+ }
+
+ if (defined $options{changePasswordAtNextLogin}) {
+ $post .= ' changePasswordAtNextLogin="'
+ .$self->_as_bool($options{changePasswordAtNextLogin}).'"';
+ }
+
+ $post .= '/>';
+ }
+
+ ## Quota
+ if ($options{quota}) {
+ $post .= "<apps:quota limit=\"$options{quota}\"/>";
+ }
+
+ ## Name
+ if ($options{givenName} or $options{familyName}) {
+ $post .= '<apps:name';
+ $post .= " familyName=\"$options{familyName}\"" if $options{familyName};
+ $post .= " givenName=\"$options{givenName}\"" if $options{givenName};
+ $post .= '/>';
+ }
+
+ $post .= '</atom:entry>';
+
+ if ($self->google->Request('PUT', $url, $post)) {
+ $self->dprint('Updated user');
+ my $entry = $self->_build_user_entry($self->google->result);
+ return $entry;
+ }
+ else {
+ die "Error updating user: ".$self->google->result->{'reason'}."\n";
+ }
}

sub RenameUser {
@@ -219,6 +306,22 @@
}

sub ChangePassword {
+ my $self = shift;
+ my $username = shift;
+ my $password = shift;
+ my $hash_function = shift;
+
+ if (not $username or not $password) {
+ die "Can't change password: username or password not set.\n";
+ }
+
+ my $entry = $self->UpdateUser(
+ userName => $username,
+ password => $password,
+ hashFunctionName => $hash_function,
+ );
+
+ return $entry;
}

## Nicknames
=======================================
---
/VUser-Google-ProvisioningAPI/trunk/lib/VUser/Google/ProvisioningAPI/V2_0/UserEntry.pm
Sat Nov 28 08:13:08 2009
+++
/VUser-Google-ProvisioningAPI/trunk/lib/VUser/Google/ProvisioningAPI/V2_0/UserEntry.pm
Sat Nov 28 20:23:58 2009
@@ -14,7 +14,7 @@


#LP: changePasswordAtNextLogin
- my ($user, $password, $family_name, $given_name, $quota, $email,
$isSuspended, $changePasswordAtNextLogin);
+ my ($user, $password, $family_name, $given_name, $quota, $email,
$isSuspended, $changePasswordAtNextLogin, $hashFunctionName);

if (defined $isSuspended) {
$isSuspended = ($isSuspended)? '1' : '0';
=======================================
--- /VUser-Google-ProvisioningAPI/trunk/t/tests/My/Test/Class.pm Fri Nov 27
22:27:35 2009
+++ /VUser-Google-ProvisioningAPI/trunk/t/tests/My/Test/Class.pm Sat Nov 28
20:23:58 2009
@@ -27,7 +27,7 @@
domain => $ENV{GAPPS_DOMAIN},
admin => $ENV{GAPPS_ADMIN},
password => $ENV{GAPPS_PASSWD},
- debug => 1
+# debug => 1
);

return $google;
=======================================
---
/VUser-Google-ProvisioningAPI/trunk/t/tests/Test/VUser/Google/Provisioning/V2_0.pm
Fri Nov 27 22:27:35 2009
+++
/VUser-Google-ProvisioningAPI/trunk/t/tests/Test/VUser/Google/Provisioning/V2_0.pm
Sat Nov 28 20:23:58 2009
@@ -66,50 +66,148 @@
my $api = $class->new(google => $test->create_google);

can_ok $api, 'RetrieveUsers';
-
can_ok $api, 'RetrieveAllUsers';

my $num_users = 110;

- ## Create 110 test users
- note "Creating $num_users test users. This will take a while.";
+ SKIP: {
+ print STDERR "\nRetrieve tests require that $num_users test users be
created and deleted.\n";
+ print STDERR "These tests can take a long time.\n";
+ print STDERR "Would you like to skip these tests? [y/N]: ";
+ my $response = <STDIN>;
+ skip "Skipping long tests at user request.", 3 if $response =~ /^y/i;
+
+ ## Create 110 test users
+ note "Creating $num_users test users. This will take a while.";
+ my $user = $test->get_test_user;
+ print STDERR "Creating test users: ";
+ foreach my $i (1 .. $num_users) {
+ print STDERR "." if $i%10 == 0;
+ my $res = $api->CreateUser(
+ userName => $user.".$i",
+ givenName => 'Test',
+ familyName => 'User',
+ password => 'testing',
+ quota => 2048,
+ changePasswordAtNextLogin => 1,
+ );
+ }
+ print "\n";
+
+ ## Fetch first page of users
+ my %results = $api->RetrieveUsers;
+ is @{ $results{'entries'} }, 100,
+ '... and we have 100 users';
+ my $next = $results{next};
+
+
+ ## Fetch second page of users
+ %results = $api->RetrieveUsers($next);
+ is $results{'entries'}[0]->UserName, $next,
+ '... and the first result of the second page is the "next" from the
first page';
+
+ ## Retrieve all users
+ my @entries = $api->RetrieveAllUsers;
+ TODO: {
+ local $TODO = 'How many users already existed?';
+ ok @entries >= $num_users+1,
+ '... and there are the expected number of users';
+ }
+
+ ## Delete test users
+ note "Deleting $num_users test users. This will also take a while.";
+ print STDERR "\nDeleting test users: ";
+ foreach my $i (1 .. $num_users) {
+ print STDERR "." if $i%10 == 0;
+ my $rc = $api->DeleteUser($user.".$i");
+ }
+ } # END SKIP
+}
+
+sub UpdateUser : Tests(7) {
+ my $test = shift;
+ my $class = $test->class;
+
+ my $api = $class->new(google => $test->create_google);
+
+ can_ok $api, 'UpdateUser';
+
my $user = $test->get_test_user;
- foreach my $i (1 .. $num_users) {
- my $res = $api->CreateUser(
- userName => $user.".$i",
- givenName => 'Test',
- familyName => 'User',
- password => 'testing',
- quota => 2048,
- changePasswordAtNextLogin => 1,
- );
- }
-
- ## Fetch first page of users
- my %results = $api->RetrieveUsers;
- is @{ $results{'entries'} }, 100,
- '... and we have 100 users';
- my $next = $results{next};
-
-
- ## Fetch second page of users
- %results = $api->RetrieveUsers($next);
- is $results{'entries'}[0]->UserName, $next,
- '... and the first result of the second page is the "next" from the first
page';
-
- ## Retrieve all users
- my @entries = $api->RetrieveAllUsers;
+
+ my $entry = $api->CreateUser(
+ userName => $user,
+ givenName => 'Test',
+ familyName => 'User',
+ password => 'testing',
+ quota => 2048,
+ changePasswordAtNextLogin => 1,
+ );
+
+ my $updated = $api->UpdateUser(
+ userName => $user,
+ givenName => 'GName'
+ );
+
+ is $updated->GivenName, 'GName',
+ '... and given name matches';
+
+ $updated = $api->UpdateUser(
+ userName => $user,
+ familyName => 'Fname',
+ );
+
+ is $updated->FamilyName, 'Fname',
+ '... and family name matches';
+
+ $updated = $api->UpdateUser(
+ userName => $user,
+ suspended => 1,
+ );
+
+ is $updated->Suspended, 1,
+ '... and suspended matches';
+
+ $updated = $api->UpdateUser(
+ userName => $user,
+ quota => 1024,
+ );
+
TODO: {
- local $TODO = 'How many users already existed?';
- ok @entries >= $num_users+1,
- '... and there are the expected number of users';
+ local $TODO = 'May not be allowed to change quotas.';
+ is $updated->Quota, 1024,
+ '... and quota matches';
}

- ## Delete test users
- note "Deleting $num_users test users. This will also take a while.";
- foreach my $i (1 .. $num_users) {
- my $rc = $api->DeleteUser($user.".$i");
- }
+ $updated = $api->UpdateUser(
+ userName => $user,
+ changePasswordAtNextLogin => 0,
+ );
+
+ is $updated->ChangePasswordAtNextLogin, 0,
+ '... and changePasswordAtNextLogin matches';
+
+ can_ok $api, 'ChangePassword';
+
+ TODO: {
+ local $TODO = 'How can we test if setting the password actually worked?';
+
+ # Use ClientLogin API to test Auth?
+ # http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
+
+ $updated = $api->ChangePassword(
+ $user, 'new-password',
+ );
+
+ $updated = $api->ChangePassword(
+ $user, 'd27117a019717502efe307d110f5eb3d', 'MD5'
+ );
+
+ $updated = $api->ChangePassword(
+ $user, '51eea05d46317fadd5cad6787a8f562be90b4446', 'SHA-1'
+ );
+ }
+
+ my $rc = $api->DeleteUser($user);
}

1;
Reply all
Reply to author
Forward
0 new messages