def delete(self, trans):
        """
        Deletes the item permanently.
        
        @param trans: A valid transaction handle
        @return: None
        """
        user = currentThread().context.user
        self = _db.get_item(self._id, trans)

        user_role = permsresolver.get_access(self, user)
        can_delete = (user_role > permsresolver.AUTHOR) or \
            (user_role == permsresolver.AUTHOR and self._owner == user._id)
        
        if (not(self._isSystem) and can_delete):
            # delete item physically
            self._delete(trans)
            # update container
            parent = _db.get_item(self._parentid, trans)
            parent.modified = time.time()
            _db.put_item(parent, trans)
        else:
            raise exceptions.PermissionDenied, \
                'The object was not deleted.\n' + \
                'The user has insufficient permissions.'
Exemple #2
0
 def _fetch_session(self, session_id, cookies_enabled):
     session = None
     if session_id:
         session = SessionManager.fetch_session(session_id)
     if session is not None:
         context.session = session
         context.user = _db.get_item(context.session.userid)
         context.request.serverVariables["AUTH_USER"] = \
             context.user.displayName.value
         if not cookies_enabled:
             if not session.sessionid in context.request.SCRIPT_NAME:
                 context.request.serverVariables['SCRIPT_NAME'] += \
                     '/{%s}' % session.sessionid
             else:
                 lstScript = context.request.SCRIPT_NAME.split('/')
                 context.request.serverVariables['SCRIPT_NAME'] = \
                     '/%s/{%s}' % (lstScript[1], session.sessionid)
     else:
         # create guest session
         guest_id = settings['sessionmanager']['guest']
         context.user = _db.get_item(guest_id)
         new_session = SessionManager.create(guest_id)
         session_id = new_session.sessionid
         if 'PMB' in context.request.serverVariables['HTTP_USER_AGENT']:
             # if is a mobile client
             # add session id in special header
             context.response.set_header('Porcupine-Session', session_id)
         else:
             # add cookie with sessionid
             context.response.cookies['_sid'] = session_id
             context.response.cookies['_sid']['path'] = \
                 context.request.SCRIPT_NAME + '/'
         context.session = new_session
    def update(self, trans):
        """
        Updates the item.
        
        @param trans: A valid transaction handle
        @return: None
        """
        old_item = _db.get_item(self._id, trans)
        parent = _db.get_item(self._parentid, trans)
        
        user = currentThread().context.user
        user_role = permsresolver.get_access(old_item, user)
        
        if user_role > permsresolver.READER:
            # set security
            if user_role == permsresolver.COORDINATOR:
                # user is COORDINATOR
                if (self.inheritRoles != old_item.inheritRoles) or \
                        (not self.inheritRoles and \
                         self.security != old_item.security):
                    self._applySecurity(parent, trans)
            else:
                # restore previous ACL
                self.security = old_item.security
                self.inheritRoles = old_item.inheritRoles

            _db.handle_update(self, old_item, trans)
            self.modifiedBy = user.displayName.value
            self.modified = time.time()
            parent.modified = self.modified
            _db.put_item(self, trans)
            _db.put_item(parent, trans)
        else:
            raise exceptions.PermissionDenied, \
                    'The user does not have update permissions.'
    def move_to(self, target_id, trans):
        """
        Moves the item to the designated target.
        
        @param target_id: The ID of the destination container
        @type target_id: str
        @param trans: A valid transaction handle
        @return: None
        @raise L{porcupine.exceptions.ObjectNotFound}:
            If the target container does not exist.
        """
        user = currentThread().context.user
        user_role = permsresolver.get_access(self, user)
        can_move = (user_role > permsresolver.AUTHOR)
        ## or (user_role == permsresolver.AUTHOR and oItem.owner == user.id)

        parent_id = self._parentid
        target = _db.get_item(target_id, trans)
        if target == None or target._isDeleted:
            raise exceptions.ObjectNotFound, (
                'The target container "%s" does not exist.' %
                target_id , False)
        
        if isinstance(self, Shortcut):
            contentclass = self.get_target_contentclass(trans)
        else:
            contentclass = self.get_contentclass()
        
        user_role2 = permsresolver.get_access(target, user)
        
        if self.isCollection and target.is_contained_in(self._id, trans):
            raise exceptions.ContainmentError, \
                'Cannot move item to destination.\n' + \
                'The destination is contained in the source.'
        
        if (not(self._isSystem) and can_move and
                user_role2 > permsresolver.READER):
            if not(contentclass in target.containment):
                raise exceptions.ContainmentError, \
                    'The target container does not accept ' + \
                    'objects of type\n"%s".' % contentclass
            
            self._parentid = target._id
            self.inheritRoles = False
            self.modified = time.time()
            _db.check_unique(self, None, trans)
            _db.put_item(self, trans)

            # update target
            target.modified = time.time()
            _db.put_item(target, trans)

            # update parent
            parent = _db.get_item(parent_id, trans)
            parent.modified = time.time()
            _db.put_item(parent, trans)
        else:
            raise exceptions.PermissionDenied, \
                'The object was not moved.\n' + \
                'The user has insufficient permissions.'
 def on_delete(item, attr, trans, bPermanent):
     if bPermanent:
         [CompositionEventHandler._removeComposite(_db.get_item(id, trans),
                                                   trans)
          for id in attr.value]
     else:
         for sID in attr.value:
             composite = _db.get_item(sID, trans)
             _db.handle_delete(composite, trans, False)
             composite._isDeleted = 1
             _db.put_item(composite, trans)
 def on_update(item, new_attr, old_attr, trans):
     from porcupine.systemObjects import Composite
     # load objects
     dctObjects = {}
     for i, obj in enumerate(new_attr.value):
         if isinstance(obj, Composite):
             obj._containerid = item._id
         elif isinstance(obj, str):
             obj = _db.get_item(obj, trans)
             new_attr.value[i] = obj
         else:
             raise exceptions.ContainmentError, \
                 'Invalid object type "%s" in composition.' % \
                 obj.__class__.__name__
         dctObjects[obj._id] = obj
     
     # check containment
     composite_type = misc.get_rto_by_name(new_attr.compositeClass)
     
     if [obj for obj in dctObjects.values()
             if not isinstance(obj, composite_type)]:
         raise exceptions.ContainmentError, \
             'Invalid content class "%s" in composition.' % \
             obj.get_contentclass()
     
     # get previous value
     if old_attr != None:
         old_ids = set(old_attr.value)
     else:
         old_ids = set()
     
     new_ids = set([obj._id for obj in new_attr.value])
     
     # calculate added composites
     lstAdded = list(new_ids - old_ids)
     for obj_id in lstAdded:
         _db.handle_update(dctObjects[obj_id], None, trans)
         _db.put_item(dctObjects[obj_id], trans)
     
     # calculate constant composites
     lstConstant = list(new_ids & old_ids)
     for obj_id in lstConstant:
         _db.handle_update(dctObjects[obj_id],
                           _db.get_item(obj_id, trans),
                           trans)
         _db.put_item(dctObjects[obj_id], trans)
     
     # calculate removed composites
     lstRemoved = list(old_ids - new_ids)
     [CompositionEventHandler._removeComposite(_db.get_item(id, trans),
                                               trans)
      for id in lstRemoved]
             
     new_attr.value = list(new_ids)
