예제 #1
0
    def getByID(node_id):
        # TODO: does user have access to this node?

        try:
            id = int(node_id)
            result = db.run(
                "MATCH (d:Data)--(t:SchemaType)--(r:Repository) WHERE ID(d) = {node_id} RETURN d, t.name as typename, t.code as typecode, ID(t) as schema_id, ID(r) as repo_id",
                {"node_id": id})
        except:
            result = db.run(
                "MATCH (d:Data)--(t:SchemaType)--(r:Repository) WHERE d.uuid = {uuid} RETURN d, ID(d) as node_id, t.name as typename, t.code as typecode, ID(t) as schema_id, ID(r) as repo_id",
                {"uuid": node_id})

        if result.peek():
            for r in result:
                return {
                    "node_id": r["node_id"],
                    "typename": r["typename"],
                    "typecode": r["typecode"],
                    "schema_id": r["schema_id"],
                    "repo_id": r["repo_id"],
                    "data": r["d"].properties
                }
        else:
            raise FindError(message="Node does not exist")
예제 #2
0
    def deleteListItem(repo_id, code, item_id):
        try:
            repo_id = int(repo_id)
        except TypeError:
            raise DbError(message="Invalid repo_id provided",
                          context="List.deleteListItem",
                          dberror="")
        try:
            result = db.run(
                "MATCH (r:Repository)--(l:List {code: {code}})-[x]-(i:ListItem) WHERE ID(r) = {repo_id} AND ID(i) = {item_id} DELETE i,x",
                {
                    "repo_id": int(repo_id),
                    "item_id": int(item_id),
                    "code": code
                })

            if result is not None:
                return True
            else:
                raise FindError(message="Could not find list item",
                                context="List.deleteListItem",
                                dberror="")
        except Exception as e:
            raise DbError(message="Could not delete list item",
                          context="List.deleteListItem",
                          dberror=e.message)
예제 #3
0
    def deleteType(repo_id, type_id):
        # TODO validate params

        # TODO: check that repository is owned by current user

        try:
            result = db.run(
                "MATCH (t:SchemaType)-[x]-(r:Repository) WHERE ID(r) = {repo_id} AND ID(t) = {type_id} OPTIONAL MATCH (f:SchemaField)-[y]-(t) OPTIONAL MATCH (d:Data)-[z]-(t) DELETE x,y,t,f,z,d",
                {
                    "type_id": int(type_id),
                    "repo_id": int(repo_id)
                })
            print "type=" + type_id
            print "repo=" + repo_id
            if result is not None:
                SchemaManager.resetTypeInfoCache()
                return {"type_id": type_id}
            else:
                raise FindError(message="Could not find type",
                                context="Schema.deleteType",
                                dberror="")
        except Exception as e:
            raise DbError(message="Could not delete type",
                          context="Schema.deleteType",
                          dberror=e.message)
예제 #4
0
    def deleteField(repo_id, typecode, field_id):
        # TODO validate params

        # TODO: check that repository is owned by current user
        SchemaManager.resetTypeInfoCache()

        try:
            result = db.run(
                "MATCH (r:Repository)--(t:SchemaType {code: {typecode}})-[x]-(f:SchemaField) WHERE ID(r) = {repo_id} AND ID(f) = {field_id} DELETE f,x",
                {
                    "repo_id": int(repo_id),
                    "field_id": int(field_id),
                    "typecode": typecode
                })

            if result is not None:
                return True
            else:
                raise FindError(message="Could not find field",
                                context="Schema.deleteField",
                                dberror="")
        except Exception as e:
            raise DbError(message="Could not delete field",
                          context="Schema.deleteField",
                          dberror=e.message)
