def create_notification(event=None, *args, **kwargs): if 'recipients' in kwargs: # mimic existing code so that when recipients is specified, no other system or personal notifications are sent. logger.debug('creating notifications for recipients') for recipient_notifications in Notifications.objects.filter( user__username__in=kwargs['recipients'], user__is_active=True, product=None): # kwargs.update({'user': recipient_notifications.user}) process_notifications(event, recipient_notifications, *args, **kwargs) else: logger.debug('creating system notifications') # send system notifications to all admin users # System notifications try: system_notifications = Notifications.objects.get(user=None) except Exception: system_notifications = Notifications() admin_users = Dojo_User.objects.filter(is_staff=True) for admin_user in admin_users: system_notifications.user = admin_user process_notifications(event, system_notifications, *args, **kwargs) # Personal but global notifications # only retrieve users which have at least one notification type enabled for this event type. logger.debug('creating personal notifications') product = None if 'product' in kwargs: product = kwargs.get('product') if not product and 'engagement' in kwargs: product = kwargs['engagement'].product if not product and 'test' in kwargs: product = kwargs['test'].engagement.product # get users with either global notifications, or a product specific noditiciation users = Dojo_User.objects.filter(is_active=True).prefetch_related( Prefetch("notifications_set", queryset=Notifications.objects.filter( Q(product_id=product) | Q(product__isnull=True)), to_attr="applicable_notifications")).annotate( applicable_notifications_count=Count( 'notifications__id', filter=Q(notifications__product_id=product) | Q(notifications__product__isnull=True))).filter( applicable_notifications_count__gt=0) for user in users: # send notifications to user after merging possible multiple notifications records (i.e. personal global + personal product) # kwargs.update({'user': user}) process_notifications( event, Notifications.merge_notifications_list( user.applicable_notifications), *args, **kwargs)
def test_merge_notifications_list(self): global_personal_notifications = Notifications(user=User.objects.get( username='******')) personal_product_notifications = Notifications( user=User.objects.get(username='******'), product=Product.objects.all()[0]) global_personal_notifications.product_added = ['alert'] global_personal_notifications.test_added = '' global_personal_notifications.scan_added = None global_personal_notifications.other = ['slack', 'mail'] global_personal_notifications.save( ) # we have to save it and retrieve it because only then the fields get turned into lists... global_personal_notifications = Notifications.objects.get( id=global_personal_notifications.id) print(vars(global_personal_notifications)) personal_product_notifications.product_added = ['mail'] personal_product_notifications.test_added = ['mail', 'alert'] personal_product_notifications.scan_added = None print(vars(personal_product_notifications)) personal_product_notifications.save() personal_product_notifications = Notifications.objects.get( id=personal_product_notifications.id) print(vars(personal_product_notifications)) merged_notifications = Notifications.merge_notifications_list( [global_personal_notifications, personal_product_notifications]) print(vars(merged_notifications)) self.assertEqual('alert' in merged_notifications.product_added, True) self.assertEqual('mail' in merged_notifications.product_added, True) self.assertEqual('slack' in merged_notifications.product_added, False) self.assertEqual(len(merged_notifications.product_added), 2) self.assertEqual('alert' in merged_notifications.test_added, True) self.assertEqual('mail' in merged_notifications.test_added, True) self.assertEqual('slack' in merged_notifications.test_added, False) self.assertEqual(len(merged_notifications.test_added), 2) self.assertEqual('alert' in merged_notifications.scan_added, False) self.assertEqual('mail' in merged_notifications.scan_added, False) self.assertEqual('slack' in merged_notifications.scan_added, False) self.assertEqual(len(merged_notifications.scan_added), 0) self.assertEqual('alert' in merged_notifications.other, True) self.assertEqual('mail' in merged_notifications.other, True) self.assertEqual('slack' in merged_notifications.other, True) # default alert from global self.assertEqual(len(merged_notifications.other), 3)
def create_notification(event=None, *args, **kwargs): if 'recipients' in kwargs: # mimic existing code so that when recipients is specified, no other system or personal notifications are sent. logger.debug('creating notifications for recipients') for recipient_notifications in Notifications.objects.filter( user__username__in=kwargs['recipients'], user__is_active=True, product=None): # kwargs.update({'user': recipient_notifications.user}) process_notifications(event, recipient_notifications, *args, **kwargs) else: logger.debug('creating system notifications for event: %s', event) # send system notifications to all admin users # System notifications try: system_notifications = Notifications.objects.get(user=None) except Exception: system_notifications = Notifications() # System notifications are sent one with user=None, which will trigger email to configured system email, to global slack channel, etc. process_notifications(event, system_notifications, *args, **kwargs) # All admins will also receive system notifications, but as part of the person global notifications section below # This time user is set, so will trigger email to personal email, to personal slack channel (mention), etc. # only retrieve users which have at least one notification type enabled for this event type. logger.debug('creating personal notifications for event: %s', event) product = None if 'product' in kwargs: product = kwargs.get('product') if not product and 'engagement' in kwargs: product = kwargs['engagement'].product if not product and 'test' in kwargs: product = kwargs['test'].engagement.product if not product and 'finding' in kwargs: product = kwargs['finding'].test.engagement.product # get users with either global notifications, or a product specific noditiciation # and all admin/superuser, they will always be notified users = Dojo_User.objects.filter(is_active=True).prefetch_related(Prefetch( "notifications_set", queryset=Notifications.objects.filter(Q(product_id=product) | Q(product__isnull=True)), to_attr="applicable_notifications" )).annotate(applicable_notifications_count=Count('notifications__id', filter=Q(notifications__product_id=product) | Q(notifications__product__isnull=True)))\ .filter((Q(applicable_notifications_count__gt=0) | Q(is_superuser=True) | Q(is_staff=True))) # only send to authorized users or admin/superusers if product: users = users.filter( Q(id__in=product.authorized_users.all()) | Q(id__in=product.prod_type.authorized_users.all()) | Q(is_superuser=True) | Q(is_staff=True)) for user in users: # send notifications to user after merging possible multiple notifications records (i.e. personal global + personal product) # kwargs.update({'user': user}) applicable_notifications = user.applicable_notifications if user.is_staff or user.is_superuser: # admin users get all system notifications applicable_notifications.append(system_notifications) notifications_set = Notifications.merge_notifications_list( applicable_notifications) notifications_set.user = user process_notifications(event, notifications_set, *args, **kwargs)
def create_notification(event=None, **kwargs): system_settings = System_Settings.objects.get() kwargs["system_settings"] = system_settings if 'recipients' in kwargs: # mimic existing code so that when recipients is specified, no other system or personal notifications are sent. logger.debug('creating notifications for recipients') for recipient_notifications in Notifications.objects.filter( user__username__in=kwargs['recipients'], user__is_active=True, product=None): # kwargs.update({'user': recipient_notifications.user}) process_notifications(event, recipient_notifications, **kwargs) else: logger.debug('creating system notifications for event: %s', event) # send system notifications to all admin users # parse kwargs before converting them to dicts product_type = None if 'product_type' in kwargs: product_type = kwargs.get('product_type') product = None if 'product' in kwargs: product = kwargs.get('product') elif 'engagement' in kwargs: product = kwargs['engagement'].product elif 'test' in kwargs: product = kwargs['test'].engagement.product elif 'finding' in kwargs: product = kwargs['finding'].test.engagement.product elif 'obj' in kwargs: from dojo.utils import get_product product = get_product(kwargs['obj']) # System notifications try: system_notifications = Notifications.objects.get(user=None) except Exception: system_notifications = Notifications() # System notifications are sent one with user=None, which will trigger email to configured system email, to global slack channel, etc. process_notifications(event, system_notifications, **kwargs) # All admins will also receive system notifications, but as part of the person global notifications section below # This time user is set, so will trigger email to personal email, to personal slack channel (mention), etc. # only retrieve users which have at least one notification type enabled for this event type. logger.debug('creating personal notifications for event: %s', event) # There are notification like deleting a product type that shall not be sent to users. # These notifications will have the parameter no_users=True if not ('no_users' in kwargs and kwargs['no_users'] is True): # get users with either global notifications, or a product specific noditiciation # and all admin/superuser, they will always be notified users = Dojo_User.objects.filter(is_active=True).prefetch_related(Prefetch( "notifications_set", queryset=Notifications.objects.filter(Q(product_id=product) | Q(product__isnull=True)), to_attr="applicable_notifications" )).annotate(applicable_notifications_count=Count('notifications__id', filter=Q(notifications__product_id=product) | Q(notifications__product__isnull=True)))\ .filter((Q(applicable_notifications_count__gt=0) | Q(is_superuser=True) | Q(is_staff=True))) # only send to authorized users or admin/superusers if product: users = get_authorized_users_for_product_and_product_type( users, product, Permissions.Product_View) elif product_type: users = get_authorized_users_for_product_type( users, product_type, Permissions.Product_Type_View) for user in users: # send notifications to user after merging possible multiple notifications records (i.e. personal global + personal product) # kwargs.update({'user': user}) applicable_notifications = user.applicable_notifications if user.is_staff or user.is_superuser: # admin users get all system notifications applicable_notifications.append(system_notifications) notifications_set = Notifications.merge_notifications_list( applicable_notifications) notifications_set.user = user process_notifications(event, notifications_set, **kwargs)