Exemple #7
0
def get_handle(**kwargs):
    if _db._db_handle is None or not _db._db_handle.is_open():
        # open database
        kwargs.setdefault('maintain', False)
        kwargs.setdefault('recover', 0)
        _db.open(**kwargs)
        identity = kwargs.get('identity', _db.get_item('system'))
        if isinstance(identity, basestring):
            identity = _db.get_item(identity)
        context.user = identity
    return _db
 def get_target_contentclass(self, trans=None):
     """Returns the content class of the target item.
     
     @param trans: A valid transaction handle
     @return: the fully qualified name of the target's
              content class
     @rtype: str
     """
     if self.target.value:
         target = _db.get_item(self.target.value, trans)
         while isinstance(target, Shortcut):
             target = _db.get_item(target.target.value, trans)
         return target.get_contentclass()
 def on_delete(item, attr, trans, bPermanent):
     if not item._isDeleted:
         if attr.value and attr.respectsReferences:
             raise exceptions.ReferentialIntegrityError, (
                 'Cannot delete object "%s" ' % item.displayName.value +
                 'because it is referenced by other objects.')
         if attr.cascadeDelete:
             _db.get_item(attr.value, trans)._recycle(trans)
     if bPermanent and attr.value:
         if attr.cascadeDelete:
             _db.get_item(attr.value, trans)._delete(trans)
         else:
             # remove reference
             Relator1EventHandler._remove_reference(attr, item._id, trans)
 def recycle(self, rb_id, trans):
     """
     Moves the item to the specified recycle bin.
     The item then becomes inaccessible.
     
     @param rb_id: The id of the destination container, which must be
                   a L{RecycleBin} instance
     @type rb_id: str
     @param trans: A valid transaction handle
     @return: None
     """
     user = currentThread().context.user
     self = _db.get_item(self._id, trans)
     
     user_role = permsresolver.get_access(self, user)
     can_delete = (user_role > permsresolver.AUTHOR) or \
                  (user_role == permsresolver.AUTHOR and
                   self._owner == user._id)
     
     if (not(self._isSystem) and can_delete):
         deleted = DeletedItem(self, trans)
         deleted._owner = user._id
         deleted._created = time.time()
         deleted.modifiedBy = user.displayName.value
         deleted.modified = time.time()
         deleted._parentid = rb_id
         
         # check recycle bin's containment
         recycle_bin = _db.get_item(rb_id, trans)
         if not(deleted.get_contentclass() in recycle_bin.containment):
             raise exceptions.ContainmentError, \
                 'The target container does not accept ' + \
                 'objects of type\n"%s".' % deleted.get_contentclass()
         
         _db.handle_update(deleted, None, trans)
         _db.put_item(deleted, trans)
         
         # delete item logically
         self._recycle(trans)
         
         # update container
         parent = _db.get_item(self._parentid, trans)
         parent.modified = time.time()
         _db.put_item(parent, trans)
     else:
         raise exceptions.PermissionDenied, \
             'The object was not deleted.\n' + \
             'The user has insufficient permissions.'
