]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Add functions to view/add/del users and setup roles
authorEric Bollengier <eric@eb.homelinux.org>
Fri, 2 Nov 2007 17:13:50 +0000 (17:13 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Fri, 2 Nov 2007 17:13:50 +0000 (17:13 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5831 91ce42f0-d328-0410-95d8-f526ca767f89

gui/bweb/cgi/bweb.pl
gui/bweb/lang/es/tpl/begin.tpl
gui/bweb/lang/fr/tpl/begin.tpl
gui/bweb/lib/Bweb.pm
gui/bweb/script/tpl_extract_msg.pl
gui/bweb/tpl/begin.tpl
gui/bweb/tpl/display_user.tpl [new file with mode: 0644]
gui/bweb/tpl/display_users.tpl [new file with mode: 0644]

index 3b40b7aee58d9db8d331bb1cd1ca732a3cf813d3..fb30f197e5adf32c6580ba51c90d784c68990a53 100755 (executable)
@@ -92,6 +92,21 @@ if ($action eq 'begin') {            # main display
 } elsif ($action eq 'apply_conf') {
     $conf->modify();
 
+} elsif ($action eq 'user_del') {
+    $bweb->users_del();
+
+} elsif ($action eq 'user_add') {
+    $bweb->users_add();
+
+} elsif ($action eq 'user_edit') {
+    $bweb->display_user();
+
+} elsif ($action eq 'user_save') {
+    $bweb->users_add();
+
+} elsif ($action eq 'users') {
+    $bweb->display_users();
+
 } elsif ($action eq 'client') {        
     $bweb->display_clients();
 
index c9c8f6194ae9dd0d0f21023b2c8bfcc999471a35..a476204a29706ccd64e8482ae2e7dba023a4a1d2 100644 (file)
@@ -55,7 +55,13 @@ if (navigator.appName == 'Konqueror') {
  </li>
 </TMPL_IF> 
  <li><a href="bweb.pl?action=graph"> Estadísticas </a></li>
- <li> <a href="bweb.pl?action=view_conf"> Configuración </a> </li>
+ <li> <a href="bweb.pl?action=view_conf"> Configuración </a> 
+<TMPL_IF enable_security>
+  <ul> <li> <a href="bweb.pl?action=view_conf"> Configuration </a> 
+       <li> <a href="bweb.pl?action=users"> Manage users </a>
+  </ul>
+</TMPL_IF>
+</li>
  <li> <a href="bweb.pl?action=about"> Acerca </a> </li>
  <li style="padding: 0.25em 2em;float: right;">&nbsp;Usuario  <TMPL_VAR NAME=loginname> </li>
  <li style="float: right;white-space: nowrap;">
index f5bdb53c52a1591a7e73d3615a9730df5fd6675e..27d2e603dfa6bb041be04fc274fa34bb6f380afa 100644 (file)
@@ -55,7 +55,13 @@ if (navigator.appName == 'Konqueror') {
  </li>
 </TMPL_IF> 
  <li><a href="bweb.pl?action=graph"> Statistiques </a></li>
- <li> <a href="bweb.pl?action=view_conf"> Configuration </a> </li>
+ <li> <a href="bweb.pl?action=view_conf"> Configuration </a>
+<TMPL_IF enable_security>
+  <ul> <li> <a href="bweb.pl?action=view_conf"> Configuration </a> 
+       <li> <a href="bweb.pl?action=users"> Manage users </a>
+  </ul>
+</TMPL_IF>
+ </li>
  <li> <a href="bweb.pl?action=about"> A propos </a> </li>
  <li style="padding: 0.25em 2em;float: right;">&nbsp;Logged as <TMPL_VAR NAME=loginname> </li>
  <li style="float: right;white-space: nowrap;">
index 59d1084b8f8dd898223b50dd0b033112b62c06cd..9dc4a6d2a5716251a50eba5db8267b76d09f09f4 100644 (file)
@@ -1273,6 +1273,7 @@ sub new
        $self->{sql} = $sql_func{$1};
     }
 
+    $self->{loginname} = CGI::remote_user();
     $self->{debug} = $self->{info}->{debug};
     $Bweb::Gui::template_dir = $self->{info}->{template_dir};
 
@@ -1551,6 +1552,28 @@ SELECT client_group_name AS name
                                  values %$grps] ;
     }
 
+    if ($what{db_usernames}) {
+       my $query = "
+SELECT username 
+  FROM bweb_user
+";
+
+       my $users = $self->dbh_selectall_hashref($query, 'username');
+       $ret{db_usernames} = [sort {$a->{username} cmp $b->{username} } 
+                                 values %$users] ;
+    }
+
+    if ($what{db_roles}) {
+       my $query = "
+SELECT rolename 
+  FROM bweb_role
+";
+
+       my $r = $self->dbh_selectall_hashref($query, 'rolename');
+       $ret{db_roles} = [sort {$a->{rolename} cmp $b->{rolename} } 
+                                 values %$r] ;
+    }
+
     if ($what{db_mediatypes}) {
        my $query = "
 SELECT MediaType as mediatype
@@ -2001,6 +2024,13 @@ sub get_param
        }
     }
 
+    # fill this only when security is enabled
+    if ($elt{username} and $self->{info}->{enable_security}) {
+        my $u = $self->dbh_quote($self->{loginname});
+        $ret{username}=$self->{loginname};
+        $limit .= "AND bweb_user.username = $u ";
+    }
+
     return ($limit, %ret);
 }
 
