[pve-devel] r4979 - pve-access-control/trunk

svn-commits at proxmox.com svn-commits at proxmox.com
Thu Aug 12 13:34:59 CEST 2010


Author: dietmar
Date: 2010-08-12 11:34:59 +0000 (Thu, 12 Aug 2010)
New Revision: 4979

Added:
   pve-access-control/trunk/User.pm
Modified:
   pve-access-control/trunk/AccessControl.pm
   pve-access-control/trunk/ChangeLog
   pve-access-control/trunk/Makefile
   pve-access-control/trunk/pveum
Log:
use new RESTHandler


Modified: pve-access-control/trunk/AccessControl.pm
===================================================================
--- pve-access-control/trunk/AccessControl.pm	2010-08-12 11:28:19 UTC (rev 4978)
+++ pve-access-control/trunk/AccessControl.pm	2010-08-12 11:34:59 UTC (rev 4979)
@@ -10,6 +10,7 @@
 use Net::LDAP;
 use PVE::Tools qw(run_command lock_file file_get_contents);
 use PVE::INotify qw(read_file write_file);
+use PVE::JSONSchema;
 
 use Data::Dumper; # fixme: remove
 
@@ -337,98 +338,6 @@
     return secure_exec($ticket, 'create_ticket', [ @param ]);
 }
 