def getHandle(identity=None, recover=0):
    # open database
    _db.open(recover=recover, maintain=False)
    if identity == None:
        identity = _db.get_item('system')
    currentThread().context = SecurityContext(identity)
    return _db
    def _fetch_session(self):
        path_info = self.request.serverVariables['PATH_INFO'] or '/'

        # get session
        session = None
        cookiesEnabled = True
        if self.request.cookies.has_key('_sid'):
            session = SessionManager.fetch_session(
                self.request.cookies['_sid'].value)
        else:
            cookiesEnabled = False
            session_match = re.match(self.sid_pattern, path_info)
            if session_match:
                path_info = path_info.replace(session_match.group(), '', 1) or '/'
                self.request.serverVariables['PATH_INFO'] = path_info
                session = SessionManager.fetch_session(session_match.group(1))

        if session != None:
            self.session = session
            self.user = _db.get_item(self.session.userid)
            self.request.serverVariables["AUTH_USER"] = \
                self.user.displayName.value
            if not cookiesEnabled:
                if not session.sessionid in self.request.serverVariables["SCRIPT_NAME"]:
                    self.request.serverVariables["SCRIPT_NAME"] += \
                        '/{%s}' % session.sessionid
                else:
                    lstScript = self.request.serverVariables["SCRIPT_NAME"].split('/')
                    self.request.serverVariables["SCRIPT_NAME"] = \
                        "/%s/{%s}" %(lstScript[1], session.sessionid)
        else:
            self.session = self.__create_guest_session()
 def get_deleted_item(self):
     """
     Use this method to get the item that was logically deleted.
         
     @return: the deleted item
     @rtype: L{GenericItem}
     """
     return _db.get_item(self._deletedId)
def get_handle(**kwargs):
    if _db._db_handle is None or not _db._db_handle.is_open():
        # open database
        kwargs.setdefault("maintain", False)
        kwargs.setdefault("recover", 0)
        _db.open(**kwargs)
        identity = kwargs.get("identity", _db.get_item("system"))
        context.user = identity
    return _db
 def thread_loop(self):
     # run as system
     context.user = _db.get_item('system')
     while self.running:
         time.sleep(self.interval)
         try:
             self.execute()
         except:
             e = exceptions.InternalServerError()
             e.emit()
 def restore_to(self, parent_id, trans):
     """
     Restores the deleted object to the specified container.
     
     @param parent_id: The ID of the container in which
                       the item will be restored
     @type parent_id: str    
     @param trans: A valid transaction handle
     @return: None
     @raise L{porcupine.exceptions.ObjectNotFound}:
         If the original location or the original item no longer exists.
     """
     deleted = _db.get_item(self._deletedId, trans)
     if deleted == None:
         raise exceptions.ObjectNotFound, (
             'Cannot locate original item.\n' +
             'It seems that this item resided in a container\n' +
             'that has been permanently deleted or it is shortcut\n' +
             'having its target permanently deleted.', False)
     parent = _db.get_item(parent_id or deleted._parentid, trans)
     if parent == None or parent._isDeleted:
         raise exceptions.ObjectNotFound, (
             'Cannot locate target container.\n' +
             'It seems that this container is deleted.', False)
     
     if isinstance(deleted, Shortcut):
         contentclass = deleted.get_target_contentclass(trans)
     else:
         contentclass = deleted.get_contentclass()
     
     if contentclass and not(contentclass in parent.containment):
         raise exceptions.ContainmentError, \
             'The target container does not accept ' + \
             'objects of type\n"%s".' % contentclass
     
     # try to restore original item
     self._restore(deleted, parent, trans)
     # update parent
     parent.modified = time.time()
     _db.put_item(parent, trans)
     # delete self
     self.delete(trans, _removeDeleted=False)
