Changelog for invirt-web 0.1.44
[invirt/packages/invirt-web.git] / code / validation.py
index 9b7a0b0..26a49a3 100755 (executable)
@@ -5,6 +5,7 @@ import getafsgroups
 import re
 import string
 import dns.resolver
 import re
 import string
 import dns.resolver
+from invirt import authz
 from invirt.database import Machine, NIC, Type, Disk, CDROM, Autoinstall, Owner
 from invirt.config import structs as config
 from invirt.common import InvalidInput, CodeError
 from invirt.database import Machine, NIC, Type, Disk, CDROM, Autoinstall, Owner
 from invirt.config import structs as config
 from invirt.common import InvalidInput, CodeError
@@ -24,7 +25,7 @@ class Validate:
         if strict:
             if name is None:
                 raise InvalidInput('name', name, "You must provide a machine name.")
         if strict:
             if name is None:
                 raise InvalidInput('name', name, "You must provide a machine name.")
-            if description is None:
+            if description is None or description.strip() == '':
                 raise InvalidInput('description', description, "You must provide a description.")
             if memory is None:
                 raise InvalidInput('memory', memory, "You must provide a memory size.")
                 raise InvalidInput('description', description, "You must provide a description.")
             if memory is None:
                 raise InvalidInput('memory', memory, "You must provide a memory size.")
@@ -56,13 +57,13 @@ class Validate:
         if vmtype is not None:
             self.vmtype = validVmType(vmtype)
         if cdrom is not None:
         if vmtype is not None:
             self.vmtype = validVmType(vmtype)
         if cdrom is not None:
-            if not CDROM.query().get(cdrom):
+            if not CDROM.query.get(cdrom):
                 raise CodeError("Invalid cdrom type '%s'" % cdrom)
             self.cdrom = cdrom
         if autoinstall is not None:
             #raise InvalidInput('autoinstall', 'install',
             #                   "The autoinstaller has been temporarily disabled")
                 raise CodeError("Invalid cdrom type '%s'" % cdrom)
             self.cdrom = cdrom
         if autoinstall is not None:
             #raise InvalidInput('autoinstall', 'install',
             #                   "The autoinstaller has been temporarily disabled")
-            self.autoinstall = Autoinstall.query().get(autoinstall)
+            self.autoinstall = Autoinstall.query.get(autoinstall)
 
 
 def getMachinesByOwner(owner, machine=None):
 
 
 def getMachinesByOwner(owner, machine=None):
@@ -73,7 +74,7 @@ def getMachinesByOwner(owner, machine=None):
     """
     if machine:
         owner = machine.owner
     """
     if machine:
         owner = machine.owner
-    return Machine.query().filter_by(owner=owner)
+    return Machine.query.filter_by(owner=owner)
 
 def maxMemory(owner, g, machine=None, on=True):
     """Return the maximum memory for a machine or a user.
 
 def maxMemory(owner, g, machine=None, on=True):
     """Return the maximum memory for a machine or a user.
@@ -106,9 +107,10 @@ def maxDisk(owner, machine=None):
         machine_id = machine.machine_id
     else:
         machine_id = None
         machine_id = machine.machine_id
     else:
         machine_id = None
-    disk_usage = Disk.query().filter(Disk.c.machine_id != machine_id).\
-                     join('machine').\
-                     filter_by(owner=owner).sum(Disk.c.size) or 0
+    disk_usage_query = Disk.query.filter(Disk.machine_id != machine_id).\
+        join('machine').filter_by(owner=owner)
+
+    disk_usage = sum([m.size for m in disk_usage_query]) or 0
     return min(quota_single, quota_total-disk_usage/1024.)
 
 def cantAddVm(owner, g):
     return min(quota_single, quota_total-disk_usage/1024.)
 
 def cantAddVm(owner, g):
@@ -129,7 +131,7 @@ def haveAccess(user, state, machine):
 
 def owns(user, machine):
     """Return whether a user owns a machine"""
 
 def owns(user, machine):
     """Return whether a user owns a machine"""
-    return user in expandLocker(machine.owner)
+    return user in authz.expandOwner(machine.owner)
 
 def validMachineName(name):
     """Check that name is valid for a machine name"""
 
 def validMachineName(name):
     """Check that name is valid for a machine name"""
