Changeset 87 for trunk/DNSDB.pm


Ignore:
Timestamp:
03/31/11 18:01:43 (13 years ago)
Author:
Kris Deugau
Message:

/trunk

Checkpoint. Permissions manipulation should be complete.
Still need to set up permissions *checking*.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r83 r87  
    240240# Update an ACL entry
    241241# Takes a db handle, type, owner-id, and hashref for the changed permissions.
    242 ##fixme: Must handle case of changing object's permissions from inherited to custom
     242##fixme: Must handle case of changing object's permissions from custom to inherited
    243243sub changePermissions {
    244244  my $dbh = shift;
     
    246246  my $id = shift;
    247247  my $newperms = shift;
     248  my $inherit = shift || 0;
    248249
    249250  my $failmsg = '';
    250251
    251   # see if we're switching from inherited to custom
    252   my $sth = $dbh->prepare("SELECT (u.permission_id=g.permission_id) AS was_inherited,u.permission_id".
     252  # see if we're switching from inherited to custom.  for bonus points,
     253  # snag the permid and parent permid anyway, since we'll need the permid
     254  # to set/alter custom perms, and both if we're switching from custom to
     255  # inherited.
     256  my $sth = $dbh->prepare("SELECT (u.permission_id=g.permission_id) AS was_inherited,u.permission_id,g.permission_id".
    253257        " FROM ".($type eq 'user' ? 'users' : 'groups')." u ".
    254258        " JOIN groups g ON u.".($type eq 'user' ? '' : 'parent_')."group_id=g.group_id ".
     
    256260  $sth->execute($id);
    257261
    258   my ($wasinherited,$permid) = $sth->fetchrow_array;
     262  my ($wasinherited,$permid,$parpermid) = $sth->fetchrow_array;
    259263
    260264# hack phtoui
     
    268272  # Wrap all the SQL in a transaction
    269273  eval {
    270     if ($wasinherited) {
     274    if ($inherit) {
     275
     276      $dbh->do("UPDATE ".($type eq 'user' ? 'users' : 'groups')." SET inherit_perm='t',permission_id=? ".
     277        "WHERE ".($type eq 'user' ? 'user' : 'group')."_id=?", undef, ($parpermid, $id) );
     278      $dbh->do("DELETE FROM permissions WHERE permission_id=?", undef, ($permid) );
     279
     280    } else {
     281
     282      if ($wasinherited) {      # munge new permission entry in if we're switching from inherited perms
    271283##fixme: need to add semirecursive bit to properly munge inherited permission ID on subgroups and users
    272       $dbh->do("INSERT INTO permissions ($permlist) ".
    273         "SELECT $permlist FROM permissions WHERE permission_id=?", undef, ($permid) );
    274       #$sth = $dbh->prepare($sql);
    275       #$sth->execute($permid);
    276       $sth = $dbh->prepare("SELECT permission_id FROM ".($type eq 'user' ? 'users' : 'groups').
    277         " WHERE ".($type eq 'user' ? 'user' : 'group')."_id=?");
    278       $sth->execute($id);
    279       ($permid) = $sth->fetchrow_array;
    280       $dbh->do("UPDATE permissions SET ".($type eq 'user' ? 'user' : 'group')."_id=? ".
    281         "WHERE permission_id=?", undef, ($id,$permid) );
    282       $dbh->do("UPDATE ".($type eq 'user' ? 'users' : 'groups')." SET permission_id=? ".
    283         "WHERE ".($type eq 'user' ? 'user' : 'group')."_id=?", undef, ($permid,$id) );
    284     }
    285     foreach (@permtypes) {
    286       if (defined ($newperms->{$_})) {
    287         $dbh->do("UPDATE permissions SET $_=? WHERE permission_id=?", undef, ($newperms->{$_},$permid) );
    288         #$sth->execute($newperms->{$_},$permid);
     284# ... if'n'when we have groups with fully inherited permissions.
     285        # SQL is coo
     286        $dbh->do("INSERT INTO permissions ($permlist,".($type eq 'user' ? 'user' : 'group')."_id) ".
     287                "SELECT $permlist,? FROM permissions WHERE permission_id=?", undef, ($id,$permid) );
     288        ($permid) = $dbh->selectrow_array("SELECT permission_id FROM permissions ".
     289                "WHERE ".($type eq 'user' ? 'user' : 'group')."_id=?", undef, ($id) );
     290        $dbh->do("UPDATE ".($type eq 'user' ? 'users' : 'groups')." SET inherit_perm='f',permission_id=? ".
     291                "WHERE ".($type eq 'user' ? 'user' : 'group')."_id=?", undef, ($permid, $id) );
    289292      }
    290     }
     293
     294      # and now set the permissions we were passed
     295      foreach (@permtypes) {
     296        if (defined ($newperms->{$_})) {
     297          $dbh->do("UPDATE permissions SET $_=? WHERE permission_id=?", undef, ($newperms->{$_},$permid) );
     298        }
     299      }
     300
     301    } # (inherited->)? custom
    291302
    292303    $dbh->commit;
     
    295306    my $msg = $@;
    296307    eval { $dbh->rollback; };
    297     return ('FAIL',"$failmsg: $msg");
     308    return ('FAIL',"$failmsg: $msg ($permid)");
    298309  } else {
    299310    return ('OK',$permid);
     
    533544        "VALUES ($groupid,?,?,?,?,?,?,?)");
    534545    if ($inherit) {
    535 ##fixme:  fixme!
     546      # Duplicate records from parent.  Actually relying on inherited records feels
     547      # very fragile, and it would be problematic to roll over at a later time.
    536548      my $sth2 = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl FROM default_records WHERE group_id=?");
     549      $sth2->execute($pargroup);
    537550      while (my @clonedata = $sth2->fetchrow_array) {
    538551        $sth->execute(@clonedata);
     
    665678
    666679## DNSDB::addUser()
    667 #
     680# Add a user.
     681# Takes a DB handle, username, group ID, password, state (active/inactive).
     682# Optionally accepts:
     683#   user type (user/admin)      - defaults to user
     684#   permissions string          - defaults to inherit from group
     685#      three valid forms:
     686#       i                    - Inherit permissions
     687#       c:<user_id>          - Clone permissions from <user_id>
     688#       C:<permission list>  - Set these specific permissions
     689#   first name                  - defaults to username
     690#   last name                   - defaults to blank
     691#   phone                       - defaults to blank (could put other data within column def)
     692# Returns (OK,OK) on success, (FAIL,<message>) on failure
    668693sub addUser {
    669694  $errstr = '';
    670695  my $dbh = shift;
    671   return ('FAIL',"Need database handle") if !$dbh;
    672696  my $username = shift;
    673   return ('FAIL',"Missing username") if !defined($username);
    674697  my $group = shift;
    675   return ('FAIL',"Missing group") if !defined($group);
    676698  my $pass = shift;
    677   return ('FAIL',"Missing password") if !defined($pass);
    678699  my $state = shift;
    679   return ('FAIL',"Need account status") if !defined($state);
     700
     701  return ('FAIL',"Missing one or more required entries") if !defined($state);
    680702
    681703  my $type = shift || 'u';      # create limited users by default - fwiw, not sure yet how this will interact with ACLs
     
    701723  local $dbh->{RaiseError} = 1;
    702724
     725my $failmsg;
    703726  # Wrap all the SQL in a transaction
    704727  eval {
    705     # insert the user...
    706     my $sth = $dbh->prepare("INSERT INTO users (group_id,username,password,firstname,lastname,phone,type,status) ".
    707         "VALUES (?,?,?,?,?,?,?,?)");
    708     $sth->execute($group,$username,unix_md5_crypt($pass),$fname,$lname,$phone,$type,$state);
     728    # insert the user...  note we set inherited perms by default since
     729    # it's simple and cleans up some other bits of state
     730    my $sth = $dbh->prepare("INSERT INTO users ".
     731        "(group_id,username,password,firstname,lastname,phone,type,status,permission_id,inherit_perm) ".
     732        "VALUES (?,?,?,?,?,?,?,?,(SELECT permission_id FROM permissions WHERE group_id=?),'t')");
     733    $sth->execute($group,$username,unix_md5_crypt($pass),$fname,$lname,$phone,$type,$state,$group);
    709734
    710735    # get the ID...
     
    713738    ($user_id) = $sth->fetchrow_array();
    714739
     740# Permissions!  Gotta set'em all!
     741    die "Invalid permission string $permstring"
     742        if $permstring !~ /^(?:
     743                i       # inherit
     744                |c:\d+  # clone
     745                        # custom.  no, the leading , is not a typo
     746                |C:(?:,(?:group|user|domain|record|self)_(?:edit|create|delete))+
     747                )$/x;
     748# bleh.  I'd call another function to do my dirty work, but we're in the middle of a transaction already.
     749    if ($permstring ne 'i') {
     750      # for cloned or custom permissions, we have to create a new permissions entry.
     751      my $clonesrc = $group;
     752      if ($permstring =~ /^c:(\d+)/) { $clonesrc = $1; }
     753      $dbh->do("INSERT INTO permissions ($permlist,user_id) ".
     754        "SELECT $permlist,? FROM permissions WHERE permission_id=".
     755        "(SELECT permission_id FROM permissions WHERE ".($permstring =~ /^c:/ ? 'user' : 'group')."_id=?)",
     756        undef, ($user_id,$clonesrc) );
     757      $dbh->do("UPDATE users SET permission_id=".
     758        "(SELECT permission_id FROM permissions WHERE user_id=?) ".
     759        "WHERE user_id=?", undef, ($user_id, $user_id) );
     760    }
     761    if ($permstring =~ /^C:/) {
     762      # finally for custom permissions, we set the passed-in permissions (and unset
     763      # any that might have been brought in by the clone operation above)
     764      my ($permid) = $dbh->selectrow_array("SELECT permission_id FROM permissions WHERE user_id=?",
     765        undef, ($user_id) );
     766      foreach (@permtypes) {
     767        if ($permstring =~ /,$_/) {
     768          $dbh->do("UPDATE permissions SET $_='t' WHERE permission_id=?", undef, ($permid) );
     769        } else {
     770          $dbh->do("UPDATE permissions SET $_='f' WHERE permission_id=?", undef, ($permid) );
     771        }
     772      }
     773    }
     774
     775    $dbh->do("UPDATE users SET inherit_perm='n' WHERE user_id=?", undef, ($user_id) );
     776
    715777##fixme: add another table to hold name/email for log table?
    716 die "dying horribly\n";
     778#die "dying horribly ($permstring, $user_id)";
    717779
    718780    # once we get here, we should have suceeded.
     
    723785    my $msg = $@;
    724786    eval { $dbh->rollback; };
    725     return ('FAIL',$msg);
     787    return ('FAIL',$msg." $failmsg");
    726788  } else {
    727789    return ('OK',$user_id);
     
    762824  my $pass = shift;
    763825  my $state = shift;
    764   my $type = shift;
     826  my $type = shift || 'u';
    765827  my $fname = shift || $username;
    766828  my $lname = shift || '';
     
    11361198  my $id = shift;
    11371199
    1138 return "FAIL", "wakka wakka";
    11391200  my $sth = $dbh->prepare("DELETE FROM ".($defrec eq 'y' ? 'default_' : '')."records WHERE record_id=?");
    11401201  $sth->execute($id);
Note: See TracChangeset for help on using the changeset viewer.