Exemple #17
0
 def thread_loop(self):
     # run as system
     time_to_run = int(time.time()) + self.interval
     context.user = _db.get_item('system')
     while self.running:
         time.sleep(1)
         if int(time.time()) >= time_to_run:
             time_to_run = int(time.time()) + self.interval
             try:
                 self.execute()
             except:
                 e = exceptions.InternalServerError()
                 e.emit()
 def _remove_reference(attr, oid, trans):
     from porcupine.datatypes import Relator1, RelatorN
     ref_item = _db.get_item(attr.value, trans)
     ref_attr = getattr(ref_item, attr.relAttr)
     if isinstance(ref_attr, RelatorN):
         try:
             ref_attr.value.remove(oid)
         except ValueError:
             pass
     elif isinstance(ref_attr, Relator1):
         ref_attr.value = None
     ref_attr.validate()
     _db.put_item(ref_item, trans)
 def delete(self, trans, _removeDeleted=True):
     """
     Deletes the deleted object permanently.
     
     @param trans: A valid transaction handle
     @param _removeDeleted: Leave as is
     @return: None
     """
     Removable.delete(self, trans)
     if _removeDeleted:
         # we got a direct call. remove deleted item
         deleted = _db.get_item(self._deletedId, trans)
         if deleted != None:
             deleted._delete(trans)
 def create(target, trans=None):
     """Helper method for creating shortcuts of items.
     
     @param target: The id of the item or the item object itself
     @type parent: str OR L{Item}
     @param trans: A valid transaction handle
     @return: L{Shortcut}
     """
     if type(target) == str:
         target = _db.get_item(target, trans)
     shortcut = Shortcut()
     shortcut.displayName.value = target.displayName.value
     shortcut.target.value = target._id
     return shortcut
Exemple #21
0
 def _get_item(self, s):
     item = persist.loads(s)
     if not self.enforce_permissions:
         if self.resolve_shortcuts:
             while item is not None and isinstance(item, Shortcut):
                 item = _db.get_item(item.target.value)
     else:
         # check read permissions
         access = permsresolver.get_access(item, context.user)
         if item._isDeleted or access == 0:
             item = None
         elif self.resolve_shortcuts and isinstance(item, Shortcut):
             item = item.get_target()
     return item
 def _get_item(self, s):
     item = persist.loads(s)
     if self.fetch_all:
         if self.resolve_shortcuts:
             while item != None and isinstance(item, Shortcut):
                 item = _db.get_item(item.target.value, self._txn)
     else:
         # check read permissions
         access = permsresolver.get_access(item, self._thread.context.user)
         if item._isDeleted or access == 0:
             item = None
         elif self.resolve_shortcuts and isinstance(item, Shortcut):
             item = item.get_target(self._txn)
     return item
 def is_contained_in(self, item_id, trans=None):
     """
     Checks if the item is contained in the specified container.
     
     @param item_id: The id of the container
     @type item_id: str
     @rtype: bool
     """
     item = self
     while item._id != '':
         if item._id == item_id:
             return True
         item = _db.get_item(item.parentid, trans)
     return False
Exemple #24
0
 def _get_item(self, s):
     item = persist.loads(s)
     if not self.enforce_permissions:
         if self.resolve_shortcuts:
             while item is not None and isinstance(item, Shortcut):
                 item = _db.get_item(item.target.value)
     else:
         # check read permissions
         access = permsresolver.get_access(item, context.user)
         if item._isDeleted or access == 0:
             item = None
         elif self.resolve_shortcuts and isinstance(item, Shortcut):
             item = item.get_target()
     return item
 def _add_reference(attr, oid, trans):
     from porcupine.datatypes import Relator1, RelatorN
     ref_item = _db.get_item(attr.value, trans)
     if ref_item != None and isinstance(ref_item,
                                        tuple([misc.get_rto_by_name(cc)
                                               for cc in attr.relCc])):
         ref_attr = getattr(ref_item, attr.relAttr)
         if isinstance(ref_attr, RelatorN):
             ref_attr.value.append(oid)
         elif isinstance(ref_attr, Relator1):
             ref_attr.value = oid
         ref_attr.validate()
         _db.put_item(ref_item, trans)
     else:
         attr.value = None
 def _remove_references(attr, ids, oid, trans):
     # remove references
     from porcupine.datatypes import Relator1, RelatorN
     for id in ids:
         ref_item = _db.get_item(id, trans)
         ref_attr = getattr(ref_item, attr.relAttr)
         if isinstance(ref_attr, RelatorN):
             try:
                 ref_attr.value.remove(oid)
             except ValueError:
                 pass
         elif isinstance(ref_attr, Relator1):
             ref_attr.value = ''
         ref_attr.validate()
         _db.put_item(ref_item, trans)