예제 #5
0
    def delete(repo_id):
        RepoManager.validate_repo_id(repo_id)

        owner = RepoManager.getOwner(repo_id)

        result = db.run(
            "MATCH (n:Repository) WHERE ID(n) = {repo_id} WITH n OPTIONAL MATCH (n)--(s:SchemaType)--(f:SchemaField) WITH n, s, f OPTIONAL MATCH (s)--(d:Data) DETACH DELETE n, s, f, d",
            {"repo_id": repo_id})
        summary = result.consume()

        # Was this the only repo for that owner?
        if "id" in owner:
            repos = lib.managers.PeopleManager.PeopleManager.getRepos(
                owner["id"])
            if len(repos) == 0:
                # create new default repo because user just deleted their only one.
                RepoManager.create(
                    app_config['default_repo_information']['url'],
                    app_config['default_repo_information']['name'],
                    app_config['default_repo_information']['description'],
                    app_config['default_repo_information']['license'], 0,
                    owner['id'], "ID(p) = {identity}")

        if summary.counters.nodes_deleted >= 1:
            return True

        raise FindError(message="Could not find repository",
                        context="Repositories.delete")
예제 #6
0
    def getReposForPerson(identity):
        repos = PeopleManager.getRepos(identity)
        user = PeopleManager.getInfo(identity)

        if repos is not None:
            return {"repos": repos, "userinfo": user}

        raise FindError(message="Could not find person",
                        context="People.getReposForPerson")
예제 #7
0
 def checkRepoPermissions(user_name, repo_id):
     repo_list = PeopleManager.getRepoIDs(user_name)
     print repo_list, repo_id
     try:
         repo_id = int(repo_id)
     except:
         raise FindError(message="Need integer repo_id",
                         context="People.checkRepoPermissions")
     if repo_id in repo_list:
         return True
     return False
예제 #8
0
    def getRepoForPortal(repo_uuid):
        try:
            result = db.run(
                "MATCH (r:Repository {uuid: {uuid}}) RETURN ID(r) AS id, r.name as name, r.readme as description",
                {
                    "uuid": repo_uuid
                }).peek()
            if result:
                repo_id = result['id']
                name = result['name']
                description = result['description']
        except:
            raise FindError("Could not load repository with UUID")

        repo_owner = RepoManager.getOwner(repo_id)
        owner_name = repo_owner['name']
        owner_location = repo_owner['location']
        owner_tagline = repo_owner['tagline']

        data = RepoManager.getData(repo_id, 48)

        return {
            "repo": repo_id,
            "repo_name": name,
            "description": description,
            "data": data,
            "owner": owner_name,
            "location": owner_location,
            "tagline": owner_tagline
        }

        #
        # ADMIN ONLY
        # Set a repository to be featured
        @staticmethod
        def setFeaturedRepo(repo_id, featured):
            RepoManager.validate_repo_id(repo_id)

            if int(featured) != 0 and int(featured) != 1:
                featured = 0

            result = db.run(
                "MATCH (r:Repository) WHERE ID(r)={repo_id} SET r.published = {featured} RETURN ID(r), r.featured as featured",
                {
                    "repo_id": int(repo_id),
                    "featured": featured
                }).peek()

            if result:
                if result['featured'] == featured:
                    return True

            return False
예제 #9
0
    def removeFollower(repo_id, person_id):
        RepoManager.validate_repo_id(repo_id)

        result = db.run(
            "START p=node(*) MATCH (p)-[rel:FOLLOWS]->(n) WHERE ID(p)={person_id} AND ID(n)={repo_id} DELETE rel",
            {
                "person_id": person_id,
                "repo_id": repo_id
            })

        summary = result.consume()
        if summary.counters.relationship_deleted >= 1:
            return True

        raise FindError(message="Could not find person",
                        context="Repositories.removeFollower")
예제 #10
0
    def getRepositoryByCode(code):
        result = db.run(
            "MATCH (r:Repository {name: {code}}) RETURN ID(r) AS id, r.name AS  name",
            {"code": code})

        ret = {}

        if result:
            for r in result:
                ret['repo_id'] = r['id']
                ret['name'] = r['name']
                return ret
        else:
            raise FindError("Could not find repository")

        return ret