@@ -2633,6 +2663,245 @@ sub display_groups
                   "display_groups.tpl");
 }
 
+###########################################################
+
+
+# TODO: avoir un mode qui coupe le programme avec une page d'erreur
+# we can also get all security and fill {security} hash
+sub can_do
+{
+    my ($self, $action) = @_;
+    # is security enabled in configuration ?
+    if (not $self->{info}->{enable_security}) {
+        return 1;
+    }
+    # admin is a special user that can do everything
+    if ($self->{loginname} eq 'admin') {
+        return 1;
+    }
+    # must be logged
+    if (!$self->{loginname}) {
+        $self->error("Can't do $action, your are not logged. " .
+                     "Check security with your administrator");
+        $self->display_end();
+        exit (0);
+    }
+    # already checked
+    if ($self->{security}->{$action}) {
+        return 1;
+    }
+    my ($u, $r) = ($self->dbh_quote($self->{loginname}),
+                   $self->dbh_quote($action));
+    my $query = "
+ SELECT 1, username, rolename
+  FROM bweb_user 
+       JOIN bweb_role_member USING (userid)
+       JOIN bweb_role USING (roleid)
+ WHERE username = $u
+   AND rolename = $r
+";
+
+    my $row = $self->dbh_selectrow_hashref($query);
+    # do cache with this role   
+    if (!$row) {
+        $self->error("$u sorry, but this action ($action) is not permited. " .
+                     "Check security with your administrator");
+        $self->display_end();
+        exit (0);
+    } 
+    $self->{security}->{$row->{rolename}} = 1;    
+    return 1;
+}
+# role and username have to be quoted before
+# role and username can be a quoted list
+sub revoke
+{
+    my ($self, $role, $username) = @_;
+    $self->can_do("user_mgnt");
+    
+    my $nb = $self->dbh_do("
+ DELETE FROM bweb_role_member 
+       WHERE roleid = (SELECT roleid FROM bweb_role
+                        WHERE rolename IN ($role))
+         AND userid = (SELECT userid FROM bweb_user
+                        WHERE username IN ($username))");
+    return $nb;
+}
+
+# role and username have to be quoted before
+# role and username can be a quoted list
+sub grant
+{
+    my ($self, $role, $username) = @_;
+    $self->can_do("user_mgnt");
+
+    my $nb = $self->dbh_do("
+   INSERT INTO bweb_role_member (roleid, userid)
+     SELECT roleid, userid FROM bweb_role, bweb_user 
+       WHERE rolename IN ($role)
+         AND username IN ($username)
+     ");
+    return $nb;
+}
+
+# role and username have to be quoted before
+# role and username can be a quoted list
+sub grant_like
+{
+    my ($self, $copy, $user) = @_;
+    $self->can_do("user_mgnt");
+
+    my $nb = $self->dbh_do("
+  INSERT INTO bweb_role_member (roleid, userid) 
+       SELECT roleid, a.userid FROM bweb_user AS a, bweb_role_member JOIN bweb_user USING (userid)
+        WHERE bweb_user.username = $copy
+          AND a.username = $user");
+    return $nb;
+}
+
+# username can be a join quoted list of usernames
+sub revoke_all
+{
+    my ($self, $username) = @_;
+    $self->can_do("user_mgnt");
+
+    $self->dbh_do("
+   DELETE FROM bweb_role_member
+         WHERE userid IN (
+               SELECT userid 
+                 FROM bweb_user 
+                WHERE username in ($username)
+)");
+}
+
+sub users_del
+{
+    my ($self) = @_;
+    $self->can_do("user_mgnt");
+
+    my $arg = $self->get_form(qw/jusernames/);
+
+    unless ($arg->{jusernames}) {
+        return $self->error("Can't get user");
+    }
+
+    $self->{dbh}->begin_work();
+    {
+        $self->revoke_all($arg->{jusernames});
+        $self->dbh_do("DELETE FROM bweb_user WHERE username IN ($arg->{jusernames})");
+    }
+    $self->{dbh}->commit();
+    
+    $self->display_users();
+}
+
+sub users_add
+{
+    my ($self) = @_;
+    $self->can_do("user_mgnt");
+
+    # we don't quote username directly to check that it is conform
+    my $arg = $self->get_form(qw/username qpasswd qcomment jrolenames qcreate qcopy_username/) ;
+
+    if (not $arg->{qcreate}) {
+        $arg = $self->get_form(qw/db_roles db_usernames/);
+        $self->display($arg, "display_user.tpl");
+        return 1;
+    }
+
+    my $u = $self->dbh_quote($arg->{username});
+
+    if (!$arg->{qpasswd}) {
+        $arg->{qpasswd} = "''";
+    }
+    if (!$arg->{qcomment}) {
+        $arg->{qcomment} = "''";
+    }
+
+    # will fail if user already exists
+    $self->dbh_do("
+  UPDATE bweb_user SET passwd=$arg->{qpasswd}, comment=$arg->{qcomment}
+   WHERE username = $u")
+        or
+    $self->dbh_do("
+  INSERT INTO bweb_user (username, passwd, comment) 
+        VALUES ($u, $arg->{qpasswd}, $arg->{qcomment})");
+
+    $self->{dbh}->begin_work();
+    {
+        $self->revoke_all($u);
+
+        if ($arg->{qcopy_username}) {
+            $self->grant_like($arg->{qcopy_username}, $u);
+        } else {
+            $self->grant($arg->{jrolenames}, $u);
+        }
+    }
+    $self->{dbh}->commit();
+
+    $self->display_users();
+}
+
+# TODO: we miss a matrix with all user/roles
+sub display_users
+{
+    my ($self) = @_;
+    $self->can_do("user_mgnt");
+
+    my $arg = $self->get_form(qw/db_usernames/) ;
+
+    if ($self->{dbh}->errstr) {
+        return $self->error("Can't use users with bweb, read INSTALL to enable them");
+    }
+
+    $self->display({ ID => $cur_id++,
+                     %$arg},
+                   "display_users.tpl");
+}
+
+sub display_user
+{
+    my ($self) = @_;
+    $self->can_do("user_mgnt");
+
+    my $arg = $self->get_form(qw/username db_usernames/);
+    my $user = $self->dbh_quote($arg->{username});
+
+    my $userp = $self->dbh_selectrow_hashref("
+   SELECT username, passwd, comment
+     FROM bweb_user
+    WHERE username = $user
+");
+
+    if (!$userp) {
+        return $self->error("Can't find $user in catalog");
+    }
+
+#  rolename  | userid
+#------------+--------
+# cancel_job |
+# restore    |
+# run_job    |      1
+
+    my $role = $self->dbh_selectall_hashref("
+SELECT rolename, temp.userid
+     FROM bweb_role
+     LEFT JOIN (SELECT roleid, userid
+             FROM bweb_user JOIN bweb_role_member USING (userid)
+            WHERE username = $user) AS temp USING (roleid)
+ORDER BY rolename
+", 'rolename');
+
+    $self->display({
+        db_usernames => $arg->{db_usernames},
+        username => $userp->{username},
+        comment => $userp->{comment},
+        passwd => $userp->{passwd},
+        db_roles => [ values %$role], 
+    }, "display_user.tpl");
+}
+
+
 ###########################################################
 
 sub get_media_max_size
index b9ba549c09afd7e58bdc5cc0daf6dc393427914e..666b0e30210a88d14a2db5f8e08edba4e753ae38 100755 (executable)
@@ -52,6 +52,10 @@ my %dict;
 sub print_it
 {
     foreach my $w (@_) {
+       next if ($w eq '&nbsp;');
+       next if ($w !~ /\w/);
+       next if ($w =~ />/);
+
        next if (exists $dict{$w});
        $dict{$w}=1;
 
@@ -79,9 +83,7 @@ sub text {
     $text =~ s/(^\s+)|(\s+$)//gs;
 
     # skip some special cases
-    return if ($text eq '&nbsp;');
-    return if ($text !~ /\w/);
-    return if ($text =~ />/);
+    return if ($text eq 'selected');
     print_it($text);
 }
 
index a535a6b54050869f0eef31536c08305df79be1f6..349c8fc1051424c2d8daa827d4f55fbdeb0f4285 100644 (file)
@@ -55,7 +55,13 @@ if (navigator.appName == 'Konqueror') {
  </li>
 </TMPL_IF> 
  <li><a href="bweb.pl?action=graph"> Statistics </a></li>
- <li> <a href="bweb.pl?action=view_conf"> Configuration </a> </li>
+ <li> <a href="bweb.pl?action=view_conf"> Configuration </a> 
+<TMPL_IF enable_security>
+  <ul> <li> <a href="bweb.pl?action=view_conf"> Configuration </a> 
+       <li> <a href="bweb.pl?action=users"> Manage users </a>
+  </ul>
+</TMPL_IF>
+</li>
  <li> <a href="bweb.pl?action=about"> About </a> </li>
  <li style="padding: 0.25em 2em;float: right;">&nbsp;Logged as <TMPL_VAR NAME=loginname> </li>
  <li style="float: right;white-space: nowrap;">
diff --git a/gui/bweb/tpl/display_user.tpl b/gui/bweb/tpl/display_user.tpl
new file mode 100644 (file)
index 0000000..8c1a902
--- /dev/null
@@ -0,0 +1,73 @@
+<div class='titlediv'>
+  <h1 class='newstitle'> User: <TMPL_VAR username></h1>
+</div>
+<div class='bodydiv'>
+
+<form name="form1" action="?">
+<input type="hidden" value="1" name="create">
+ <table>
+ <tr>
+  <td>Username:</td> <td> <input class="formulaire" type="text" name="username" value="<TMPL_VAR username>"> </td>
+<!-- </tr><tr>
+  <td>Password:</td> <td> <input class="formulaire" type="password" name="passwd" value="<TMPL_VAR passwd>"> </td>
+-->
+ </tr><tr>
+  <td>Comment:</td> <td> <input class="formulaire" type="text" name="comment" value="<TMPL_VAR comment>"> </td>
+ </tr><tr>
+<td> Profile:</td><td>
+ <select name="profile" id='profile' class="formulaire">
+  <option onclick='set_role("")'></option>
+  <option onclick='set_role("administrator")'>Administrator</option>
+  <option onclick='set_role("customer")'>Customer</option>
+ </select>
+</td><td>Or like an existing user: </td><td>
+ <select name="copy_username" class="formulaire">
+  <option onclick="disable_sel(false)"></option>
+ <TMPL_LOOP db_usernames>
+  <option title="<TMPL_VAR comment>" onclick="disable_sel(true)" value="<TMPL_VAR username>"><TMPL_VAR username></option>
+ </TMPL_LOOP>
+ </select>
+</td>
+ </tr><tr>
+ </tr><tr>
+<td> Roles:</td><td>
+ <select name="rolename" id='rolename' multiple class="formulaire" size=15>
+ <TMPL_LOOP db_roles>
+  <option title="<TMPL_VAR comment>" value="<TMPL_VAR rolename>" <TMPL_IF userid>selected</TMPL_IF> ><TMPL_VAR rolename></option>
+ </TMPL_LOOP>
+ </select>
+ </td>
+</table>
+    <input type="image" name='action' value='user_save'
+     src='/bweb/save.png'>
+</form>
+</div>
+
+<script type="text/javascript" language='JavaScript'>
+function disable_sel(val) 
+{
+       document.form1.profile.disabled = val;
+       document.form1.rolename.disabled = val;
+}
+function set_role(val)
+{
+   if (val == "administrator") {
+       for (var i=0; i < document.form1.rolename.length; ++i) {
+             document.form1.rolename[i].selected = true;
+       }
+   } else if (val == "customer") {
+       for (var i=0; i < document.form1.rolename.length; ++i) {
+          if (document.form1.rolename[i].value == 'view_stats'   ||
+               document.form1.rolename[i].value == 'view_history' ||
+               document.form1.rolename[i].value == 'view_log'
+               )
+           {
+             document.form1.rolename[i].selected = true;
+          } else {
+             document.form1.rolename[i].selected = false;
+          }
+       }
+   }
+
+}
+</script>
diff --git a/gui/bweb/tpl/display_users.tpl b/gui/bweb/tpl/display_users.tpl
new file mode 100644 (file)
index 0000000..7a477a9
--- /dev/null
@@ -0,0 +1,65 @@
+<br/>
+ <div class='titlediv'>
+  <h1 class='newstitle'>Users</h1>
+ </div>
+ <div class="bodydiv">
+   <form action='?' method='get'>
+    <table id='id<TMPL_VAR ID>'></table>
+    <input type="image" name='action' value='user_add' title='Add' src='/bweb/add.png'>&nbsp;
+    <input type="image" name='action' value='user_del' 
+     onclick="return confirm('Do you want to delete this user ?');" 
+     title='Supprimer' src='/bweb/remove.png'>&nbsp;
+    <input type="image" name='action' value='user_edit' title='Modify' src='/bweb/edit.png'>&nbsp;
+
+    <input type="image" name='action' value='client' title='View clients'
+     src='/bweb/zoom.png'>&nbsp;
+    <input type="image" name='action' value='job' title='View jobs'
+     src='/bweb/zoom.png'>&nbsp;
+   </form>
+ </div>
+
+<script type="text/javascript" language="JavaScript">
+
+var header = new Array("Username","Selection");
+
+var data = new Array();
+var chkbox;
+
+<TMPL_LOOP db_usernames>
+
+chkbox = document.createElement('INPUT');
+chkbox.type  = 'radio';
+chkbox.name  = 'username';
+chkbox.value = '<TMPL_VAR username>';
+
+data.push( new Array(
+"<TMPL_VAR username>",
+chkbox
+ )
+);
+</TMPL_LOOP>
+
+nrsTable.setup(
+{
+ table_name:     "id<TMPL_VAR ID>",
+ table_header: header,
+ table_data: data,
+ up_icon: up_icon,
+ down_icon: down_icon,
+ prev_icon: prev_icon,
+ next_icon: next_icon,
+ rew_icon:  rew_icon,
+ fwd_icon:  fwd_icon,
+// natural_compare: false,
+ even_cell_color: even_cell_color,
+ odd_cell_color: odd_cell_color, 
+ header_color: header_color,
+ page_nav: true,
+ padding: 3,
+// disable_sorting: new Array(5,6),
+ rows_per_page: rows_per_page
+}
+);
+</script>
+
+