Exemple #27
0
    def _get_size(self):
        try:
            if self._value is not None:
                # equality
                size = self._cursor.count()
            else:
                # range cursor - approximate sizing
                # assuming even distribution of keys

                # get scope's range
                first_value = str_long(
                    self._cursor.set_range(self._scope + b'_')[0])
                last = self._cursor.set_range(self._scope + b'a')
                if last is not None:
                    last_value = str_long(self._cursor.get(db.DB_PREV)[0])
                else:
                    last_value = str_long(self._cursor.last()[0])
                scope_range = float(last_value - first_value)

                if self._range._lower_value is not None:
                    start_value = str_long(self._scope + b'_' +
                                           self._range._lower_value)
                    if start_value < first_value:
                        start_value = first_value
                else:
                    start_value = first_value

                if self._range._upper_value is not None:
                    end_value = str_long(self._scope + b'_' +
                                         self._range._upper_value)
                    if end_value > last_value:
                        end_value = last_value
                else:
                    end_value = last_value

                if scope_range == 0:
                    size = 0
                else:
                    children_count = _db.get_item(self._scope).children_count
                    size = int(((end_value - start_value) / scope_range) *
                               children_count)

        except (db.DBLockDeadlockError, db.DBLockNotGrantedError):
            if context._trans is not None:
                context._trans.abort()
            raise exceptions.DBRetryTransaction

        return size
