예제 #1
0
    def save(self, verbosity=1, *args, **kwargs):
        if connection.get_schema() != get_public_schema_name():
            raise Exception("Can't update tenant outside the public schema. Current schema is %s."
                            % connection.get_schema())

        is_new = self.pk is None
        super(TenantMixin, self).save(*args, **kwargs)

        if is_new and self.auto_create_schema:
            self.create_schema(check_if_exists=True, verbosity=verbosity)
            post_schema_sync.send(sender=TenantMixin, tenant=self)

        transaction.commit_unless_managed()
예제 #2
0
    def save(self, verbosity=1, *args, **kwargs):
        if connection.get_schema() != get_public_schema_name():
            raise Exception(
                "Can't update tenant outside the public schema. Current schema is %s."
                % connection.get_schema())

        is_new = self.pk is None
        super(TenantMixin, self).save(*args, **kwargs)

        if is_new and self.auto_create_schema:
            self.create_schema(check_if_exists=True, verbosity=verbosity)
            post_schema_sync.send(sender=TenantMixin, tenant=self)

        transaction.commit_unless_managed()
예제 #3
0
    def delete(self, *args, **kwargs):
        """
        Drops the schema related to the tenant instance. Just drop the schema if the parent
        class model has the attribute auto_drop_schema set to True.
        """
        if connection.get_schema() not in (self.schema_name, get_public_schema_name()):
            raise Exception("Can't delete tenant outside it's own schema or the public schema. Current schema is %s."
                            % connection.get_schema())

        if schema_exists(self.schema_name) and self.auto_drop_schema:
            cursor = connection.cursor()
            cursor.execute('DROP SCHEMA %s CASCADE' % self.schema_name)

        super(TenantMixin, self).delete(*args, **kwargs)
예제 #4
0
    def save(self, verbosity=1, *args, **kwargs):
        is_new = self.pk is None

        if is_new and connection.get_schema() != get_public_schema_name():
            raise Exception("Can't create tenant outside the public schema. Current schema is %s."
                            % connection.get_schema())
        elif not is_new and connection.get_schema() not in (self.schema_name, get_public_schema_name()):
            raise Exception("Can't update tenant outside it's own schema or the public schema. Current schema is %s."
                            % connection.get_schema())

        if is_new and self.auto_create_schema:
            self.create_schema(check_if_exists=True, verbosity=verbosity)
            post_schema_sync.send(sender=TenantMixin, tenant=self)

        super(TenantMixin, self).save(*args, **kwargs)
예제 #5
0
def schema_context(schema_name):
    previous_schema = connection.get_schema()
    try:
        connection.set_schema(schema_name)
        yield
    finally:
        connection.set_schema(previous_schema)
예제 #6
0
def tenant_context(tenant):
    previous_schema = connection.get_schema()
    try:
        connection.set_tenant(tenant)
        yield
    finally:
        connection.set_schema(previous_schema)
예제 #7
0
    def _create_user(self, email, password, is_staff, is_superuser,
                     is_verified, **extra_fields):
        # Do some schema validation to protect against calling create user from inside
        # a tenant. Must create public tenant permissions during user creation. This
        # happens during assign role. This function cannot be used until a public
        # schema already exists
        UserModel = get_user_model()

        if connection.get_schema() != get_public_schema_name():
            raise SchemaError(
                "Schema must be public for UserProfileManager user creation")

        if not email:
            raise ValueError("Users must have an email address.")

        # If no password is submitted, just assign a random one to lock down
        # the account a little bit.
        if not password:
            password = self.make_random_password(length=30)

        email = self.normalize_email(email)

        profile = UserModel.objects.filter(email=email).first()
        if profile and profile.is_active:
            raise ExistsError("User already exists!")

        # Profile might exist but not be active. If a profile does exist
        # all previous history logs will still be associated with the user,
        # but will not be accessible because the user won't be linked to
        # any tenants from the user's previous membership. There are two
        # exceptions to this. 1) The user gets re-invited to a tenant it
        # previously had access to (this is good thing IMO). 2) The public
        # schema if they had previous activity associated would be available
        if not profile:
            profile = UserModel()

        profile.email = email
        profile.is_active = True
        profile.is_verified = is_verified
        profile.set_password(password)
        for attr, value in extra_fields.items():
            setattr(profile, attr, value)
        profile.save()

        # Get public tenant tenant and link the user (no perms)
        public_tenant = get_tenant_model().objects.get(
            schema_name=get_public_schema_name())
        public_tenant.add_user(profile)

        # Public tenant permissions object was created when we assigned a
        # role to the user above, if we are a staff/superuser we set it here
        if is_staff or is_superuser:
            user_tenant = profile.usertenantpermissions
            user_tenant.is_staff = is_staff
            user_tenant.is_superuser = is_superuser
            user_tenant.save()

        tenant_user_created.send(sender=self.__class__, user=profile)

        return profile
