class Profile(StructuredNode): @classmethod def category(cls): pass poster_username = StringProperty() poster_profile_url = StringProperty() poster_profile_id = IntegerProperty() aim = StringProperty() activity = IntegerProperty() age = IntegerProperty() date_registered = IntegerProperty() email = EmailProperty() gender = StringProperty() icq = StringProperty() last_active = DateProperty() location = StringProperty() msn = StringProperty() merit = StringProperty() position = StringProperty() post_count = IntegerProperty() signature = StringProperty() website = StringProperty() yim = StringProperty() posted = RelationshipTo('Post', 'written')
class Employee(StructuredNode): name = StringProperty(unique_index=True, max_length=50) photo_url = StringProperty(max_length=200) email = EmailProperty() education = StringProperty(max_length=50) department = RelationshipFrom( 'uemployees.department.models.Department', 'WORK_AT_DEPARTMENT', model=WorkAtDepartment ) disciplines = RelationshipTo( 'uemployees.discipline.models.Discipline', 'TEACH_A_DISCIPLINE', model=TeachDiscipline ) degrees = RelationshipTo( 'uemployees.degree.models.Degree', 'EMPLOYEE_HAS_DEGREE' ) interests = RelationshipTo( 'uemployees.interest.models.Interest', 'EMPLOYEE_HAS_APOI' ) publications = RelationshipTo( 'uemployees.publication.models.Publication', 'EMPLOYEE_HAS_PUBLICATION' )
class User(StructuredNode): uid = UniqueIdProperty() created_at = DateTimeProperty(default_now=True) modified_at = DateTimeProperty(default_now=True) name = StringProperty(required=True) email = EmailProperty(required=True, unique_index=True) password = StringProperty() comments = RelationshipFrom('comment.models.Comment', 'OWNED_BY') votes = RelationshipTo('comment.models.Comment', 'VOTED_FOR', model=VoteRelationship) @staticmethod def get_all(): return User.nodes @staticmethod def get(uid): return User.nodes.get_or_none(uid=uid) def set_password(self, password): self.password = bcrypt.generate_password_hash(password).decode('utf-8') def check_password(self, value): check = bcrypt.check_password_hash(self.password, value) return check def __repr__(self): return '<User({name!r})>'.format(name=self.name) @staticmethod def get_by_email(email): return User.nodes.get_or_none(email=email)
class EmailAddress(DjangoNode): uuid = UniqueIdProperty() value = EmailProperty() profile = RelationshipFrom(PROFILE_MODEL, HasEmailAddress.rel_name, model=HasEmailAddress)
class GlobusIdentityNode(StructuredNode): __label__ = 'GlobusIdentity' email = EmailProperty() globusId = StringProperty() name = StringProperty() organization = StringProperty() username = StringProperty() login = RelationshipTo('GlobusLoginNode', 'identityFrom')
class UserNode(StructuredNode): __label__ = 'User' email = EmailProperty(unique_index=True, required=True) firstName = StringProperty(required=True) lastName = StringProperty(required=True) team = RelationshipTo('TeamNode', 'memberOf', cardinality=cardinality.ZeroOrOne) token = RelationshipTo('GlobusLoginNode', 'auth', cardinality=cardinality.ZeroOrOne)
class User(StructuredNode): uid = UniqueIdProperty() fcm_id = StringProperty() token_bal = IntegerProperty() name = StringProperty() contact = StringProperty(unique_index=True) email = EmailProperty() knows = RelationshipTo('User', 'knows') create_date = DateTimeProperty(default=lambda: datetime.utcnow())
class InspectedTokenNode(StructuredNode): __label__= 'TokenDetails' email = EmailProperty(required=True, unique_index = True) name = StringProperty(required=True) username = StringProperty(required=True) exp = DateTimeProperty(required=True) iat = DateTimeProperty(required=True) identitiesSet = ArrayProperty() login = RelationshipTo('GlobusLoginNode', 'detailsFor')
class User(StructuredNode, flask_login.UserMixin): login = StringProperty(required=True, primary=True) password = StringProperty(required=True) email = EmailProperty() birth_date = DateProperty() owned_repositories = RelationshipTo("Repository", "OWNS") contributed_repositories = RelationshipTo("Repository", "CONTRIBUTED_TO", model=ContributedTo) recommended_repositories = RelationshipTo("Repository", "RECO") def get_id(self): return self.login
class User(StructuredNode): username = StringProperty(required=True, max_length=NAME_MAX_LEN, unique_index=True) email = EmailProperty(required=True, unique_index=True) password = StringProperty(required=True) first_name = StringProperty(required=True, max_length=NAME_MAX_LEN) last_name = StringProperty(required=True, max_length=NAME_MAX_LEN) birthdate = DateProperty(required=True) gender = StringProperty(required=True, choices=GENDERS) city = StringProperty(required=True, choices=CITIES) address = StringProperty(required=False, max_length=ADDRESS_MAX_LEN) role = StringProperty(required=True, choices=ROLES) authorized = BooleanProperty(default=False) reservations = RelationshipTo('Seat', 'RESERVED_A') token = RelationshipTo('Token', 'BEARS_A', cardinality=ZeroOrOne)
class Person(DjangoNode): email = EmailProperty(unique_index=True) friends = Relationship('Person', PersonRelationship._FRIEND, model=PersonRelationship) blocks = RelationshipTo('Person', PersonRelationship._BLOCK, model=PersonRelationship) # blocked_by = RelationshipFrom('Person', 'BLOCKED_BY') subscribes = RelationshipTo('Person', PersonRelationship._SUBSCRIBE, model=PersonRelationship) # subscribed_by = RelationshipFrom('Person', 'SUBSCRIBED_BY') created_by = StringProperty() created = DateTimeProperty(default=datetime.utcnow()) modified_by = StringProperty() modified = DateTimeProperty(default=datetime.utcnow()) # Get all the Person of relation_type of relation_direction @staticmethod def get_all_relation_of_type(person, relation_direction, relation_type): result = [] traversal_definition = dict(node_class=Person, direction=relation_direction, relation_type=relation_type, model=None) relations_traversal = Traversal(person, Person.__label__, traversal_definition) result = relations_traversal.all() return result # Get all the friends for a list of person nodes @staticmethod def get_common_friends(person_list): result = [] # We don't really know how to handle more than 2 persons at the moment query = "MATCH (n:Person)-[:FRIEND]-(friend:Person)-[:FRIEND]-(m:Person) \ WHERE n.email='%s' \ AND m.email='%s' \ RETURN DISTINCT friend.email \ ORDER BY friend.email ASC" % (person_list[0].email, person_list[1].email) result, meta = db.cypher_query(query) # We do not need to run the inflate method return result class Meta: # fields = ('email') app_label = 'friends'
class model(StructuredNode, grest.models.Node): GREEK = (("A", "Alpha"), ("B", "Beta"), ("G", "Gamma")) uuid = UniqueIdProperty() string = StringProperty(required=True) choices = StringProperty(choices=GREEK) integer = IntegerProperty() json = JSONProperty() array_of_string = ArrayProperty(StringProperty()) raw_data = ArrayProperty() date = DateProperty() datetime = DateTimeProperty() boolean = BooleanProperty() email = EmailProperty()
class Person(StructuredNode, models.Node): """ person model 1. (person)-[Manage_TO]->(Environment) 2. (person)-[Manage_TO]->(App) """ person_id = UniqueIdProperty() person_name = StringProperty() phone = StringProperty() email = EmailProperty() role = StringProperty() environment = RelationshipTo(Environment, "Manage_TO", model=EnvironmentInfo) app = RelationshipTo(App, "Manage_TO", model=AppInfo)
class User(UserCustomClass): email = EmailProperty(required=True, unique_index=True) name = StringProperty(required=True) surname = StringProperty(required=True) authmethod = StringProperty(required=True) password = StringProperty() mfa_hash = StringProperty() first_login = DateTimeProperty() last_login = DateTimeProperty() last_password_change = DateTimeProperty() is_active = BooleanProperty(default=True) privacy_accepted = BooleanProperty(default=True) expiration = DateTimeProperty() tokens = RelationshipTo("Token", "HAS_TOKEN", cardinality=ZeroOrMore) roles = RelationshipTo("Role", "HAS_ROLE", cardinality=ZeroOrMore) belongs_to = RelationshipTo("Group", "BELONGS_TO")
class TeamMember(StructuredNode): first_name = StringProperty(required=True) last_name = StringProperty(required=True) name = StringProperty(required=True) email: object = EmailProperty(required=True, unique_index=True) # defines the relationship between Team Member and Skill, The type of relationship is "PROFICIENCY_FOR", # and the team member can have zero or more Skills. skill = Relationship(Skill, "PROFICIENCY_FOR", cardinality=ZeroOrMore, model=ProficiencyRel) # This demonstrates creation of email address based on provided first_name and last_name. The user doesn't have # to provide an email address while creating a team member. def pre_save(self): self.email = f"{self.first_name}.{self.last_name}@acme.com" self.name = f"{self.last_name},{self.first_name}"
class User(DjangoNode): uid = UniqueIdProperty() firstname = StringProperty(index=True, required=True) lastname = StringProperty(index=True, required=True) email = EmailProperty(unique_index=True, required=True) password = StringProperty(required=True) _token = RelationshipTo('Token', 'OWNS_TOKEN') class Meta: app_label = 'wiseturn' @property def token(self): return self._token.single() def post_create(self): token = Token().save() self._token.connect(token)
class User(StructuredNode): uid = UniqueIdProperty() address = StringProperty() currency = StringProperty() date_joined = DateTimeProperty(default=datetime.now()) favourites = JSONProperty() first_name = StringProperty() latitude = StringProperty() longitude = StringProperty() last_name = StringProperty() username = StringProperty(unique_index=True) email = EmailProperty(unique_index=True) is_active = BooleanProperty() last_login = DateTimeProperty() password = StringProperty() city = RelationshipTo(City, 'LIVES_IN') @property def serialize(self): return { 'node_properties': { "id": self.uid, "address": self.address, "currency": self.currency, "date_joined": self.date_joined, "first_name": self.first_name, "latitude": str(self.latitude), "longitude": str(self.longitude), "last_name": self.last_name, "username": self.username, "email": self.email, "favourites": self.favourites, }, } @property def serialize_connections(self): return [ { 'nodes_type': 'City', 'nodes_related': self.serialize_relationships(self.city.all()), }, ]
class Person(StructuredNode): # uid = UniqueIdProperty() email = EmailProperty(required=True, unique_index=True) name = StringProperty(required=True) lastname = StringProperty(required=True) is_active = BooleanProperty(default=0) password_hash = StringProperty(required=True) friends = Relationship('Person', 'IS_FRIEND') groups = Relationship('Group', 'IS_MEMBER') chat = Relationship('Chat', 'CHAT_MEMBER') event_joined = Relationship('Event', 'IS_JOINING') event_invited = Relationship('Event', 'IS_INVITED') event_declined = Relationship('Event', 'HAS_DECLINED') def __str__(self): """Return a human readable representation of the model instance.""" return "{}".format(self.name)
class User(StructuredNode, FindMixin): # type: ignore """A `neomodel` model specifying how a user is stored in neo4j.""" uid = UniqueIdProperty() email = EmailProperty(unique_index=True, required=True) hashed_password = StringProperty(required=True) is_active = BooleanProperty() is_verified = BooleanProperty() is_superuser = BooleanProperty() data_sources = RelationshipTo('DataSource', 'has_access') accessed = RelationshipTo('BaseAccess', 'accessed', model=AccessRel) def post_create(self) -> None: """Hook that is run after a user node is created""" self._add_public_data_sources() def _add_public_data_sources(self) -> None: """Links the user node to have access to all public data source nodes""" public_data_sources = DataSource.nodes.filter(public=True) for pds in public_data_sources: self.data_sources.connect(pds) def to_dict(self) -> Dict[str, Union[str, bool]]: """Converts the user node to a dictionary representation and renames the `uid` key to the `id` key so that the resulting dict can be converted to a fastapi_users pydantic user model.""" d = self.__dict__.copy() d['id'] = d.pop('uid') return d def can_access(self, node: BaseAccess) -> bool: """Uses the `has_access` relationship to determine if the user has permission to access data from a specific data source. :param node: The node instance that the user wants to access """ node_source = node.get_data_source_node() user_sources = self.data_sources.all() # Checks that the data source the `node` came from is one in which the # user has access to return node_source in user_sources
class Person(StructuredNode, models.Node): # uid = UniqueIdProperty() __validation_rules__ = { "name": fields.Str(), "lastname": fields.Str(), "password": fields.Str(required=True), "email": fields.Str(required=True) } email = EmailProperty(required=True, unique_index=True) name = StringProperty(required=True) lastname = StringProperty(required=True) is_active = BooleanProperty(default=0) password = StringProperty(required=True) friends = Relationship('Person', 'IS_FRIEND') groups = Relationship('Group', 'IS_MEMBER') chat = Relationship('Chat', 'CHAT_MEMBER') event_joined = Relationship('Event', 'IS_JOINING') event_invited = Relationship('Event', 'IS_INVITED') event_declined = Relationship('Event', 'HAS_DECLINED')
class User(StructuredNode, UserInterface): """ User Node A user cannot exist without being in a Organization (even if that Organization is just "Ian McCarty, Inc") A user can belong to only one company A company can have multiple users A user can be have access to multiple applications, and be in multiple groups """ STATUSES = {'ENABLED': 'Enabled', 'DISABLED': 'Disabled'} # properties uid = StringProperty(unique_index=True, default=generate_uuid4) name = StringProperty(required=True) email = EmailProperty(required=True, unique_index=True) username = StringProperty(required=True, unique_index=True) password = StringProperty(required=True) status = StringProperty(default="ENABLED", choices=STATUSES) created_at = DateTimeProperty(default_now=True) modified_at = DateTimeProperty(default_now=True) password_modified_at = DateTimeProperty(default_now=True) org_admin = BooleanProperty() # relationships # outgoing relationships data = RelationshipTo('.data.Data', 'HAS_DATA') organization = RelationshipTo('.organization.Organization', 'IN_ORGANIZATION', cardinality=One) applications = RelationshipTo('.application.Application', 'IN_APPLICATION') groups = RelationshipTo('.group.Group', 'IN_GROUP') apikeys = RelationshipTo('.apikey.ApiKey', 'AUTHENTICATES_USER') def __init__(self, *args, **kwargs): """ Initialize a User Set some private properties that can be used as a "cache" for custom queries to retrieve some of these objects so that we don't make tons of extra queries to pull associated data :param args: :param kwargs: """ super().__init__(*args, **kwargs) self._organization = None self._data = list() self._apikeys = list() self._applications = list() self._groups = list() def get_data(self): if not self._data: self._data = list(self.data.all()) return {_x.to_object() for _x in self._data} def get_organization(self): if not self._organization: self._organization = self.organization.get_or_none() return self._organization.to_object() def get_applications(self): if not self._applications: self._applications = list(self.applications.all()) return {_x.to_object() for _x in self._applications} def get_groups(self): if not self._groups: self._groups = list(self.groups.all()) return {_x.to_object() for _x in self._groups} def get_apikeys(self): if not self._apikeys: self._apikeys = list(self.apikeys.all()) return {_x.to_object() for _x in self._apikeys} def connect_object(self, relationship, o): """ Maybe I want to use this, but also likely not... :param relationship: :param o: :return: """ r = getattr(self, relationship) r.connect(o) cached_r = f"_{relationship}" cr = getattr(self, cached_r) if cr and isinstance(cr, 'list'): cr.append(o) elif cr and isinstance(cr, None): cr = o @staticmethod def create_from_object(o: EUser) -> EUser: """ Usernames are unique uids are unique passwords should be hashed (bcrypt) password_modified should be autoset :param o: :return: """ _org = o.organization._object if not _org: _org = Organization.nodes.filter(uid=o.organization.uid) _apps = [a._object for a in o.applications] if not all(_apps): _apps = Application.nodes.filter( uid__in=[a.uid for a in o.applications]) _groups = [g._object for g in o.groups] if not all(_groups): _groups = Group.nodes.filter(uid__in=[g.uid for g in o.groups]) if not o.username: raise Exception("A username is required") with db.transaction: _o = User(uid=o.uid or generate_uuid4(), name=o.name, email=o.email, username=o.username, password=o.password, status=o.status, created_at=o.created_at, modified_at=o.modified_at, password_modified_at=o.password_modified_at, org_admin=o.org_admin) _o.save() _o.organization.connect(_org) _o._organization = _org for _a in _apps: _o.applications.connect(_a) _o._applications.append(_a) for _g in _groups: _o.groups.connect(_g) _o._groups.append(_g) # attach any data nodes for x in o.data: _data = Data(key=x.key, value=x.value) _data.save() _data.user.connect(_o) _o._data.append(_data) return _o.to_object(organization_flag=True, application_flag=True, group_flag=True, apikey_flag=True) @staticmethod def get_object(o: EUser): if not o._object: o._object = User.nodes.get( uid=o.uid) # will raise exception if not found return o._object @staticmethod def attach_application(o: EUser, a: EApplication) -> EUser: """ Attach an Application to a User :param o: :param a: :return: """ _o = User.get_object(o) _a = Application.get_object(a) _o.applications.connect(_a) _o._applications.append(_a) return o @staticmethod def detach_application(o: EUser, a: EApplication) -> EUser: """ Detach an Application from a User - this also removes a User from group memberships from that Application :param o: :param a: :return: """ with db.transaction: _o = User.get_object(o) _a = Application.get_object(a) # remove from any groups associated with the app for _g in _a.groups.all(): _o.groups.disconnect(_g) if _g in _o._groups: _o._groups.remove(_g) # disconnect from the app _o.applications.disconnect(_a) if _a in _o._applications: _o._applications.remove(_a) return o @staticmethod def attach_group(o: EUser, g: EGroup) -> EUser: """ Attach a Group to a User Note: The User must already be a member of the associated Application :param o: :param g: :return: """ _o = User.get_object(o) _g = Group.get_object(g) member_application_ids = {x.uid for x in _o.applications.all()} group_application_id = _g.application.get().uid if group_application_id not in member_application_ids: raise Exception( "User must be a member of application %s to join group %s" % (group_application_id, g.id)) _o.groups.connect(_g) _o._groups.append(_g) return o @staticmethod def detach_group(o: EUser, g: EGroup) -> EUser: """ Detach a Group from a User :param o: :param g: :return: """ with db.transaction: _o = User.get_object(o) _g = Group.get_object(g) _o.groups.disconnect(_g) if _g in _o._groups: _o._groups.remove(_g) return o @staticmethod def update_from_object(o: EUser) -> EUser: if not o.edits: return o _o = User.get_object(o) with db.transaction: local_fields = { 'name', 'username', 'email', 'password', 'status', 'org_admin' } local_field_edits = {(s[0], s[1]) for s in o.edits if s[0] in local_fields} if local_field_edits: for field, new_value in local_field_edits: setattr(_o, field, new_value) _o.modified_at = datetime.datetime.now() _o.save() foreign_fields = { 'data', } foreign_field_edits = { s[0]: s[1] for s in o.edits if s[0] in foreign_fields } if foreign_field_edits: # CRUD on data Data.update_data_nodes(foreign_field_edits.get('data'), _o, 'user') return _o.to_object(organization_flag=True, application_flag=True, group_flag=True, apikey_flag=True) def to_object(self, organization_flag=False, application_flag=False, group_flag=False, apikey_flag=False, *args, **kwargs) -> EUser: o = EUser(uid=self.uid, name=self.name, email=self.email, username=self.username, password=self.password, status=self.status, created_at=self.created_at, modified_at=self.modified_at, password_modified_at=self.password_modified_at, org_admin=self.org_admin) o.data = {_data.to_object() for _data in self.data.all()} if organization_flag: o.organization = self.get_organization() if application_flag: o.applications = self.get_applications() if group_flag: o.groups = self.get_groups() if apikey_flag: o.apikeys = self.get_apikeys() o._object = self return o @staticmethod def get_all(organization_flag=False, application_flag=False, group_flag=False, apikey_flag=False, limit=25, offset=0, order_by='email', *args, **kwargs) -> SetUser: orgs = [ x.to_object(organization_flag=organization_flag, application_flag=application_flag, group_flag=group_flag, apikey_flag=apikey_flag) for x in User.nodes.order_by(order_by)[offset:offset + limit] ] return orgs @staticmethod def get_by_uid(uid, organization_flag=False, application_flag=False, group_flag=False, apikey_flag=False, *args, **kwargs) -> EUser: """ Retrieve a User based on its ID :param uid: :param organization_flag: :param application_flag: :param group_flag: :param apikey_flag: :param args: :param kwargs: :return: """ user = None _user = User.nodes.get_or_none(uid=uid) if _user: user = _user.to_object(organization_flag=organization_flag, application_flag=application_flag, group_flag=group_flag, apikey_flag=apikey_flag) return user @staticmethod def get_by_username(username, organization_flag=False, application_flag=False, group_flag=False, apikey_flag=False, *args, **kwargs) -> EUser: """ Retrieve a User based on its username :param username: :param organization_flag: :param application_flag: :param group_flag: :param apikey_flag: :param args: :param kwargs: :return: """ user = None _user = User.nodes.get_or_none(username=username) if _user: user = _user.to_object(organization_flag=organization_flag, application_flag=application_flag, group_flag=group_flag, apikey_flag=apikey_flag) return user @staticmethod def search(search, organization_flag=False, application_flag=False, group_flag=False, apikey_flag=False, limit=25, offset=0, order_by='email', *args, **kwargs) -> SetUser: """ Search for Users @see documentation for econtextauth.mappers.neo4j.__init__ for instructions on creating the index :param search: :param organization_flag: :param application_flag: :param group_flag: :param apikey_flag: :param args: :param kwargs: :return: """ users_dict = dict() ordered_user_ids = list() users = list() params = {'search_term': search} # full-text search against organizations and users query = "CALL db.index.fulltext.queryNodes('broad_search_index', $search_term) YIELD node, score " \ "OPTIONAL MATCH (node:Organization)<-[:IN_ORGANIZATION]-(u:User) " \ "RETURN node, u" results, meta = db.cypher_query(query, params) for node, u in results: # user match (name, email, username) if "User" in node.labels and node['uid'] not in users_dict: users_dict[node['uid']] = User.inflate(node) if u and u['uid'] not in users_dict: users_dict[u['uid']] = User.inflate(u) # substring matches against API keys query = "MATCH (k:ApiKey)<--(u:User) WHERE k.key CONTAINS toUpper($search_term) RETURN u" results, meta = db.cypher_query(query, params) for (u, ) in results: if u and u['uid'] not in users_dict: users_dict[u['uid']] = User.inflate(u) # populate Users with appropriate info query = "MATCH (u:User)-->(n) WHERE u.uid IN $user_ids RETURN u.uid, n" results, meta = db.cypher_query(query, {'user_ids': list(users_dict.keys())}) for uid, node in results: user = users_dict.get(uid) if "Organization" in node.labels: user._organization = Organization.inflate(node) elif "Application" in node.labels: user._applications.append(Application.inflate(node)) elif "Group" in node.labels: user._groups.append(Group.inflate(node)) elif "ApiKey" in node.labels: user._apikeys.append(ApiKey.inflate(node)) return { u.to_object(organization_flag=organization_flag, application_flag=application_flag, group_flag=group_flag, apikey_flag=apikey_flag) for u in users_dict.values() } @staticmethod def delete_from_object(o: EUser) -> bool: _o = User.get_object(o) with db.transaction: # delete associated data nodes first: for data in _o.data.all(): data.delete() _o.delete() return True
class Users(StructuredNode): uid = UniqueIdProperty() firstname = StringProperty(required=True) middlename = StringProperty(default=None) lastname = StringProperty(required=True) email = EmailProperty(unique_index=True, required=True) password = StringProperty(required=True) created_at = DateTimeProperty(default_now=True) updated_at = DateTimeProperty(default_now=True) deleted_at = DateTimeProperty(required=False, default=None) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def _validate_email_format(self, email=None): __email = email or self.email if not email_validator(__email): raise KeyError("Email is invalid format.") else: return None def find_by_email(self, email=None): __email = email or self.email return self.nodes.order_by('created_at').filter( email=__email, deleted_at__isnull=True) def _hash_password(self): if hasattr(self, "password"): self.password = bcrypt.hashpw(self.password.encode("utf-8"), bcrypt.gensalt()).decode() def authenticate(self): user = self.find_by_email() if user: if bcrypt.checkpw(self.password.encode("utf-8"), user.password.encode("utf-8")): user.created_at = str(user.created_at) user.updated_at = str(user.updated_at) return user else: raise PermissionError("Authentication failed.") else: raise LookupError("Account does not exist!") def find(self, page=0, per_page=15, **kwargs): skip = 0 if page <= 1 else page - 1 limit = skip + per_page order_by = 'created_at' if "order_by" in kwargs and kwargs['order_by']: order_by = kwargs['order_by'] if "uid" in kwargs and kwargs['uid']: return self.find_by_id(uid=kwargs['uid']) else: return self.nodes.order_by(order_by).filter( deleted_at__isnull=True)[skip:limit] def find_by_id(self, uid): return self.nodes.get(uid=uid, deleted_at__isnull=True) def save(self): """ check email format before executing neo4j model """ self._validate_email_format() if self.find_by_email(): raise LookupError("Account already exist!") else: self._hash_password() return super().save()
class User(StructuredNode): uid = StringProperty(unique_index=True) email = EmailProperty(required=True, unique_index=True) name = StringProperty(required=True)