예제 #11
0
    def addFollower(repo_id, person_id):
        RepoManager.validate_repo_id(repo_id)

        result = db.run(
            "MATCH (n:Repository) WHERE ID(n)={repo_id} MATCH (p:Person) WHERE ID(p)={person_id} MERGE (p)-[:FOLLOWS]->(n)",
            {
                "repo_id": repo_id,
                "person_id": person_id
            })

        summary = result.consume()
        if summary.counters.relationships_created >= 1:
            return True

        raise FindError(message="Could not find person or repository",
                        context="Repositories.addFollower")
예제 #12
0
    def addCollaborator(repo_id, person_id, access="read-only"):
        RepoManager.validate_repo_id(repo_id)

        result = db.run(
            "MATCH (n:Repository) WHERE ID(n)={repo_id} MATCH (p:Person) WHERE ID(p)={person_id} MERGE (p)-[x:COLLABORATES_WITH]->(n) ON CREATE SET x.access = {access}",
            {
                "repo_id": repo_id,
                "person_id": person_id,
                "access": access
            })

        summary = result.consume()
        if summary.counters.relationships_created >= 1:
            return True
        raise FindError(message="Already exists",
                        context="Repositories.addCollaborator")
예제 #13
0
    def deleteOwner(repo_id, owner_id):
        RepoManager.validate_repo_id(repo_id)

        result = db.run(
            "START p=node(*) MATCH (p)-[rel:OWNED_BY]->(n) WHERE ID(p)={owner_id} AND ID(n)={repo_id} DELETE rel",
            {
                "owner_id": owner_id,
                "repo_id": repo_id
            })

        summary = result.consume()
        if summary.counters.relationships_deleted >= 1:
            return True

        raise FindError(message="Could not find person or repository",
                        context="Repositories.deleteOwner")
예제 #14
0
    def setOwner(repo_id, identity, ident_str):
        RepoManager.validate_repo_id(repo_id)

        result = db.run(
            "MATCH (n:Repository) WHERE ID(n)={repo_id} MATCH (p:Person) WHERE "
            + ident_str + " MERGE (p)<-[:OWNED_BY]->(n)", {
                "repo_id": repo_id,
                "identity": identity
            })

        summary = result.consume()
        if summary.counters.relationships_created >= 1:
            return True
        else:
            raise FindError(message="Could not find person",
                            context="Repositories.setOwner")
예제 #15
0
    def deletePerson(person_id):
        try:
            result = db.run(
                "MATCH (n:Person) WHERE ID(n)={person_id} OPTIONAL MATCH (n)-[r]-() DELETE r,n",
                {"person_id": person_id})
        except Exception as e:
            raise DbError(message="Could not delete person",
                          context="People.deletePerson",
                          dberror=e.message)

            # Check that we deleted something
        summary = result.consume()
        if summary.counters.nodes_deleted >= 1:
            return True

        raise FindError(message="Could not find person",
                        context="People.deletePerson")
예제 #16
0
    def deleteList(repo_id, list_id):
        try:
            result = db.run(
                "MATCH (l:List)-[x]-(r:Repository) WHERE ID(r) = {repo_id} AND ID(l) = {list_id} OPTIONAL MATCH (i:ListItem)-[y]-(l) DELETE x,y,l,i",
                {
                    "list_id": int(list_id),
                    "repo_id": int(repo_id)
                })

            if result is not None:
                return {"list_id": list_id}
            else:
                raise FindError(message="Could not find list",
                                context="Schema.deleteList",
                                dberror="")
        except Exception as e:
            raise DbError(message="Could not delete list",
                          context="Schema.deleteList",
                          dberror=e.message)
예제 #17
0
    def setPassword(person_id, password):
        # TODO: verify user has access to update password...
        if password is not None:
            if is_number(person_id):
                find_str = "ID(p)={person_id}"
            else:
                find_str = "p.password_reset_key = {person_id}"

            db_password_hash = ''
            # check if password matches person_id
            result = db.run(
                "MATCH (p:Person) WHERE " + find_str +
                " RETURN p.password AS password", {"person_id": person_id})
            for p in result:
                db_password_hash = p['password']

            if db_password_hash != '':
                # hash new password and update DB
                new_pass_hash = sha256_crypt.hash(password)

                if db_password_hash == new_pass_hash:
                    return True

                result = db.run(
                    "MATCH (p:Person) WHERE " + find_str +
                    " SET p.password = {new_pass_hash}, p.password_reset_key = '' RETURN p",
                    {
                        "person_id": person_id,
                        "new_pass_hash": new_pass_hash
                    })

                # Check we updated something
                summary = result.consume()
                if summary.counters.properties_set >= 1:
                    return True
                return False

            else:
                raise FindError("No user found")

        else:
            raise AuthError("Password is empty")
예제 #18
0
    def editPerson(identity, forename, surname, location, email, url, tagline,
                   is_disabled, nyunetid):
        if is_number(identity):
            ident_str = "ID(p)={identity}"
            identity = int(identity)
        else:
            ident_str = "p.email={identity}"

        update = []
        if forename is not None:
            update.append("p.forename = {forename}")

        if surname is not None:
            update.append("p.surname = {surname}")

        if location is not None:
            update.append("p.location = {location}")

        if email is not None:
            update.append("p.email = {email}")

        if url is not None:
            update.append("p.url = {url}")

        if tagline is not None:
            update.append("p.tagline = {tagline}")

        if nyunetid is not None:
            update.append("p.nyunetid = {nyunetid}")

        if is_disabled is not None:
            print is_disabled
            try:
                is_disabled = int(is_disabled)
                if is_disabled <> 0:
                    is_disabled = 1
                update.append("p.is_disabled = {is_disabled}")
            except:
                pass

        update_str = "%s" % ", ".join(map(str, update))

        if update_str != '' and update_str is not None:
            result = db.run(
                "MATCH (p:Person) WHERE " + ident_str + " SET " + update_str +
                " RETURN p.forename AS forename, p.surname AS surname, p.location AS location, p.email AS email, p.url AS url, p.tagline AS tagline, p.is_disabled AS is_disabled, p.nyunetid AS nyunetid",
                {
                    "identity": identity,
                    "forename": forename,
                    "surname": surname,
                    "location": location,
                    "email": email,
                    "url": url,
                    "tagline": tagline,
                    "is_disabled": is_disabled,
                    "nyunetid": nyunetid
                })

            if result:
                updated_person = {}
                for p in result:
                    updated_person['forename'] = p['forename']
                    updated_person['surname'] = p['surname']
                    updated_person['name'] = str(p['forename']) + " " + str(
                        p['surname'])
                    updated_person['location'] = p['location']
                    updated_person['email'] = p['email']
                    updated_person['url'] = p['url']
                    updated_person['tagline'] = p['tagline']
                    updated_person['is_disabled'] = p['is_disabled']
                    updated_person['nyunetid'] = p['nyunetid']

                if updated_person is not None:
                    return updated_person
                else:
                    raise FindError(message="Person does not exist",
                                    context="People.editPerson")

            else:
                raise DbError(message="Could not update person",
                              context="People.editPerson",
                              dberror="")
        else:
            raise ValidationError(message="Nothing to update",
                                  context="People.editPerson")