예제 #8
0
def schema_context(schema_name):
    previous_schema = connection.get_schema()
    try:
        connection.set_schema(schema_name)
        yield
    finally:
        connection.set_schema(previous_schema)
예제 #9
0
def tenant_context(tenant):
    previous_schema = connection.get_schema()
    try:
        connection.set_tenant(tenant)
        yield
    finally:
        connection.set_schema(previous_schema)
예제 #10
0
 def inner(self, *args, **options):
     tenant_schema = self.schema_name
     # Save current schema and restore it when we're done
     saved_schema = connection.get_schema()
     # Set schema to this tenants schema to start building permissions in that tenant
     connection.set_schema(tenant_schema)
     try:
         result = func(self, *args, **options)
     finally:
         # Even if an exception is raised we need to reset our schema state
         connection.set_schema(saved_schema)
     return result
예제 #11
0
    def _create_user(self, username, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        # Do some schema validation to protect against calling create user from inside
        # a tenant. Must create public tenant permissions during user creation. This
        # happens during assign role. This function cannot be used until a public
        # schema already exists
        UserModel = get_user_model()

        if connection.get_schema() != get_public_schema_name():
            raise SchemaError("Schema must be public for UserManager user creation.")

        if not username:
            raise ValueError("The given username must be set.")
        username = self.model.normalize_username(username)

        if not email:
            raise ValueError("Users must have an email address.")
        email = self.normalize_email(email)

        # If no password is submitted, just assign a random one to lock down
        # the account a little bit.
        if not password:
            password = self.make_random_password(length=30)

        user = UserModel.objects.filter(username=username).first()
        if user and user.is_active:
            raise ExistsError("User already exists!")

        # User might exist but not be active. If a user does exist
        # all previous history logs will still be associated with the user,
        # but will not be accessible because the user won't be linked to
        # any tenants from the user's previous membership. There are two
        # exceptions to this. 1) The user gets re-invited to a tenant it
        # previously had access to (this is good thing IMO). 2) The public
        # schema if they had previous activity associated would be available
        if not user:
            user = UserModel(username=username, email=email, **extra_fields)

        user.email = email
        user.is_active = True
        user.set_password(password)
        for attr, value in extra_fields.items():
            setattr(user, attr, value)
        user.save()

        tenant_user_created.send(sender=self.__class__, user=user)
        return user
예제 #12
0
    def save(self, verbosity=1, *args, **kwargs):
        if hasattr(connection, 'get_schema') and connection.get_schema() != get_public_schema_name():
            raise Exception("Can't update tenant outside the public schema. Current schema is %s." % connection.get_schema())

        is_new = self.pk is None

        if is_new and settings.TENANT_DYNAMIC_SITE and hasattr(self, 'site_id') and not self.site_id:
            self.site_id = self.create_site().id

        print self.site_id

        super(TenantMixin, self).save(*args, **kwargs)

        print self.site_id

        if is_new and self.auto_create_schema and hasattr(connection, 'get_schema'):
            self.create_schema(check_if_exists=True, verbosity=verbosity)
            post_schema_sync.send(sender=TenantMixin, tenant=self)

        transaction.commit_unless_managed()
예제 #13
0
def get_current_tenant():
    current_schema = connection.get_schema()
    TenantModel = get_tenant_model()
    tenant = TenantModel.objects.get(schema_name=current_schema)
    return tenant
    def delete(self, *args, **kwargs):
        if connection.get_schema() not in (self.schema_name, get_public_schema_name()):
            raise Exception("Can't delete tenant outside it's own schema or the public schema. Current schema is %s."
                            % connection.get_schema())

        super(TenantMixin, self).delete(*args, **kwargs)