Exemple #28
0
    def _get_size(self):
        try:
            if self._value is not None:
                # equality
                size = self._cursor.count()
            else:
                # range cursor - approximate sizing
                # assuming even distribution of keys

                # get scope's range
                first_value = str_long(
                    self._cursor.set_range(self._scope + b'_')[0])
                last = self._cursor.set_range(self._scope + b'a')
                if last is not None:
                    last_value = str_long(self._cursor.get(db.DB_PREV)[0])
                else:
                    last_value = str_long(self._cursor.last()[0])
                scope_range = float(last_value - first_value)

                if self._range._lower_value is not None:
                    start_value = str_long(self._scope + b'_' +
                                           self._range._lower_value)
                    if start_value < first_value:
                        start_value = first_value
                else:
                    start_value = first_value

                if self._range._upper_value is not None:
                    end_value = str_long(self._scope + b'_' +
                                         self._range._upper_value)
                    if end_value > last_value:
                        end_value = last_value
                else:
                    end_value = last_value

                if scope_range == 0:
                    size = 0
                else:
                    children_count = _db.get_item(self._scope).children_count
                    size = int(((end_value - start_value) /
                                scope_range) * children_count)

        except (db.DBLockDeadlockError, db.DBLockNotGrantedError):
            if context._trans is not None:
                context._trans.abort()
            raise exceptions.DBRetryTransaction

        return size
    def append_to(self, parent, trans):
        """
        Adds the item to the specified container.

        @param parent: The id of the destination container or the container
                       itself
        @type parent: str OR L{Container}
        @param trans: A valid transaction handle
        @return: None
        """
        if type(parent) == str:
            parent = _db.get_item(parent, trans)
        
        if isinstance(self, Shortcut):
            contentclass = self.get_target_contentclass(trans)
        else:
            contentclass = self.get_contentclass()
        
        user = currentThread().context.user
        user_role = permsresolver.get_access(parent, user)
        if user_role == permsresolver.READER:
            raise exceptions.PermissionDenied, \
                'The user does not have write permissions ' + \
                'on the parent folder.'
        if not(contentclass in parent.containment):
            raise exceptions.ContainmentError, \
                'The target container does not accept ' + \
                'objects of type\n"%s".' % contentclass

        # set security to new item
        if user_role == permsresolver.COORDINATOR:
            # user is COORDINATOR
            self._applySecurity(parent, trans)
        else:
            # user is not COORDINATOR
            self.inheritRoles = True
            self.security = parent.security
        
        self._owner = user._id
        self._created = time.time()
        self.modifiedBy = user.displayName.value
        self.modified = time.time()
        self._parentid = parent._id
        _db.handle_update(self, None, trans)
        parent.modified = self.modified
        _db.put_item(self, trans)
        _db.put_item(parent, trans)
    def copy_to(self, target_id, trans):
        """
        Copies the item to the designated target.

        @param target_id: The ID of the destination container
        @type target_id: str
        @param trans: A valid transaction handle
        @return: None
        @raise L{porcupine.exceptions.ObjectNotFound}:
            If the target container does not exist.
        """
        target = _db.get_item(target_id, trans)
        if target == None or target._isDeleted:
            raise exceptions.ObjectNotFound, (
                'The target container "%s" does not exist.' %
                target_id , False)
        
        if isinstance(self, Shortcut):
            contentclass = self.get_target_contentclass(trans)
        else:
            contentclass = self.get_contentclass()
        
        if self.isCollection and target.is_contained_in(self._id, trans):
            raise exceptions.ContainmentError, \
                'Cannot copy item to destination.\n' + \
                'The destination is contained in the source.'
        
        # check permissions on target folder
        user = currentThread().context.user
        user_role = permsresolver.get_access(target, user)
        if not(self._isSystem) and user_role > permsresolver.READER:
            if not(contentclass in target.containment):
                raise exceptions.ContainmentError, \
                    'The target container does not accept ' + \
                    'objects of type\n"%s".' % contentclass
            
            self._copy(target, trans, clear_inherited=True)
            # update parent
            target.modified = time.time()
            _db.put_item(target, trans)
        else:
            raise exceptions.PermissionDenied, \
                'The object was not copied.\n' + \
                'The user has insufficient permissions.'
 def __create_guest_session(self):
     # create new session with the specified guest user
     self.user = _db.get_item(settings['sessionmanager']['guest'])
     new_session = SessionManager.create(settings['sessionmanager']['guest'])
     
     session_id = new_session.sessionid
     query_string = self.request.getQueryString()
     
     if '_nojavascript' in query_string:
         root_url = self.request.getRootUrl()
         path = self.request.serverVariables['PATH_INFO']
         self.response.redirect(
             '%(root_url)s/{%(session_id)s}%(path)s' % locals()
         )
     
     # add cookie with sessionid
     self.response.cookies['_sid'] = session_id
     self.response.cookies['_sid']['path'] = \
         self.request.serverVariables['SCRIPT_NAME']
     return new_session
Exemple #32
0
    def apply(context, item, registration, **kwargs):
        policyid = kwargs['policyid']
        policy = _db.get_item(policyid)
        user = context.user
        policyGrantedTo = policy.policyGranted.value

        userID = user._id
        if userID in policyGrantedTo or user.is_admin():
            return

        memberOf = ['everyone']
        memberOf.extend(user.memberof.value)
        if hasattr(user, 'authenticate'):
            memberOf.append('authusers')

        for groupid in memberOf:
            if groupid in policyGrantedTo:
                return

        raise exceptions.PermissionDenied(
            "This action is restricted due to policy '%s'" %
            policy.displayName.value)
Exemple #33
0
    def apply(context, item, registration, **kwargs):
        policyid = kwargs['policyid']
        policy = _db.get_item(policyid)
        user = context.user
        policyGrantedTo = policy.policyGranted.value

        userID = user._id
        if userID in policyGrantedTo or user.is_admin():
            return

        memberOf = ['everyone']
        memberOf.extend(user.memberof.value)
        if hasattr(user, 'authenticate'):
            memberOf.append('authusers')

        for groupid in memberOf:
            if groupid in policyGrantedTo:
                return

        raise exceptions.PermissionDenied(
            "This action is restricted due to policy '%s'" %
            policy.displayName.value)