@@ -180,7 +182,7 @@ def validDisk(owner, g, disk, machine=None):
 def validVmType(vm_type):
     if vm_type is None:
         return None
 def validVmType(vm_type):
     if vm_type is None:
         return None
-    t = Type.query().get(vm_type)
+    t = Type.query.get(vm_type)
     if t is None:
         raise CodeError("Invalid vm type '%s'"  % vm_type)
     return t
     if t is None:
         raise CodeError("Invalid vm type '%s'"  % vm_type)
     return t
@@ -197,7 +199,7 @@ def testMachineId(user, state, machine_id, exists=True):
         machine_id = int(machine_id)
     except ValueError:
         raise InvalidInput('machine_id', machine_id, "Must be an integer.")
         machine_id = int(machine_id)
     except ValueError:
         raise InvalidInput('machine_id', machine_id, "Must be an integer.")
-    machine = Machine.query().get(machine_id)
+    machine = Machine.query.get(machine_id)
     if exists and machine is None:
         raise InvalidInput('machine_id', machine_id, "Does not exist.")
     if machine is not None and not haveAccess(user, state, machine):
     if exists and machine is None:
         raise InvalidInput('machine_id', machine_id, "Does not exist.")
     if machine is not None and not haveAccess(user, state, machine):
@@ -208,8 +210,7 @@ def testMachineId(user, state, machine_id, exists=True):
 def testAdmin(user, admin, machine):
     """Determine whether a user can set the admin of a machine to this value.
 
 def testAdmin(user, admin, machine):
     """Determine whether a user can set the admin of a machine to this value.
 
-    Return the value to set the admin field to (possibly 'system:' +
-    admin).  XXX is modifying this a good idea?
+    Return the value to set the admin field to (possibly 'system:' + admin).
     """
     if admin is None:
         return None
     """
     if admin is None:
         return None
@@ -217,20 +218,17 @@ def testAdmin(user, admin, machine):
         return admin
     if admin == user:
         return admin
         return admin
     if admin == user:
         return admin
+    # we do not require that the user be in the admin group;
+    # just that it is a non-empty set
+    if authz.expandAdmin(admin):
+        return admin
     if ':' not in admin:
     if ':' not in admin:
-        if cache_acls.isUser(admin):
-            return admin
-        admin = 'system:' + admin
-    try:
-        if user in getafsgroups.getAfsGroupMembers(admin, config.authz.afs.cells[0].cell):
-            return admin
-    except getafsgroups.AfsProcessError, e:
-        errmsg = str(e)
-        if errmsg.startswith("pts: User or group doesn't exist"):
-            errmsg = 'The group "%s" does not exist.' % admin
-        raise InvalidInput('administrator', admin, errmsg)
-    #XXX Should we require that user is in the admin group?
-    return admin
+        if authz.expandAdmin('system:' + admin):
+            return 'system:' + admin
+        errmsg = 'No user "%s" or non-empty group "system:%s" found.' % (admin, admin)
+    else:
+        errmsg = 'No non-empty group "%s" found.' % (admin,)
+    raise InvalidInput('administrator', admin, errmsg)
 
 def testOwner(user, owner, machine=None):
     """Determine whether a user can set the owner of a machine to this value.
 
 def testOwner(user, owner, machine=None):
     """Determine whether a user can set the owner of a machine to this value.
@@ -244,7 +242,7 @@ def testOwner(user, owner, machine=None):
     if '@' in owner:
         raise InvalidInput('owner', owner, "No cross-realm Hesiod lockers allowed")
     try:
     if '@' in owner:
         raise InvalidInput('owner', owner, "No cross-realm Hesiod lockers allowed")
     try:
-        if user not in cache_acls.expandLocker(owner):
+        if user not in authz.expandOwner(owner):
             raise InvalidInput('owner', owner, 'You do not have access to the '
                                + owner + ' locker')
     except getafsgroups.AfsProcessError, e:
             raise InvalidInput('owner', owner, 'You do not have access to the '
                                + owner + ' locker')
     except getafsgroups.AfsProcessError, e: