def delete(self, using=None, keep_parents=False): if settings.LOCALCOSMOS_OPEN_SOURCE == True: super().delete(using=using, keep_parents=keep_parents) else: # localcosmos.org uses django-tenants from django_tenants.utils import schema_context, get_tenant_model Tenant = get_tenant_model() user_id = self.pk # using transactions because multiple schemas can refer to the same # user ID as FK references! with transaction.atomic(): deleted = False # delete user and all of its data across tenants for tenant in Tenant.objects.all().exclude( schema_name='public'): with schema_context(tenant.schema_name): super().delete(using=using, keep_parents=keep_parents) # reassign the ID because delete() sets it to None self.pk = user_id deleted = True if deleted == False: # deleting from public schema is not necessary, it happens on the first schema-specific deletion with schema_context('public'): super().delete()
def delete_user(user): """ Delete user across DB schemas. """ if hasattr(user, "tenant_set"): from django_tenants.utils import schema_context # pylint: disable=E0401, C0415 user_id = user.pk # using transactions b/c multiple schemas can refer to the same # user ID as FK references! with transaction.atomic(): # delete user and all of its data across tenants for tenant in user.tenant_set.all(): with schema_context(tenant.schema_name): user.delete() # reassign the ID b/c delete() sets it to None user.pk = user_id # then delete everything from the public schema with schema_context("public"): user.delete() else: user.delete()
def test_installation_unconfigured_then_nothing(self): for schema_name in ['public', self.tenant.schema_name]: with schema_context(schema_name): self.assertFalse( Product.objects.filter(name='kiwitcms-bot/test').exists()) self.assertFalse( BugSystem.objects.filter( name='GitHub Issues for kiwitcms-bot/test').exists()) # simulate unconfigured installation owned by the same user # who owns the GitHub repository app_inst = AppInstallationFactory(sender=self.social_user.uid, ) payload = """ { "action": "created", "repository": { "id": 225221463, "full_name": "kiwitcms-bot/test", "private": false, "owner": { }, "html_url": "https://github.com/kiwitcms-bot/test", "description": "A test repository", "fork": false }, "sender": { "login": "******", "id": %d }, "installation": { "id": %d, "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uNTQ5ODkwOA==" } }""".strip() % (self.social_user.user.username, self.social_user.uid, app_inst.installation) signature = github.calculate_signature( settings.KIWI_GITHUB_APP_SECRET, json.dumps(json.loads(payload)).encode()) response = self.client.post(self.url, json.loads(payload), content_type='application/json', HTTP_X_HUB_SIGNATURE=signature, HTTP_X_GITHUB_EVENT='repository') self.assertContains(response, 'ok') # assert no new products have been created for schema_name in ['public', self.tenant.schema_name]: with schema_context(schema_name): self.assertFalse( Product.objects.filter(name='kiwitcms-bot/test').exists()) self.assertFalse( BugSystem.objects.filter( name='GitHub Issues for kiwitcms-bot/test').exists())
def test_installation_unconfigured_then_nothing(self): for schema_name in ['public', self.tenant.schema_name]: with schema_context(schema_name): self.assertFalse(Version.objects.filter(value='v2.0').exists()) # simulate unconfigured installation owned by the same user # who owns the GitHub repository app_inst = AppInstallationFactory(sender=self.social_user.uid, ) payload = """ { "ref": "v2.0", "ref_type": "tag", "master_branch": "master", "description": "an empty repository", "pusher_type": "user", "repository": { "full_name": "kiwitcms-bot/example", "private": false, "owner": { "login": "******", "site_admin": false }, "description": "an empty repository", "fork": true, "default_branch": "master" }, "sender": { "login": "******", "id": %d, "type": "User", "site_admin": false }, "installation": { "id": %d, "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uNTY1MTMwNQ==" } }""".strip() % (self.social_user.user.username, self.social_user.uid, app_inst.installation) signature = github.calculate_signature( settings.KIWI_GITHUB_APP_SECRET, json.dumps(json.loads(payload)).encode()) response = self.client.post(self.url, json.loads(payload), content_type='application/json', HTTP_X_HUB_SIGNATURE=signature, HTTP_X_GITHUB_EVENT='create') self.assertContains(response, 'ok') # assert no new version have been created for schema_name in ['public', self.tenant.schema_name]: with schema_context(schema_name): self.assertFalse(Version.objects.filter(value='v2.0').exists())
def pay_now(request, emp_id, isall=False): with schema_context(request.user.username): emp = get_object_or_404(Employee, pk=emp_id) ac = get_object_or_404(Accounts, name=request.user.username) if ac.is_available(emp.total) == False: messages.error(request, 'Sorry, No such Amount') messages.error(request, 'Salary Not updated for {}'.format(emp)) return redirect('inventory:salary_cal') s = Salary(emp=emp, basicSalary=emp.basicSalary, bonus=emp.bonus, total=emp.total) s.save() emp.isPaid = True emp.bonus = 0 emp.lastSalary = now() emp.save() ac.reduce_amt(s.total) des = "Salary payed to {}".format(emp) Transaction(amt=s.total, description=des, type=1).save() if isall: return messages.success(request, 'Payed to {}'.format(emp)) return redirect('inventory:salary_cal')
def add_transaction(request): with schema_context(request.user.username): form = TransactionForm(request.POST or None, request.FILES or None) if request.method == "POST": form = TransactionForm(request.POST) if form.is_valid(): amt = form.cleaned_data.get('amt') type = form.cleaned_data.get('type') des = form.cleaned_data.get('description') ac = get_object_or_404(Accounts, name=request.user.username) if type == 1 and ac.is_available(amt) == False: messages.error(request, 'Sorry, No such Amount') messages.error(request, 'Salary Not updated for {}'.format(emp)) return redirect('inventory:salary_cal') if type == 1: ac.reduce_amt(amt) else: ac.increase_amt(amt) ac.save() form.save() messages.success(request, des) return redirect('inventory:dashboard') else: messages.error(request, 'Transaction Failed.') messages.error(request, form.errors) header = "New Transaction" return render(request, 'inventory/add_common.html', { 'form': form, 'header': header })
def test_get_country_uat(self): """Check that we get country UAT if no match for business area code""" with schema_context(SCHEMA_NAME): country_uat = CountryFactory(name="UAT") res = self.mapper._get_country("UAT") self.assertEqual(res, country_uat) self.assertEqual(self.mapper.countries, {"UAT": country_uat})
def setUp(self): super(SharedAuthTest, self).setUp() settings.SHARED_APPS = ('django_tenants', 'customers', 'django.contrib.auth', 'django.contrib.contenttypes', ) settings.TENANT_APPS = ('dts_test_app', ) settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS self.sync_shared() self.public_tenant = get_tenant_model()(schema_name=get_public_schema_name()) self.public_tenant.save() self.public_domain = get_tenant_domain_model()(tenant=self.public_tenant, domain='test.com') self.public_domain.save() # Create a tenant self.tenant = get_tenant_model()(schema_name='tenant') self.tenant.save() self.domain = get_tenant_domain_model()(tenant=self.tenant, domain='tenant.test.com') self.domain.save() # Create some users with schema_context(get_public_schema_name()): # this could actually also be executed inside a tenant self.user1 = User(username='******', email="*****@*****.**") self.user1.save() self.user2 = User(username='******', email="*****@*****.**") self.user2.save() # Create instances on the tenant that point to the users on public with tenant_context(self.tenant): self.d1 = ModelWithFkToPublicUser(user=self.user1) self.d1.save() self.d2 = ModelWithFkToPublicUser(user=self.user2) self.d2.save()
def order_now(request, cus_id): # for booking order with schema_context(request.user.username): if request.method == 'POST': formset = OrderFormset(request.POST) if formset.is_valid(): cus = get_object_or_404(Customer, pk=cus_id) total = 0 order = Orders(cus=cus, total_amt=total, Odate=now()) order.save() for form in formset: if form.cleaned_data.get( 'product') and form.cleaned_data.get('weight'): product = form.cleaned_data.get('product') weight = form.cleaned_data.get('weight') total += (product.cost * weight) items = OrderItems(order=order, product=product, weight=weight) items.save() if total: order.total_amt = total order.save() messages.success(request, 'Order Booked.') return redirect('inventory:customer') else: messages.error(request, "Order not booked") else: for e in formset.errors: messages.error(request, e) else: formset = OrderFormset(request.GET or None) return render(request, 'inventory/order_now.html', {'formset': formset})
def get_metrics_in_profiles(schema): with schema_context(schema): try: token = MyAPIKey.objects.get(name='WEB-API') headers = {'Accept': 'application/json', 'x-api-key': token.token} response = requests.get(settings.WEBAPI_METRIC, headers=headers, timeout=180) response.raise_for_status() data = response.json()['data'] metrics_dict = dict() for item in data: for service in item['services']: if 'metrics' in service: for metric in service['metrics']: if metric not in metrics_dict: metrics_dict.update({metric: [item['name']]}) else: metrics_dict.update({ metric: metrics_dict[metric] + [item['name']] }) return metrics_dict except requests.exceptions.HTTPError: raise except MyAPIKey.DoesNotExist: raise Exception('Error fetching WEB API data: API key not found.')
def setUpClass(cls): get_tenant_model().auto_create_schema = True with schema_context('public'): # remove pre-existing tenants so they don't mess up the tests get_tenant_model().objects.exclude(schema_name='public').delete() # public tenant object b/c schema exists but not the Tenant itself! public_tenant = get_tenant_model().objects.filter( schema_name='public').first() if not public_tenant: public_tenant = get_tenant_model()(schema_name='public') cls.setup_tenant(public_tenant) public_tenant.save() public_domain = get_tenant_domain_model()( tenant=public_tenant, domain='public.test.com') cls.setup_domain(public_domain) public_domain.save() super().setUpClass() social_user = UserSocialAuthFactory() cls.app_inst = AppInstallationFactory(sender=social_user.uid) social_tester = UserSocialAuthFactory(user=cls.tester) cls.app_inst_tester = AppInstallationFactory(sender=social_tester.uid)
def setUp(self): super().setUp() settings.SHARED_APPS = ('django_tenants', 'customers', 'django.contrib.auth', 'django.contrib.contenttypes', ) settings.TENANT_APPS = ('dts_test_app', ) settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS self.sync_shared() self.public_tenant = get_tenant_model()(schema_name=get_public_schema_name()) self.public_tenant.save() self.public_domain = get_tenant_domain_model()(tenant=self.public_tenant, domain='test.com') self.public_domain.save() # Create a tenant self.tenant = get_tenant_model()(schema_name='tenant') self.tenant.save() self.domain = get_tenant_domain_model()(tenant=self.tenant, domain='tenant.test.com') self.domain.save() # Create some users with schema_context(get_public_schema_name()): # this could actually also be executed inside a tenant self.user1 = User(username='******', email="*****@*****.**") self.user1.save() self.user2 = User(username='******', email="*****@*****.**") self.user2.save() # Create instances on the tenant that point to the users on public with tenant_context(self.tenant): self.d1 = ModelWithFkToPublicUser(user=self.user1) self.d1.save() self.d2 = ModelWithFkToPublicUser(user=self.user2) self.d2.save()
def setUpClass(cls): super(SharedAuthTest, cls).setUpClass() settings.SHARED_APPS = ( 'django_tenants', 'django.contrib.auth', 'django.contrib.contenttypes', ) settings.TENANT_APPS = ('dts_test_app', ) settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS cls.sync_shared() Tenant(domain_urls=['test.com'], schema_name=get_public_schema_name()).save() # Create a tenant cls.tenant = Tenant(domain_urls=['tenant.test.com'], schema_name='tenant') cls.tenant.save() # Create some users with schema_context(get_public_schema_name( )): # this could actually also be executed inside a tenant cls.user1 = User(username='******', email="*****@*****.**") cls.user1.save() cls.user2 = User(username='******', email="*****@*****.**") cls.user2.save() # Create instances on the tenant that point to the users on public with tenant_context(cls.tenant): cls.d1 = ModelWithFkToPublicUser(user=cls.user1) cls.d1.save() cls.d2 = ModelWithFkToPublicUser(user=cls.user2) cls.d2.save()
def handle(self, *args, **kwargs): services = list() if not kwargs.get('json', False) or not kwargs.get( 'schemaname', False): raise CommandError("Both arguments should be specified") try: with open(os.path.expandvars(kwargs['json'])) as jsonfile: raw = jsonfile.read() services = json.loads(raw) except OSError as exc: raise CommandError(repr(exc)) with schema_context(kwargs['schemaname'].lower()): try: tenant = Tenant.objects.get( schema_name=kwargs['schemaname'].lower()) models.ServiceFlavour.objects.all().delete() bulk = list() for service in services: sd = models.ServiceFlavour( name=service['name'], description=service['description']) bulk.append(sd) models.ServiceFlavour.objects.bulk_create(bulk) except (Tenant.DoesNotExist, DataError) as exc: raise CommandError(repr(exc))
def setUpClass(cls): super(SharedAuthTest, cls).setUpClass() settings.SHARED_APPS = ('django_tenants', 'django.contrib.auth', 'django.contrib.contenttypes', ) settings.TENANT_APPS = ('dts_test_app', ) settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS cls.sync_shared() Tenant(domain_urls=['test.com'], schema_name=get_public_schema_name()).save() # Create a tenant cls.tenant = Tenant(domain_urls=['tenant.test.com'], schema_name='tenant') cls.tenant.save() # Create some users with schema_context(get_public_schema_name()): # this could actually also be executed inside a tenant cls.user1 = User(username='******', email="*****@*****.**") cls.user1.save() cls.user2 = User(username='******', email="*****@*****.**") cls.user2.save() # Create instances on the tenant that point to the users on public with tenant_context(cls.tenant): cls.d1 = ModelWithFkToPublicUser(user=cls.user1) cls.d1.save() cls.d2 = ModelWithFkToPublicUser(user=cls.user2) cls.d2.save()
def save_message(room, sender, text, multitenant=False, schema_name=None): if multitenant: if not schema_name: raise AttributeError("Multitenancy support error: \ scope does not have multitenancy details added. \ did you forget to add ChatterMTMiddlewareStack to your routing?" ) else: from django_tenants.utils import schema_context with schema_context(schema_name): new_message = Message(room=room, sender=sender, text=text) new_message.save() new_message.recipients.add(sender) new_message.save() room.date_modified = new_message.date_modified room.save() return new_message.date_created else: new_message = Message(room=room, sender=sender, text=text) new_message.save() new_message.recipients.add(sender) new_message.save() room.date_modified = new_message.date_modified room.save() return new_message.date_created
async def connect(self): self.user = self.scope['user'] self.schema_name = self.scope.get('schema_name', None) self.multitenant = self.scope.get('multitenant', False) for param in self.scope['path'].split('/'): if len(param) == 22: # ShortUUID length room_id = param break try: self.room = await get_room(room_id, self.multitenant, self.schema_name) if self.multitenant: from django_tenants.utils import schema_context with schema_context(self.schema_name): if self.user in self.room.members.all(): room_group_name = 'chat_%s' % self.room.id await self.channel_layer.group_add( room_group_name, self.channel_name) await self.accept() else: await self.disconnect(403) else: if self.user in self.room.members.all(): room_group_name = 'chat_%s' % self.room.id await self.channel_layer.group_add(room_group_name, self.channel_name) await self.accept() else: await self.disconnect(403) except Exception as ex: raise ex await self.disconnect(500)
def delivered(request, ord_id): # completing the order with schema_context(request.user.username): order = get_object_or_404(Orders, pk=ord_id) items = OrderItems.objects.filter(order=order) for i in items: if (i.product.is_available(i.weight) == False): messages.error(request, '{} is Out of Stock!'.format(i.product.name)) messages.error(request, 'Order cannot be deliver.') return redirect('inventory:order_all') for i in items: i.product.reduce_product(i.weight) ac = get_object_or_404(Accounts, name=request.user.username) ac.increase_amt(order.total_amt) ac.save() des = "Order Completed for {}".format(order.cus) Transaction(amt=order.total_amt, description=des, type=0).save() order.Ddate = now() order.isDelivered = True order.save() messages.success(request, 'Order Completed.') return redirect('inventory:order_all')
def update_metric_history(sender, instance, created, **kwargs): if not created: schemas = list( Tenant.objects.all().values_list('schema_name', flat=True) ) schemas.remove(get_public_schema_name()) probes = admin_models.ProbeHistory.objects.filter( package=instance ) for schema in schemas: with schema_context(schema): for probe in probes: metrics = Metric.objects.filter(probekey=probe) for metric in metrics: vers = TenantHistory.objects.filter( object_id=metric.id ).order_by('-date_created') for ver in vers: serialized_data = json.loads(ver.serialized_data) serialized_data[0]['fields']['probekey'] = [ probe.name, probe.package.version ] ver.serialized_data = json.dumps(serialized_data) ver.save()
def salary_details(request, emp_id): # for single employee with schema_context(request.user.username): emp = get_object_or_404(Employee, pk=emp_id) sal = Salary.objects.filter(emp=emp) return render(request, 'inventory/salary_details.html', { 'sal': sal, 'emp': emp })
def view_all_transaction(request): with schema_context(request.user.username): tr = Transaction.objects.all() header = "All Transactions Details" return render(request, 'inventory/transaction.html', { 'trans': tr, "header": header })
def create_tenant_user(tenant_slug, username, email, password, connected_user_email=None, **user_extra): """ Create user for a specified tenant. """ PublicUserModel = get_user_model() TenantUserModel = get_tenant_user_model() TenantModel = get_tenant_model() public_schema_name = get_public_schema_name() tenant = TenantModel.objects.filter(slug=tenant_slug).first() if not tenant: raise ExistsError("Tenant not exists.") public_profile = None if connected_user_email: with schema_context(public_schema_name): public_profile = PublicUserModel.objects.filter( email=connected_user_email).first() if not public_profile: raise ExistsError("Related public user not exists.") profile = None with schema_context(tenant.schema_name): profile = TenantUserModel.objects.filter(username=username).first() if profile and profile.is_active: raise ExistsError("User already exists!") if not profile: profile = TenantUserModel.objects.create(username=username, email=email, **user_extra) profile.email = email profile.is_active = True profile.set_password(password) for attr, value in user_extra.items(): setattr(profile, attr, value) if public_profile: profile.supervisor = public_profile profile.save() return profile
def view_works(request, emp_id): with schema_context(request.user.username): emp = get_object_or_404(Employee, pk=emp_id) wk = Work.objects.filter(emp=emp_id) return render(request, 'inventory/view_works.html', { 'wk': wk, 'emp': emp })
def view_debit(request): with schema_context(request.user.username): tr = Transaction.objects.filter(type=1) header = "Debited Transactions Details" return render(request, 'inventory/transaction.html', { 'trans': tr, "header": header })
def create_superuser(schema_name, email): """ create_superuser create the admin in new tenant """ # password = random_password() with schema_context(schema_name): User.objects.create_user(username='******', password='******')
def order_details(request, ord_id): # particular order details with schema_context(request.user.username): order = get_object_or_404(Orders, pk=ord_id) items = OrderItems.objects.filter(order=ord_id) return render(request, 'inventory/order_details.html', { 'items': items, 'order': order })
def create_groups_of_resources(tenant_name): schema = tenant_name.lower() group = tenant_name.upper() with schema_context(schema): poem_models.GroupOfAggregations.objects.create(name=group) poem_models.GroupOfMetrics.objects.create(name=group) poem_models.GroupOfMetricProfiles.objects.create(name=group) poem_models.GroupOfThresholdsProfiles.objects.create(name=group) poem_models.GroupOfReports.objects.create(name=group)
def salary_cal(request): # salary details for all employee with schema_context(request.user.username): get_total(request) emp = Employee.objects.all() for e in emp: if (now().date() - e.lastSalary > timedelta(days=7)): e.isPaid = False e.save() return render(request, 'inventory/salary_cal.html', {'emp': emp})
def get_tenant_data(data, tenant_id): tenant = Client.objects.get(id=tenant_id) with schema_context(tenant.schema_name): if data == 'sms_unit': unit = Setting.objects.first().sms_unit return unit if data == 'no_studs': students = User.objects.filter(is_student=True).count() return students
def register(request): if request.method == "POST": username = request.POST['username'] password = request.POST['password'] name = request.POST['name'] email = request.POST['email'] phno = request.POST['phno'] # Storing phno in last_name # Function checks if the string contains any special character regex = re.compile('[@_!#$%^&*()<>?/\|}{~:]') if (regex.search(username) != None): messages.error(request, 'username must not conatain any special name') messages.info(request, 'Try Another Username') return redirect('home:register') if bool(re.search(r"\s", username)) == True: messages.error(request, 'username must not conatain space') messages.info(request, 'Try Another Username') return redirect('home:register') if username.islower() != True: messages.error(request, 'username must be lower case only') messages.info(request, 'Try Another Username') return redirect('home:register') if User.objects.filter(username=username).exists(): messages.error(request, 'Username is aldready taken') messages.info(request, 'Try Another Username') return redirect('home:register') user = User.objects.create_user(username=username, password=password, first_name=name, last_name=phno, email=email) user.save() tenant = Client.objects.create(user=user, schema_name=user.username) tenant.save() domain = Domain() domain.domain = tenant.schema_name + ".global.localhost" domain.tenant = tenant domain.is_primary = True domain.save() messages.success(request, 'Account created successfully for {}'.format(name)) with schema_context(username): ac = Accounts(name=username, money=0).save() return redirect('home:login') return render(request, 'login.html')
def test_switching_tenant_without_previous_tenant(self): tenant = Tenant(domain_urls=['something.test.com'], schema_name='test') tenant.save() connection.tenant = None with tenant_context(tenant): DummyModel(name="No exception please").save() connection.tenant = None with schema_context(tenant.schema_name): DummyModel(name="Survived it!").save()
def dashboard(request): template = 'authenticated/dashboard.html' tenants = Client.objects.exclude(schema_name='public') students_count = 0 for tenant in tenants: with schema_context(tenant.schema_name): students_count += User.objects.filter(is_student=True).count() target = 500 * students_count # N500 times Number of students in all tenants context = {"tenants_count": tenants.count()} context['students_count'] = students_count context['target'] = target return render(request, template, context)
def test_switching_tenant_without_previous_tenant(self): tenant = get_tenant_model()(schema_name='test') tenant.save() domain = get_tenant_domain_model()(tenant=tenant, domain='something.test.com') domain.save() connection.tenant = None with tenant_context(tenant): DummyModel(name="No exception please").save() connection.tenant = None with schema_context(tenant.schema_name): DummyModel(name="Survived it!").save()
def notify_partner_hidden(partner_pk, tenant_name): with schema_context(tenant_name): partner = PartnerOrganization.objects.get(pk=partner_pk) pds = Intervention.objects.filter( agreement__partner__name=partner.name, status__in=[Intervention.SIGNED, Intervention.ACTIVE, Intervention.ENDED] ) if pds: email_context = { 'partner_name': partner.name, 'pds': ', '.join(pd.number for pd in pds), 'environment': get_environment(), } emails_to_pd = [pd.unicef_focal_points.values_list('email', flat=True) for pd in pds] recipients = set(itertools.chain.from_iterable(emails_to_pd)) send_notification_with_template( recipients=list(recipients), template_name='partners/blocked_partner', context=email_context )