Exemple #34
0
    def execute_command(self, cmd, request):
        try:
            # DB maintenance commands
            if cmd == 'DB_BACKUP':
                output_file = request.data
                if not os.path.isdir(os.path.dirname(output_file)):
                    raise IOError
                services.lock_db()
                try:
                    _db.backup(output_file)
                finally:
                    services.unlock_db()
                return (0, 'Database backup completed successfully.')

            elif cmd == 'DB_RESTORE':
                backup_set = request.data
                if not os.path.exists(backup_set):
                    raise IOError
                services.lock_db()
                services.close_db()
                try:
                    _db.restore(backup_set)
                finally:
                    services.open_db()
                    services.unlock_db()
                return (0, 'Database restore completed successfully.')

            elif cmd == 'DB_SHRINK':
                iLogs = _db.shrink()
                if iLogs:
                    return (0, 'Successfully removed %d log files.' % iLogs)
                else:
                    return (0, 'No log files removed.')

            # package management commands
            elif cmd == 'PACKAGE':
                ini_file = request.data
                my_pkg = None
                try:
                    my_pkg = Package(ini_file=ini_file)
                    my_pkg.create()
                finally:
                    if my_pkg is not None:
                        my_pkg.close()
                return (0, 'The package "%s-%s.ppf" was created succefully.'
                        % (my_pkg.name, my_pkg.version))

            elif cmd == 'INSTALL':
                # some scripts might require a security context
                from porcupine import context
                ppf_file = request.data
                my_pkg = None
                try:
                    my_pkg = Package(package_file=ppf_file)
                    # install as system
                    context.user = _db.get_item('system')
                    my_pkg.install()
                finally:
                    if my_pkg is not None:
                        my_pkg.close()
                    context.user = None
                return (0, 'The package "%s" was installed succefully.'
                        % ppf_file)

            elif cmd == 'UNINSTALL':
                # some scripts might require a security context
                from porcupine import context
                ppf_file = request.data
                my_pkg = None
                try:
                    my_pkg = Package(package_file=ppf_file)
                    # uninstall as system
                    context.user = _db.get_item('system')
                    my_pkg.uninstall()
                finally:
                    if my_pkg is not None:
                        my_pkg.close()
                    context.user = None
                return (0, 'The package "%s" was uninstalled succefully.'
                        % ppf_file)

            # replication commands
            elif cmd == 'SITE_INFO':
                rep_mgr = _db.get_replication_manager()
                if rep_mgr is not None:
                    site_list = list(rep_mgr.get_site_list().values())
                    site_list.append(
                        rep_mgr.local_site.address + (1,))
                    #print site_list
                    info = [str.format('{0:25}{1:10}{2:6}',
                                      'SITE', 'STATUS', 'MASTER'),
                            '-' * 41]
                    for site in site_list:
                        site_address = site[:2]
                        if site[2] == 1:
                            s = 'ONLINE'
                        else:
                            s = 'OFFLINE'
                        if rep_mgr.master and \
                                rep_mgr.master.address == site_address:
                            m = 'X'
                        else:
                            m = ''
                        info.append(str.format('{0:25}{1:10}{2:6}',
                                               site_address, s, m))

                    info.append('')
                    info.append('Total sites: %d' % len(site_list))
                    return (0, '\n'.join(info))
                else:
                    raise NotImplementedError

            elif cmd == 'REP_JOIN_SITE':
                rep_mgr = _db.get_replication_manager()
                if rep_mgr is not None:
                    site = request.data
                    #print('adding remote site %s' % (site.address, ))
                    site_list = rep_mgr.sites.values() + [rep_mgr.local_site]
                    rep_mgr.broadcast(MgtMessage('REP_ADD_REMOTE_SITE', site))
                    rep_mgr.add_remote_site(site)
                    return (0, [rep_mgr.master, site_list])
                else:
                    raise NotImplementedError

            elif cmd == 'REP_ADD_REMOTE_SITE':
                rep_mgr = _db.get_replication_manager()
                if rep_mgr is not None:
                    site = request.data
                    #print('adding remote site %s' % (site.address, ))
                    rep_mgr.add_remote_site(site)
                    return (0, None)
                else:
                    raise NotImplementedError

            elif cmd == 'REP_NEW_MASTER':
                rep_mgr = _db.get_replication_manager()
                if rep_mgr is not None:
                    master = request.data
                    #print('new master is %s' % (master.address, ))
                    rep_mgr.master = master
                    services.notify(('NEW_MASTER', master))
                    return (0, None)
                else:
                    raise NotImplementedError

            # other
            elif cmd == 'RELOAD':
                mod = misc.get_rto_by_name(request.data)
                misc.reload_module_tree(mod)
                services.notify(('RELOAD_PACKAGE', request.data))
                return (0, 'Reloaded module tree "%s"' % request.data)

            # unknown command
            else:
                logger.warning(
                    'Management service received unknown command: %s' % cmd)
                return (-1, 'Unknown command.')

        except IOError:
            return (-1, 'Invalid file path.')
        except NotImplementedError:
            return (-1, 'Unsupported command.')
Exemple #35
0
 def apply(context, item, registration, **kwargs):
     user = _db.get_item(kwargs['userid'])
     context.original_user = context.user
     context.user = user