-sub modify_user {
-
-    my ($username, $opts) = @_;
-
-    lock_user_config(sub {
-    
-	my $domain;
-
-	($username, undef, $domain) = verify_username($username);
-	
-	my $usercfg = read_file($userconfigpath);
-
-	if ($opts->{create}) {
-
-	    die "user '$username' already exists\n" 
-		if $usercfg->{users}->{$username};
-	
-	    warn "ignore password - can't set password on auth domain '$domain'\n" if $domain && $opts->{password};
-	    my $pass_plain = $opts->{password};
-
-	    store_shadow_password($username,$opts->{password}) if !$domain && $opts->{password};
-
-	    enable_user($username, $usercfg);
-
-	    if ($opts->{groups}) {
-		foreach my $group (split_list($opts->{groups})) {
-		    if ($usercfg->{groups}->{$group}) {
-			add_user_group($username, $usercfg, $group);
-		    } else {
-			warn "ignore group '$group' - no such group\n";
-			next;
-		    }
-		}
-	    }
-
-	} else {
-	    my $pw = $opts->{password};
-	    die "user '$username' does not exist\n" if !$usercfg->{users}->{$username};
-	    store_shadow_password($username,$opts->{password}) if !$domain && $opts->{password};
-	    enable_user($username, $usercfg) if $opts->{unlock} &&
-		!$usercfg->{users}->{$username}->{enabled};
-	    disable_user($username, $usercfg) if $opts->{lock} &&
-		$usercfg->{users}->{$username}->{enabled};
-	    delete_user_group($username, $usercfg) if (!$opts->{append} && $opts->{groups});
-	    if ($opts->{groups}) {
-		foreach my $group (split_list($opts->{groups})) {
-		    if ($usercfg->{groups}->{$group}) {
-			add_user_group($username, $usercfg, $group);
-		    } else {
-			warn "ignore group '$group' - no such group\n";
-			next;
-		    }
-		}
-	    }
-
-	    name_user($username, $usercfg) if $opts->{name};
-	    comment_user($username, $usercfg) if $opts->{comment};
-	}
-
-	write_file($userconfigpath, $usercfg);
-    });
-
-    my $err = $@;
-
-    die "modify user failed: $err" if $err;
-}
-
-sub delete_user {
-    
-    my ($username) = @_;
-    my $domain;
-    
-    lock_user_config(sub {
-
-	($username, undef, $domain) = verify_username($username);
-
-	my $usercfg =  read_file($userconfigpath);
-
-	delete ($usercfg->{users}->{$username})
-	    if $usercfg->{users}->{$username};
-	delete_shadow_password($username) if !$domain;
-	delete_user_group($username, $usercfg);
-	delete_user_acl($username, $usercfg);
-
-	write_file($userconfigpath, $usercfg);
-    });
-
-    my $err = $@;
-
-    die "delete user failed: $err" if $err;
-}
-
 sub delete_shadow_password {
 
     my ($username) = @_;

Modified: pve-access-control/trunk/ChangeLog
===================================================================
--- pve-access-control/trunk/ChangeLog	2010-08-12 11:28:19 UTC (rev 4978)
+++ pve-access-control/trunk/ChangeLog	2010-08-12 11:34:59 UTC (rev 4979)
@@ -1,3 +1,15 @@
+2010-08-12  Proxmox Support Team  <support at proxmox.com>
+
+	* pveum: use the new
+	RESTHandler (PVE::API2::User->cli_handler()). That way we have
+	automatic command line argument parsing.
+
+	* User.pm: use the new RESTHandler for API methods. Those methods
+	are automatically exposed with the API Server (pve-manager), and
+	we can use them in the command line tools.
+
+	* AccessControl.pm (modify_user, delete_user): moved to User.pm
+
 2010-08-10  Proxmox Support Team  <support at proxmox.com>
 
 	* control.in (Depends): depend on libpve-common-perl

Modified: pve-access-control/trunk/Makefile
===================================================================
--- pve-access-control/trunk/Makefile	2010-08-12 11:28:19 UTC (rev 4978)
+++ pve-access-control/trunk/Makefile	2010-08-12 11:34:59 UTC (rev 4979)
@@ -22,16 +22,17 @@
 dinstall: deb
 	dpkg -i ${DEB}
 
-install: pveum AccessControl.pm 
+install: pveum AccessControl.pm User.pm
 	install -d ${DESTDIR}${BINDIR}
 	install -d ${DESTDIR}${SBINDIR}
 	install -m 0755 pveum ${DESTDIR}${SBINDIR}
 	install -D -m 0644 AccessControl.pm ${DESTDIR}${PERLDIR}/PVE/AccessControl.pm
+	install -D -m 0644 User.pm ${DESTDIR}${PERLDIR}/PVE/API2/User.pm
 	install -d ${DESTDIR}/usr/share/man/man1
 	pod2man -n pveum -s 1 -r "proxmox 2.0" -c "Proxmox Documentation" <pveum | gzip -9 > ${DESTDIR}/usr/share/man/man1/pveum.1.gz
 
 .PHONY: deb
-deb ${DEB}: pveum AccessControl.pm control.in copyright changelog.Debian ChangeLog
+deb ${DEB}: pveum AccessControl.pm User.pm control.in copyright changelog.Debian ChangeLog
 	rm -rf debian
 	mkdir debian
 	make DESTDIR=debian install

Added: pve-access-control/trunk/User.pm
===================================================================
--- pve-access-control/trunk/User.pm	                        (rev 0)
+++ pve-access-control/trunk/User.pm	2010-08-12 11:34:59 UTC (rev 4979)
@@ -0,0 +1,283 @@
+package PVE::API2::User;
+
+use strict;
+use warnings;
+use PVE::INotify qw (read_file write_file);
+use PVE::AccessControl;
+
+use PVE::SafeSyslog;
+
+use Data::Dumper; # fixme: remove
+
+use PVE::RESTHandler;
+
+use base qw(PVE::RESTHandler);
+
+# fixme: index should return more/all attributes?
+__PACKAGE__->register_method ({
+    name => 'index', 
+    path => '', 
+    method => 'GET',
+    description => "User index.",
+    parameters => {
+	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		id => { type => 'string' },
+	    },
+	},
+	links => [ { rel => 'child', href => "{id}" } ],
+    },
+    code => sub {
+	my ($conn, $resp, $param) = @_;
+    
+	my $res = [];
+
+	my $usercfg = read_file("usercfg");
+ 
+	foreach my $user (keys %{$usercfg->{users}}) {
+	    next if $user eq 'root';
+
+	    push @$res, { id => $user };
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'create_ticket', 
+    path => '{userid}/ticket', 
+    method => 'POST',
+    description => "Create authentication ticket.",
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    userid => { type => 'string' },
+	    password => { type => 'string' },
+	}
+    },
+    returns => { type => 'string' },
+    code => sub {
+	my ($conn, $resp, $param) = @_;
+    
+	my $user = PVE::AccessControl::authenticate_user($param->{userid}, $param->{password});
+	my $ticket = PVE::AccessControl::assemble_ticket($user);
+
+	return $ticket;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'create_user', 
+    protected => 1,
+    path => '{userid}', 
+    method => 'POST',
+    description => "Create new user.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    userid => { type => 'string' },
+	    password => { type => 'string', optional => 1 },
+	    groups => { type => 'string', optional => 1 },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($conn, $resp, $param) = @_;
+
+	PVE::AccessControl::lock_user_config(
+	    sub {
+			
+		my ($username, undef, $domain) = 
+		    PVE::AccessControl::verify_username($param->{userid});
+	
+		my $usercfg = read_file("usercfg");
+
+		die "user '$username' already exists\n" 
+		    if $usercfg->{users}->{$username};
+			 
+		# fixme: how should we handle that?
+		warn "ignore password - can't set password on auth domain '$domain'\n" 
+		    if $domain && $param->{password};
+		
+		if ($param->{password}) {
+		    if ($domain) {
+			die "can't set password on auth domain '$domain'\n";
+		    } else {
+			PVE::AccessControl::store_shadow_password($username, $param->{password});
+		    }
+		}
+
+		PVE::AccessControl::enable_user($username, $usercfg);
+
+		if ($param->{groups}) {
+		    foreach my $group (split_list($param->{groups})) {
+			if ($usercfg->{groups}->{$group}) {
+			    PVE::AccessControl::add_user_group($username, $usercfg, $group);
+			} else {
+			    warn "ignore group '$group' - no such group\n";
+			    next;
+			}
+		    }
+		}
+
+		write_file("usercfg", $usercfg);
+	    });
+
+	my $err = $@;
+
+	die "create user failed: $err" if $err;
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'read_user', 
+    path => '{userid}', 
+    method => 'GET',
+    description => "Get user configuration.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    userid => { type => 'string' },
+	},
+    },
+    returns => {},
+    code => sub {
+	my ($conn, $resp, $param) = @_;
+
+	my $usercfg = read_file("usercfg");
+ 
+	my $data = $usercfg->{users}->{$param->{userid}};
+	die "no such user\n" if !$data;
+
+	return $data;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'update_user', 
+    protected => 1,
+    path => '{userid}', 
+    method => 'PUT',
+    description => "Update user configuration.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    userid => { type => 'string' },
+	    password => { type => 'string', optional => 1 },
+	    groups => { type => 'string', optional => 1 },
+	    append => { 
+		type => 'boolean', 
+		optional => 1,
+		requires => 'groups',
+	    },
+	    lock => { type => 'boolean', optional => 1 },
+	    unlock => { type => 'boolean', optional => 1 },
+	    name => { type => 'string', optional => 1 },
+	    comment => { type => 'string', optional => 1 },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($conn, $resp, $param) = @_;
+	
+	die "conflicting parameters unlock/lock\n" 
+	    if $param->{unlock} && $param->{lock};
+
+	PVE::AccessControl::lock_user_config(
+	    sub {
+			
+		my ($username, undef, $domain) = 
+		    PVE::AccessControl::verify_username($param->{userid});
+	
+		my $usercfg = read_file("usercfg");
+
+		die "user '$username' does not exist\n" 
+		    if !$usercfg->{users}->{$username};
+
+		if ($param->{password}) {
+		    if ($domain) {
+			die "can't set password on auth domain '$domain'\n";
+		    } else {
+			PVE::AccessControl::store_shadow_password($username, $param->{password});
+		    }
+		}
+
+		PVE::AccessControl::enable_user($username, $usercfg) if $param->{unlock};
+
+		PVE::AccessControl::disable_user($username, $usercfg) if $param->{lock};
+
+		PVE::AccessControl::delete_user_group($username, $usercfg) 
+		    if (!$param->{append} && $param->{groups});
+
+		if ($param->{groups}) {
+		    foreach my $group (split_list($param->{groups})) {
+			if ($usercfg->{groups}->{$group}) {
+			    PVE::AccessControl::add_user_group($username, $usercfg, $group);
+			} else {
+			    warn "ignore group '$group' - no such group\n";
+			    next;
+			}
+		    }
+		}
+
+		PVE::AccessControl::name_user($username, $usercfg) if $param->{name};
+
+		PVE::AccessControl::comment_user($username, $usercfg) if $param->{comment};
+
+		write_file("usercfg", $usercfg);
+	    });
+
+	my $err = $@;
+	
+	die "update user failed: $err" if $err;
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'delete_user', 
+    protected => 1,
+    path => '{userid}', 
+    method => 'DELETE',
+    description => "Delete user.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    userid => { type => 'string' },
+	}
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($conn, $resp, $param) = @_;
+
+	PVE::AccessControl::lock_user_config(
+	    sub {
+
+		my ($username, undef, $domain) = 
+		    PVE::AccessControl::verify_username($param->{userid});
+
+		my $usercfg = read_file("usercfg");
+
+		delete ($usercfg->{users}->{$username})
+		    if $usercfg->{users}->{$username};
+
+		PVE::AccessControl::delete_shadow_password($username) if !$domain;
+		PVE::AccessControl::delete_user_group($username, $usercfg);
+		PVE::AccessControl::delete_user_acl($username, $usercfg);
+
+		write_file("usercfg", $usercfg);
+	    });
+
+	my $err = $@;
+
+	die "delete user failed: $err" if $err;
+	
+	return undef;
+    }});
+
+1;

