disable default cherrypy http listener
[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
+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
@@ -24,7 +25,7 @@ class Validate:
         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.")
@@ -56,13 +57,13 @@ class Validate:
         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")
-            self.autoinstall = Autoinstall.query().get(autoinstall)
+            self.autoinstall = Autoinstall.query.get(autoinstall)
 
 
 def getMachinesByOwner(owner, machine=None):
@@ -73,7 +74,7 @@ def getMachinesByOwner(owner, machine=None):
     """
     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.
@@ -106,9 +107,10 @@ def maxDisk(owner, machine=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):
@@ -129,7 +131,7 @@ def haveAccess(user, state, 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"""
@@ -180,7 +182,7 @@ def validDisk(owner, g, disk, machine=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
@@ -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 = 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):
@@ -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.
 
-    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
@@ -217,20 +218,17 @@ def testAdmin(user, admin, machine):
         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 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.
@@ -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 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: