def process(self): """ Working through the process chain. This method returns either a dictionary for a folder node containing objects implementing the L{IResource} interface or a single object for a leaf node, like a file or document resource. """ if isinstance(self.path, unicode): raise TypeError("URL must be a str instance, not unicode!") # unquote url self.path = urllib.unquote(self.path) # check for URI length if len(self.path) >= MAXIMAL_URL_LENGTH: raise SeisHubError(code=http.REQUEST_URI_TOO_LONG) # post process path self.postpath = splitPath(self.path) # we like upper case method names self.method = self.method.upper() # check for valid methods if self.method not in ALLOWED_HTTP_METHODS: msg = 'HTTP %s is not implemented.' % self.method raise SeisHubError(code=http.NOT_ALLOWED, message=msg) # read content self.content.seek(0, 0) self.data = self.content.read() # easy args handler for id in self.args: if not len(self.args[id]): continue self.args0[id] = self.args[id][0] return self.render()
def __init__(self, schema_data, schema_type='XMLSchema'): f = StringIO(schema_data) schema_doc = etree.parse(f) if schema_type not in ['XMLSchema', 'RelaxNG', 'Schematron']: raise SeisHubError("Invalid schema type: %s" % schema_type) try: func = getattr(etree, schema_type) self.schema = func(schema_doc) except Exception, e: msg = "Could not parse a schema %s" raise SeisHubError(msg % (e.message))
def db_deleteResourceType(self, package_id, resourcetype_id): # XXX: workaround to check if there are any dependencies on this object # as not all dbs are supporting foreign keys if not self._is_resourcetype_deletable(package_id, resourcetype_id): raise SeisHubError(("Resourcetype with id '%s' in package '%s' " + \ "cannot be deleted due to other objects " + \ "depending on it.") % \ (str(resourcetype_id), str(package_id))) kwargs = dict() package = self.db_getPackages(package_id)[0] if not package: raise SeisHubError('Package not present in database: %s', str(package_id)) kwargs['package'] = package kwargs['resourcetype_id'] = resourcetype_id self.drop(ResourceTypeWrapper, **kwargs)
def render_GET(self, request): func = getattr(self.mapper, 'process_GET') if not func: msg = "Method process_GET is not implemented." raise NotImplementedError(msg) result = func(request) # result must be either a string or a dictionary of categories and ids if isinstance(result, basestring): # ensure we return a utf-8 encoded string not an unicode object if isinstance(result, unicode): result = result.encode('utf-8') # set content-type to plain text if nothing is returned if not result: request.setHeader('content-type', 'text/plain; charset=UTF-8') return result elif isinstance(result, dict): # dictionary of categories and ids for this category temp = {} for category, ids in result.items(): if category in ['folder']: folderish = True else: folderish = False for id in ids: temp[id] = self._clone(folderish=folderish) return temp msg = "A mapper must return a dictionary of categories and ids or " + \ "a basestring for a resulting document." raise SeisHubError(msg, code=http.INTERNAL_SERVER_ERROR)
def updateUser(self, id, name='', password='', uid=1000, institution='', email='', permissions=755): """ Modifies user information. """ if id not in self.passwords: raise SeisHubError("User does not exists!") session = self.Session() user = session.query(User).filter_by(id=id).one() user.name = name if password: self._validatePassword(password) user.password = hash(password) user.institution = institution user.email = email user.uid = uid user.permissions = permissions session.add(user) try: session.commit() except: session.rollback() self.refresh()
def checkPasswordHash(self, id, hash): """ Check current password hash. """ if id not in self.passwords: raise SeisHubError("User does not exists!") return self.passwords[id] == hash
def addUser(self, id, name, password, uid=1000, institution='', email='', permissions=755, checkPassword=True): """ Adds an user. """ if id in self.passwords: raise DuplicateObjectError("User already exists!") if checkPassword: self._validatePassword(password) user = User(id=id, uid=uid, name=name, password=hash(password), institution=institution, email=email, permissions=permissions) session = self.Session() session.add(user) try: session.commit() except Exception, e: session.rollback() raise SeisHubError(str(e))
def _validatePassword(self, password): """ All kind of password checks. """ min_length = self.env.config.getint('seishub', 'min_password_length') if len(password) < min_length: raise SeisHubError("Password is way too short!")
def render_MOVE(self, request): """ Processes a resource move/rename request. @see: U{http://msdn.microsoft.com/en-us/library/aa142926(EXCHG.65).aspx} """ self._checkPermissions(request, 777) # seishub directory is not directly changeable if self.package_id == 'seishub': msg = "SeisHub resources may not be moved directly." raise ForbiddenError(msg) # test if destination is set destination = request.received_headers.get('Destination', False) if not destination: msg = "Expected a destination header." raise SeisHubError(msg, code=http.BAD_REQUEST) if not destination.startswith(request.env.getRestUrl()): if destination.startswith('http'): msg = "Destination URI is located on a different server." raise SeisHubError(msg, code=http.BAD_GATEWAY) msg = "Expected a complete destination path." raise SeisHubError(msg, code=http.BAD_REQUEST) # test size of destination URI if len(destination) >= MAXIMAL_URL_LENGTH: msg = "Destination URI is to long." raise SeisHubError(msg, code=http.REQUEST_URI_TOO_LONG) # strip host destination = destination[len(request.env.getRestUrl()):] # source URI and destination URI must not be the same value parts = splitPath(destination) if parts == request.prepath: msg = "Source URI and destination URI must not be the same value." raise ForbiddenError(msg) # test if valid destination path if len(parts) < 1 or parts[:-1] != request.prepath[:-1]: msg = "Destination %s not allowed." % destination raise ForbiddenError(msg) # rename resource request.env.catalog.renameResource(self.res, parts[-1]) # on successful creation - set status code and location header request.code = http.CREATED url = request.env.getRestUrl() + destination # won't accept Unicode request.headers['Location'] = str(url) return ''
def db_deletePackage(self, package_id): #XXX: workaround to check if there are any dependencies on this object # as not all dbs are supporting foreign keys if not self._is_package_deletable(package_id): raise SeisHubError(("Package with id '%s' cannot be deleted due " + \ "to other objects depending on it.") % \ (str(package_id))) self.drop(PackageWrapper, package_id=package_id)
def _is_resourcetype_deletable(self, package_id, resourcetype_id): try: self.db_getResourceTypes(package_id, resourcetype_id)[0] except IndexError: msg = "Resourcetype '%s' in package '%s' not present in database!" raise SeisHubError(msg % (str(resourcetype_id), str(package_id))) # XXX: check if schemas/stylesheets or aliases are present: # XXX: check if any catalog entries are present return True
def __getitem__(self, cls): """ Activate the component instance for the given class, or return the existing the instance if the component has already been activated. """ if cls not in self.enabled: self.enabled[cls] = self.isComponentEnabled(cls) if not self.enabled[cls]: return None component = self.components.get(cls) if not component: if cls not in ComponentMeta._components: raise SeisHubError('Component "%s" not registered' % cls.__name__) try: component = cls(self) except TypeError, e: raise SeisHubError('Unable to instantiate component %r (%s)' % (cls, e))
def getPackage(self, package_id): """ Returns a single package object. """ pkg = self.getComponents(IPackage, package_id) if not pkg: msg = "Package with id '%s' not found. " % (package_id) msg += "Make sure the package has been enabled." raise SeisHubError(msg) return pkg[0]
def delete(self, package_id=None, resourcetype_id=None, type=None, document_id=None, uri=None): o = self.get(package_id, resourcetype_id, type, uri=uri, document_id=document_id) if len(o) > 1: raise SeisHubError("Error deleting a schema or stylesheet: " + \ "Unexpected result set length.") if len(o) == 0: raise SeisHubError("Error deleting a schema or stylesheet: " + \ "No objects found with the given parameters.") self.catalog.deleteResource(resource_id=o[0].resource._id) self.drop(self.cls, document_id=o[0].document_id) return True
def _is_package_deletable(self, package_id): try: self.db_getPackages(package_id)[0] except IndexError: raise SeisHubError('Package not present in database: %s', str(package_id)) # check if any resourcetype is present: resourcetypes = self.db_getResourceTypes(package_id) if len(resourcetypes) > 0: return False # XXX: check if schemas/stylesheets or aliases are present: # XXX: check if any catalog entries are present return True
def _split_uri(self, uri): resourcetype_id = None type = None args = uri.split('/') package_id = args[1] if len(args) == 3: # no type resourcetype_id = args[2] elif len(args) == 4: resourcetype_id = args[2] type = args[3] else: raise SeisHubError("Invalid URL: %s" % uri) return package_id, resourcetype_id, type
def db_registerResourceType(self, package_id, resourcetype_id, version='', version_control=False): try: package = self.db_getPackages(package_id)[0] except IndexError: raise SeisHubError('Package not present in database: %s' % \ str(package_id)) o = ResourceTypeWrapper(resourcetype_id, package, version, version_control) self.store(o) return o
def validate(self, xml_doc): if not IXmlDoc.providedBy(xml_doc): raise DoesNotImplement(IXmlDoc) doc = xml_doc.getXml_doc() try: self.schema.assertValid(doc) except AttributeError: valid = self.schema.validate(doc) if not valid: msg = "Could not validate document." raise SeisHubError(msg) except etree.DocumentInvalid, e: msg = "Could not validate document. (%s)" raise InvalidObjectError(msg % str(e))
class XmlIndexCatalog(DbStorage, _QueryProcessor, _IndexView): """ A catalog of indexes. Most methods use XMLIndex objects as input parameters. You may use the getIndexes methods to query for valid XMLIndex objects. """ def __init__(self, db, resource_storage=None): DbStorage.__init__(self, db) self._db_manager = db self._storage = resource_storage self.refreshIndexCache() def refreshIndexCache(self): """ Refreshs the index cache. """ self._cache = {} # get all indexes indexes = self.pickup(XmlIndex) for idx in indexes: self._addToCache(idx) def _addToCache(self, xmlindex): """ Adds a given XMLIndex to the index cache. """ self._cache[xmlindex._id] = xmlindex def _deleteFromCache(self, xmlindex): """ Deletes a given XMLIndex from the index cache. """ self._cache.pop(xmlindex._id, None) def registerIndex(self, xmlindex): """ Register a given XMLIndex object into the XMLIndexCatalog. """ if not IXmlIndex.providedBy(xmlindex): raise DoesNotImplement(IXmlIndex) try: self.store(xmlindex) except DbError, e: msg = "Error registering an index: Index '%s' already exists." raise DuplicateObjectError(msg % str(xmlindex), e) except Exception, e: msg = "Error registering an index: %s" raise SeisHubError(msg % str(xmlindex), e)
def _deleteUser(self, args): """ Delete one or multiple users. """ data = {} id = args.get('id', [''])[0] if not id: data['error'] = "No user selected." else: try: self.auth.deleteUser(id=id) except SeisHubError(), e: # checks are made in self.auth.deleteUser method data['error'] = str(e) except Exception, e: self.log.error("Error deleting user", e) data['error'] = "Error deleting user", e
def register(self, package_id, resourcetype_id, type, xml_data, name=None): """ Register a schema. @param package_id: package id @type package_id: str @param resourcetype_id: resourcetype id @type resourcetype_id: str @param type: type / additional label @type type: str @param xml_data: Xml data of schema. @type xml_data: str @param name: optional resource name @type name: str """ if not resourcetype_id: raise SeisHubError("Schemas must have a resourcetype.") return RegistryBase.register(self, package_id, resourcetype_id, type, xml_data, name)
def getUser(self, id): if id not in self.passwords: raise SeisHubError("User does not exists!") session = self.Session() return session.query(User).filter_by(id=id).one()