예제 #19
0
    def _validateData(repo_id, type_code, data, fields_created=None):
        type_info = SchemaManager.getInfoForType(repo_id, type_code)
        if type_info is None:
            raise FindError("Could not load type info")

        # gather data
        data_proc = {}
        row_errors = []
        for f in type_info["fields"]:
            v = None
            if f['code'] in data:
                v = data[f['code']]
            if v is None and f['id'] in data:
                v = data[f['id']]

            # Convert data-as-dict to JSON for serialized storage
            if isinstance(v, dict):
                v = json.dumps(v)

            if v is not None and isinstance(v, unicode) is False:
                if isinstance(
                        v, basestring
                ) is False:  # force non-string values to string prior to casting to unicode
                    v = str(v)
                v = unicode(v, errors='replace')
            if v is not None and v != '':
                dt = SchemaManager.getDataTypeInstanceForField(
                    repo_id, type_code, f["code"], v)
                dtv = dt.validate(v)
                if dtv is not True:
                    row_errors.append(f['code'])
                    continue

                # Parse the data using the relevant datatype plugin
                # NOTE: If the datatype parser returns a dict we serialize to Neo4j with properties for each key
                # in the dict. This allows data types to serialize data across multiple node properties if required.
                # This is distinct from the case where the caller submits a dict as data. In that case we convert it to
                # JSON prior to performing any parsing.
                if f['type'] == 'ListDataType':
                    list_code = f['settings']['list_code']
                    override_merge = False
                    if fields_created:
                        new_fields = [
                            x + "_list" for x in fields_created.keys()
                        ]
                        if list_code in new_fields:
                            override_merge = True
                    parsed_value = dt.parse(v, list_code, repo_id,
                                            override_merge)
                    if len(parsed_value['rejected_items']) > 0:
                        bad_items = "The following items do not appear in the current list and merges are not allowed: " + ', '.join(
                            parsed_value['rejected_items'])
                        row_errors.append(f['code'] + ' ' + bad_items)
                else:
                    parsed_value = dt.parse(v)

                # If a dict is returned we need to stored parsed value in multiple fields
                if isinstance(parsed_value, dict):
                    data_proc[f['code']] = v
                    for k, v in parsed_value.iteritems():
                        data_proc[f['code'] + "_" + k] = v
                else:
                    # simple scalar value is assigned direct
                    data_proc[f['code']] = parsed_value
                SchemaManager.getDataTypeInstanceForField.reset()
            else:
                data_proc[f['code']] = v
            if len(row_errors) > 0:
                raise FieldValidationError(message="Data is invalid for " +
                                           ", ".join(row_errors),
                                           errors=dtv,
                                           type=type_info['code'],
                                           field=f['code'],
                                           value=v,
                                           context="DataManager.add")
        return [data_proc, type_info]
예제 #20
0
    def edit(repo_id, name, url, readme, license, published, featured):
        if url is None or name is None or readme is None:
            raise ValidationError(message="Name, URL and README must be set",
                                  context="Repositories.edit")

        if RepoManager.nameCheck(name, repo_id) is False:
            raise ValidationError(message="Name is in use",
                                  context="Repositories.edit")

        update = []
        if name is not None:
            update.append("n.name = {name}")

        if url is not None:
            update.append("n.url = {url}")

        if readme is not None:
            update.append("n.readme = {readme}")

        if featured is not None:
            update.append("n.featured = {featured}")

        published_on = None
        if ((int(published) != 0) and
            (int(published) != 1)) or published is None:
            published = 0
        elif int(published) == 1:
            ts = time.time()
            published_on = datetime.datetime.fromtimestamp(ts).strftime(
                '%Y-%m-%d %H:%M:%S')
            update.append("n.published_on = {published_on}")
        if license not in RepoManager.licenses:
            license = ''

        update.append("n.published = {published}")
        update.append("n.license = {license}")

        update_str = "%s" % ", ".join(map(str, update))

        if update_str:
            print update_str, featured
            result = db.run(
                "MATCH (n:Repository) WHERE ID(n)={repo_id} SET " +
                update_str +
                " RETURN n.name AS name, n.url AS url, n.readme AS readme, n.license AS license, n.published AS published, n.featured as featured, n.published_on as published_on, ID(n) AS id",
                {
                    "repo_id": int(repo_id),
                    "name": name,
                    "url": url,
                    "readme": readme,
                    "published": published,
                    "license": license,
                    "featured": featured,
                    "published_on": published_on
                })

            updated_repo = {}
            for r in result:
                print r
                updated_repo['repo_id'] = r['id']
                updated_repo['name'] = r['name']
                updated_repo['url'] = r['url']
                updated_repo['readme'] = r['readme']
                updated_repo['license'] = r['license']
                updated_repo['published'] = r['published']
                updated_repo['published_on'] = r['published_on']
                updated_repo['featured'] = r['featured']

            summary = result.consume()
            if summary.counters.properties_set >= 1:
                return updated_repo

            raise FindError(message="Could not find repository",
                            context="Repositories.edit")