Exemple #36
0
    def handle_request(self, rh, raw_request=None):
        if raw_request is None:
            raw_request = loads(rh.input_buffer)
        response = context.response = HttpResponse()
        request = context.request = HttpRequest(raw_request)

        item = None
        registration = None

        # get sessionid
        session_id = None
        cookies_enabled = True
        path_info = request.serverVariables['PATH_INFO']

        #print(path_info)

        # detect if sessionid is injected in the URL
        session_match = re.match(self._sid_pattern, path_info)
        if session_match:
            path_info = path_info.replace(session_match.group(), '', 1) or '/'
            request.serverVariables['PATH_INFO'] = path_info
            session_id = session_match.group(1)
            cookies_enabled = False
        # otherwise check cookie
        elif '_sid' in request.cookies:
            session_id = request.cookies['_sid'].value
            cookies_enabled = True

        try:
            try:
                path_tokens = path_info.split('/')

                if len(path_tokens) > 1:
                    dir_name = path_tokens[1]
                    web_app = pubdirs.dirs.get(dir_name, None)
                else:
                    web_app = None

                if web_app is None:
                    # create snapshot txn for reads
                    context._trans = _db.get_transaction(snapshot=True)
                    # try to get the requested object from the db
                    item = _db.get_item(path_info)
                    if item is not None and not item._isDeleted:
                        self._fetch_session(session_id, cookies_enabled)
                        self._dispatch_method(item)
                    else:
                        raise exceptions.NotFound(
                            'The resource "%s" does not exist' % path_info)
                else:
                    # request to a published directory
                    self._fetch_session(session_id, cookies_enabled)

                    # remove blank entry & app name to get the requested path
                    dir_path = '/'.join(path_tokens[2:])
                    registration = web_app.get_registration(
                        dir_path,
                        request.serverVariables['REQUEST_METHOD'],
                        request.serverVariables['HTTP_USER_AGENT'],
                        request.get_lang())
                    if not registration:
                        raise exceptions.NotFound(
                            'The resource "%s" does not exist' % path_info)

                    # apply pre-processing filters
                    [filter[0].apply(context, item, registration, **filter[1])
                     for filter in registration.filters
                     if filter[0].type == 'pre']

                    rtype = registration.type
                    if rtype == 1:  # psp page
                        # create snapshot txn for reads
                        context._trans = _db.get_transaction(snapshot=True)
                        ServerPage.execute(context, registration.context)
                    elif rtype == 0:  # static file
                        f_name = registration.context
                        if_none_match = request.HTTP_IF_NONE_MATCH
                        if if_none_match is not None and if_none_match == \
                                '"%s"' % misc.generate_file_etag(f_name):
                            response._code = 304
                        else:
                            response.load_from_file(f_name)
                            if not any([f[0].mutates_output
                                        for f in registration.filters
                                        if f[0].type == 'post']):
                                response.set_header(
                                    'ETag', '"%s"' %
                                    misc.generate_file_etag(f_name))
                            if registration.encoding:
                                response.charset = registration.encoding

            except exceptions.ResponseEnd as e:
                pass

            if registration is not None and response._code == 200:
                # do we have caching directive?
                if registration.max_age:
                    response.set_expiration(registration.max_age)
                # apply post-processing filters
                [filter[0].apply(context, item, registration, **filter[1])
                 for filter in registration.filters
                 if filter[0].type == 'post']

        except exceptions.InternalRedirect as e:
            lstPathInfo = e.args[0].split('?')
            raw_request['env']['PATH_INFO'] = lstPathInfo[0]
            if len(lstPathInfo) == 2:
                raw_request['env']['QUERY_STRING'] = lstPathInfo[1]
            else:
                raw_request['env']['QUERY_STRING'] = ''
            self.handle_request(rh, raw_request)

        except exceptions.DBReadOnly:
            context._teardown()
            # proxy request to master
            rep_mgr = _db.get_replication_manager()
            if rep_mgr.master is not None:
                master_addr = rep_mgr.master.req_address
                master_request = BaseRequest(rh.input_buffer)
                try:
                    master_response = master_request.get_response(master_addr)
                except:
                    pass
                else:
                    rh.write_buffer(master_response)
                    return

            e = exceptions.InternalServerError('Database is in read-only mode')
            e.output_traceback = False
            e.emit(context, item)

        except exceptions.PorcupineException as e:
            e.emit(context, item)

        except:
            e = exceptions.InternalServerError()
            e.emit(context, item)

        context._teardown()
        settings['requestinterfaces'][request.interface](rh, response)