Modified: pve-access-control/trunk/pveum
===================================================================
--- pve-access-control/trunk/pveum	2010-08-12 11:28:19 UTC (rev 4978)
+++ pve-access-control/trunk/pveum	2010-08-12 11:34:59 UTC (rev 4979)
@@ -6,10 +6,11 @@
 use PVE::AccessControl;
 use File::Path qw(make_path remove_tree);
 use Term::ReadLine;
-use Data::Dumper; # fixme: remove
-use Time::HiRes qw( usleep ualarm gettimeofday tv_interval ); # fixme: remove
 use PVE::INotify;
+use PVE::API2::User;
 
+use Data::Dumper; # fixme: remove
+
 $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
 
 #fixme: logging?
@@ -47,7 +48,7 @@
     exit (-1);
 }
 
-sub read_password {
+my $read_password = sub {
 
     my $term = new Term::ReadLine ('pveum');
     my $attribs = $term->Attribs;
@@ -56,7 +57,7 @@
     my $conf = $term->readline('Retype new password: ');
     die "Passwords do not match.\n" if ($input ne $conf);
     return $input;
-}
+};
 
 my $cmd = shift;
 
@@ -64,63 +65,33 @@
 
     my $username = shift;
 
-    die "no username specified\n" if !$username;
-
-    my $passwd = read_password();
-	
-    my $user = PVE::AccessControl::authenticate_user($username, $passwd);
-    my $ticket = PVE::AccessControl::assemble_ticket($user);
-
+    my $ticket = PVE::API2::User->cli_handler('create_ticket', \@ARGV, { userid => $username }, $read_password);
     print "$ticket\n";
 
     exit (0);
 
 } elsif ($cmd eq 'useradd') {
 
-    my $opts = {};
-
-    if (!GetOptions ($opts, 'groups=s', 'password')) {
-        exit (-1);
-    }
-
     my $username = shift;
 
-    die "no username specified\n" if !$username;
+    PVE::API2::User->cli_handler('create_user', \@ARGV, { userid => $username }, $read_password);
 
-    $opts->{password} = read_password() if $opts->{password};
-    $opts->{create} = 1;
-    PVE::AccessControl::modify_user($username, $opts);
-
     exit(0);
 
 } elsif ($cmd eq 'usermod') {
 
-    my $opts = {};
-
-    if (!GetOptions ($opts, 'append', 'groups=s', 'unlock', 'lock', 'password', 'name=s', 'comment=s')) {
-        exit (-1);
-    }
-
-    die "wrong number of arguments\n" if scalar (@ARGV) != 1;
-
-    die "conflicting options unlock/lock\n" if $opts->{unlock} &&
-        $opts->{lock};
-
     my $username = shift;
-    $opts->{password} = read_password() if $opts->{password};
-    
-    PVE::AccessControl::modify_user($username, $opts);
 
+    PVE::API2::User->cli_handler('update_user', \@ARGV, { userid => $username }, $read_password);
+
     exit(0);
 
 } elsif ($cmd eq 'userdel') {
 
     my $username = shift;
 
-    die "no username specified\n" if !$username;
+    PVE::API2::User->cli_handler('delete_user', \@ARGV, { userid => $username });
 
-    PVE::AccessControl::delete_user($username);
-
     exit(0);
 
 } elsif ($cmd eq 'groupadd') {



More information about the pve-devel mailing list