def get(self, request, *args, **kwargs): # get room slug if one was in URL, else try finding the first sorted room # self.room can be None! self.room = None # discard the event_id kwarg, it is only for the frontend kwargs.pop('event_id', None) if not 'slug' in kwargs: first_room = self.group.rooms.visible().first() if first_room: return redirect(first_room.get_absolute_url()) else: room_slug = kwargs.pop('slug') self.room = get_object_or_None(CosinnusConferenceRoom, group=self.group, slug=room_slug) if self.room and not self.room.is_visible: if not check_user_superuser(request.user) and not check_ug_admin( request.user, self.group): return HttpResponseForbidden() self.rooms = self.group.rooms.all() if self.rooms.count() == 0 and (check_ug_admin(request.user, self.group) or check_user_superuser(request.user)): # if no rooms have been created, redirect group admins to room management return redirect( group_aware_reverse('cosinnus:conference:room-management', kwargs={'group': self.group})) return super(ConferencePageView, self).get(request, *args, **kwargs)
def superuser_required(function): """A function decorator to assure a requesting user has the superuser flag """ actual_decorator = user_passes_test( lambda u: check_user_superuser(u) ) return actual_decorator(function)
def widget_detail(request, id, offset=0): wc = get_object_or_404(WidgetConfig, id=int(id)) if not check_user_superuser(request.user) and \ wc.group and not (check_ug_membership(request.user, wc.group) or \ wc.group.public or wc.type == WidgetConfig.TYPE_MICROSITE) or \ wc.user and wc.user_id != request.user.pk: return HttpResponseForbidden('Access denied!') widget_class = widget_registry.get(wc.app_name, wc.widget_name) if widget_class is None: return render('cosinnus/widgets/not_found.html') widget = widget_class(request, wc) widget_content, rows_returned, has_more = widget.get_data(int(offset)) data = { 'X-Cosinnus-Widget-Content': widget_content, 'X-Cosinnus-Widget-Title': force_text(widget.title), 'X-Cosinnus-Widget-App-Name': force_text(wc.app_name), 'X-Cosinnus-Widget-Widget-Name': force_text(wc.widget_name), 'X-Cosinnus-Widget-Num-Rows-Returned': rows_returned, 'X-Cosinnus-Widget-Has-More-Data': 'true' if has_more else 'false', } title_url = widget.title_url if title_url is not None: data['X-Cosinnus-Widget-Title-URL'] = force_text(title_url) return JSONResponse(data)
def process_request(self, request): if not getattr(settings, 'COSINNUS_ADMIN_2_FACTOR_AUTH_ENABLED', False): return None # regular mode covers the django-admin and administration area filter_path = '/admin' # strict mode covers the entire page if getattr(settings, 'COSINNUS_ADMIN_2_FACTOR_AUTH_STRICT_MODE', False): filter_path = '/' user = getattr(request, 'user', None) # check if the user is a superuser and they attempted to access a covered url if user and check_user_superuser(user) and request.path.startswith( filter_path) and not request.path in EXEMPTED_URLS_FOR_2FA: # check if the user is not yet 2fa verified, if so send them to the verification view if not user.is_verified(): next_url = request.path return redirect( reverse('cosinnus:login-2fa') + (('?next=%s' % next_url) if is_safe_url( next_url, allowed_hosts=[request.get_host()]) else '')) return None
def dispatch(self, request, *args, **kwargs): if not self.request.user.is_authenticated: return super(InvoiceDetailView, self).dispatch(request, *args, **kwargs) # must be owner of the invoice self.object = self.get_object() if not self.object.user == self.request.user and not check_user_superuser( self.request.user): raise PermissionDenied() # immediately download a ready invoice instead of showing its detail page if self.object.is_ready and self.object.file: return redirect( reverse('wechange-payments:invoice-download', kwargs={'pk': self.object.pk})) # for non-ready invoices, re-try API invoice creation in background if the retry delay is up if not self.object.is_ready: if now() > self.object.last_action_at + timedelta( minutes=settings.PAYMENTS_INVOICE_PROVIDER_RETRY_MINUTES): invoice_backend = get_invoice_backend() invoice_backend.create_invoice(self.object, threaded=True) return super(InvoiceDetailView, self).dispatch(request, *args, **kwargs)
def dispatch(self, request, *args, **kwargs): if not self.request.user.is_authenticated: return super(PaymentProcessView, self).dispatch(request, *args, **kwargs) self.object = self.get_object() # must be owner of the payment if not self.object.user == self.request.user and not check_user_superuser( self.request.user): raise PermissionDenied() # if the payment has been completed, redirect to the success page if self.object.status == Payment.STATUS_PAID: return redirect( reverse('wechange-payments:payment-success', kwargs={'pk': self.object.pk})) elif self.object.status not in [ Payment.STATUS_STARTED, Payment.STATUS_COMPLETED_BUT_UNCONFIRMED ]: messages.error( self.request, str(_('This payment session has expired.')) + ' ' + str( _('Please try again or contact our support for assistance!' ))) # redirect user to the payment form they were coming from if Subscription.get_active_for_user(self.request.user): return redirect('wechange-payments:payment-update') else: return redirect('wechange-payments:payment') return super(PaymentProcessView, self).dispatch(request, *args, **kwargs)
def get_management_urls(self, obj): user = self.context['request'].user if check_ug_admin(user, obj.group) or check_user_superuser(user): return { 'create_event': obj.room.get_room_create_url(), 'update_event': obj.get_edit_url(), 'delete_event': obj.get_delete_url(), } return {}
def __init__(self, haystack_result, obj, user, *args, **kwargs): kwargs.update({ 'is_superuser': check_user_superuser(user), 'is_member': check_ug_membership(user, obj), 'is_pending': check_ug_pending(user, obj), 'is_invited': check_ug_invited_pending(user, obj), 'creator_name': obj.creator and obj.creator.get_full_name(), 'creator_slug': obj.creator and obj.creator.username, 'title': obj.name, 'organization_type': obj.get_type(), 'website_url': obj.website, 'email': obj.email, 'phone_number': obj.phone_number.as_international if obj.phone_number else None, 'social_media': [{ 'url': sm.url, 'icon': sm.icon } for sm in obj.social_media.all()], 'edit_url': obj.get_edit_url(), 'accept_url': reverse('cosinnus:organization-user-accept', kwargs={'organization': obj.slug}), }) # collect administrator users. these are *not* filtered by visibility, as project admins are always visible! sqs = SearchQuerySet().models(SEARCH_MODEL_NAMES_REVERSE['people']) sqs = sqs.filter_and(admin_organizations=obj.id) #sqs = filter_searchqueryset_for_read_access(sqs, user) # private users are not visible to anonymous users, BUT they are visible to logged in users! # because if a user chose to make his group visible, he has to take authorship responsibilities if not user.is_authenticated: sqs = filter_searchqueryset_for_read_access(sqs, user) kwargs.update( {'admins': [HaystackUserMapCard(result) for result in sqs]}) # Groups sqs = SearchQuerySet().models(SEARCH_MODEL_NAMES_REVERSE['projects'], SEARCH_MODEL_NAMES_REVERSE['groups']) sqs = sqs.filter_and(id__in=haystack_result.groups) sqs = filter_searchqueryset_for_read_access(sqs, user) sqs = sqs.order_by('title') kwargs.update( {'groups': [HaystackGroupMapCard(result) for result in sqs]}) super(DetailedOrganizationMapResult, self).__init__(haystack_result, obj, user, *args, **kwargs)
def get_rooms(self, obj): rooms = obj.rooms.all() request = self.context['request'] if not (check_ug_admin(request.user, obj) or check_user_superuser(request.user)): rooms = rooms.visible() serializer = ConferenceRoomSerializer(instance=rooms, many=True, context={'request': request}) return serializer.data
def wrapper(self, request, *args, **kwargs): user = request.user if not user.is_authenticated: return redirect_to_not_logged_in(request, view=self) if not check_user_superuser(user): raise PermissionDenied( 'You do not have permission to access this page.') return function(self, request, *args, **kwargs)
def check_restricted_recipient(self, message, user=None): if message.multi_conversation: recipient_group_slugs = message.multi_conversation.targetted_groups.all( ).values_list('slug', flat=True) if getattr(settings, 'NEWW_FORUM_GROUP_SLUG', None) and getattr( settings, 'NEWW_FORUM_GROUP_SLUG' ) in recipient_group_slugs and not check_user_superuser( user or self.request.user): return True return False
def dispatch(self, request, *args, **kwargs): if not check_user_superuser(request.user): raise PermissionDenied( 'You do not have permission to access this page.') self.portal = CosinnusPortal.get_current() if request.GET.get('send_test', False) == '1': _send_user_welcome_email_if_enabled(self.request.user, force=True) return redirect(self.get_success_url()) return super(UserWelcomeEmailEditView, self).dispatch(request, *args, **kwargs)
def get_queryset(self): if not getattr(self, 'qs', None): qs = super(UserProfileDetailView, self).get_queryset() if not (self.request.GET.get('force_show', False) == '1' and check_user_superuser(self.request.user)): qs = qs.exclude(user__is_active=False).\ exclude(user__last_login__exact=None).\ filter(settings__contains='tos_accepted') self.qs = qs return self.qs
def filter_searchqueryset_for_read_access(sqs, user): """ Given a SearchQuerySet, this function adds a filter that limits the result set to only include elements with read access. """ public_node = ( SQ(public__exact=True) | # public on the object itself (applicable for groups) SQ(mt_visibility__exact=BaseTagObject.VISIBILITY_ALL) | # public via "everyone can see me" visibility meta attribute SQ( always_visible__exact=True ) # special marker for indexed objects that should always show up in search ) if user.is_authenticated(): if check_user_superuser(user): pass else: logged_in_user_visibility = ( SQ(user_visibility_mode__exact=True) & # for UserProfile search index objects SQ( mt_visibility__exact=BaseTagObject.VISIBILITY_GROUP ) # logged in users can see users who are visible ) my_item = (SQ(creator__exact=user.id)) visible_for_all_authenticated_users = (SQ( visible_for_all_authenticated_users=True)) # FIXME: known problem: ``group_members`` is a stale indexed representation of the members # of an items group. New members of a group won't be able to find old indexed items if the index # is not refreshed regularly group_visible_and_in_my_group = ( SQ(mt_visibility__exact=BaseTagObject.VISIBILITY_GROUP) & SQ(group_members__contains=user.id)) ored_query = public_node | group_visible_and_in_my_group | my_item \ | logged_in_user_visibility | visible_for_all_authenticated_users users_group_ids = get_cosinnus_group_model( ).objects.get_for_user_pks(user) if users_group_ids: group_member_user_visibility = ( SQ(user_visibility_mode__exact=True) & # for UserProfile search index objects SQ(mt_visibility__exact=BaseTagObject.VISIBILITY_USER) & # team mambers can see this user SQ(membership_groups__in=users_group_ids)) ored_query = ored_query | group_member_user_visibility sqs = sqs.filter_and(ored_query) else: sqs = sqs.filter_and(public_node) return sqs
def __init__(self, *args, **kwargs): super(CustomWriteForm, self).__init__(*args, **kwargs) # retrieve the attached objects ids to select them in the update view users = [] initial_users = kwargs['initial'].get('recipients', None) preresults = [] use_ids = False recipient_list = [] if initial_users: recipient_list = initial_users.split(', ') # delete the initial data or our select2 field initials will be overwritten by django if 'recipients' in kwargs['initial']: del kwargs['initial']['recipients'] if 'recipients' in self.initial: del self.initial['recipients'] elif 'data' in kwargs and kwargs['data'].getlist('recipients'): recipient_list = kwargs['data'].getlist('recipients') use_ids = True if recipient_list: ids = self.fields['recipients'].get_ids_for_value(recipient_list, intify=use_ids) user_tokens = ids.get('user', []) group_tokens = ids.get('group', []) if use_ids: # restrict writing to the forum group forum_slug = getattr(settings, 'NEWW_FORUM_GROUP_SLUG', None) if forum_slug: try: forum_group_id = CosinnusGroup.objects.get_cached(slugs=forum_slug).id if forum_group_id in group_tokens and not check_user_superuser(kwargs['sender']): self.restricted_recipient_flag = True except CosinnusGroup.DoesNotExist: pass users = get_user_model().objects.filter(id__in=user_tokens) groups = CosinnusGroup.objects.get_cached(pks=group_tokens) else: # restrict writing to the forum group if getattr(settings, 'NEWW_FORUM_GROUP_SLUG', None) and getattr(settings, 'NEWW_FORUM_GROUP_SLUG') in group_tokens: self.restricted_recipient_flag = True users = get_user_model().objects.filter(username__in=user_tokens) groups = CosinnusGroup.objects.get_cached(slugs=group_tokens) # save away for later self.targetted_groups = groups preresults = get_user_select2_pills(users, text_only=False) preresults.extend(get_group_select2_pills(groups, text_only=False)) # we need to cheat our way around select2's annoying way of clearing initial data fields self.fields['recipients'].choices = preresults self.fields['recipients'].initial = [key for key,val in preresults] self.initial['recipients'] = self.fields['recipients'].initial
def can_user_assign(self, user): """ Test if a user can assign this object """ if self.creator_id == user.pk: return True if self.group.is_admin(user): return True if check_user_superuser(user): return True return False
def dispatch(self, *args, **kwargs): """ Find out which type of CosinnusOrganization (project/society), we're dealing with here. """ # special check, if group/project creation is limited to admins, deny regular users creating groups/projects if getattr(settings, 'COSINNUS_LIMIT_ORGANIZATION_CREATION_TO_ADMINS', False) \ and not check_user_superuser(self.request.user) and self.form_view == 'add': messages.warning(self.request, _('Sorry, only portal administrators can create projects and groups!')) return redirect(reverse('cosinnus:portal-admin-list')) # special check: only portal admins can create groups if not getattr(settings, 'COSINNUS_USERS_CAN_CREATE_ORGANIZATIONS', False) \ and self.form_view == 'add': if not check_user_superuser(self.request.user): if getattr(settings, 'COSINNUS_CUSTOM_PREMIUM_PAGE_ENABLED', False): redirect_url = reverse('cosinnus:premium-info-page') else: messages.warning(self.request, _( 'Sorry, only portal administrators can create Organizations! You can either create a Project, or write a message to one of the administrators to create a Organization for you. Below you can find a listing of all administrators.')) redirect_url = reverse('cosinnus:portal-admin-list') return redirect(redirect_url) return super(CosinnusOrganizationFormMixin, self).dispatch(*args, **kwargs)
def dispatch(self, request, *args, **kwargs): if not self.request.user.is_authenticated: return super(InvoiceDownloadView, self).dispatch(request, *args, **kwargs) # must be owner of the invoice self.object = self.get_object() if not self.object.user == self.request.user and not check_user_superuser( self.request.user): raise PermissionDenied() if not self.object.is_ready or not self.object.file: return HttpResponseNotFound() return super(InvoiceDownloadView, self).dispatch(request, *args, **kwargs)
def get_management_urls(self, obj): user = self.context['request'].user management_urls = {} # available for all members if check_ug_membership(user, obj) or check_user_superuser(user): management_urls.update({ 'manage_memberships': group_aware_reverse('cosinnus:group-detail', kwargs={'group': obj}) }) if check_ug_admin(user, obj) or check_user_superuser(user): management_urls.update({ 'manage_conference': group_aware_reverse('cosinnus:group-edit', kwargs={'group': obj}), 'manage_rooms': group_aware_reverse('cosinnus:conference:room-management', kwargs={'group': obj}), 'manage_events': group_aware_reverse('cosinnus:event:conference-event-list', kwargs={'group': obj}), }) return management_urls
def get_management_urls(self, obj): user = self.context['request'].user if check_ug_admin(user, obj.group) or check_user_superuser(user): management_urls = { 'update_room': obj.get_edit_url(), 'delete_room': obj.get_delete_url(), } # Lobby room types do not have a "Create Event" button if obj.type != CosinnusConferenceRoom.TYPE_LOBBY: management_urls.update({ 'create_event': obj.get_room_create_url(), }) return management_urls return {}
def get_password_for_user(self, user): """ returns the room password according to the permission of a given user. Returns empty string, if user is no member of the room :return: password for the user to join the room :rtype: str """ if user in self.attendees.all(): return self.attendee_password elif user in self.moderators.all(): return self.moderator_password elif check_user_superuser(user): return self.attendee_password else: return ''
def save_m2m(): old_save_m2m() new_group_slugs = [new_group.slug for new_group in self.cleaned_data['related_groups']] old_related_group_slugs = self.instance.related_groups.all().values_list('slug', flat=True) # remove no longer wanted related_groups for old_slug in old_related_group_slugs: if old_slug not in new_group_slugs: old_group_rel = get_object_or_None(RelatedGroups, to_group=self.instance, from_group__slug=old_slug) old_group_rel.delete() # add new related_groups user_group_ids = get_cosinnus_group_model().objects.get_for_user_pks(self.request.user) user_superuser = check_user_superuser(self.request.user) conference_notification_pairs = [] for related_group in self.cleaned_data['related_groups']: # non-superuser users can only tag groups they are in if not user_superuser and related_group.id not in user_group_ids: continue # only create group rel if it didn't exist existing_group_rel = get_object_or_None(RelatedGroups, to_group=self.instance, from_group=related_group) if not existing_group_rel: # create a new related group link RelatedGroups.objects.create(to_group=self.instance, from_group=related_group) # if the current group is a conference, and the related group is a society or project, # the conference will be reflected into the group, so we send a notification non_conference_group_types = [get_cosinnus_group_model().TYPE_PROJECT, get_cosinnus_group_model().TYPE_SOCIETY] if self.instance.group_is_conference and related_group.type in non_conference_group_types: audience_except_creator = [member for member in related_group.actual_members if member.id != self.request.user.id] # set the target group for the notification onto the group instance setattr(self.instance, 'notification_target_group', related_group) conference_notification_pairs.append((self.instance, audience_except_creator)) # send notifications in a session to avoid duplicate messages to any user session_id = uuid1().int for i, pair in enumerate(conference_notification_pairs): cosinnus_notifications.conference_created_in_group.send( sender=self, user=self.request.user, obj=pair[0], audience=pair[1], session_id=session_id, end_session=bool(i == len(conference_notification_pairs)-1) )
def check_all_permissions(self, request, *args, **kwargs): super(RequireGroupMember, self).check_all_permissions(request, *args, **kwargs) group_slug = kwargs.get('group', None) if group_slug is None: raise PermissionDenied try: self.group = CosinnusGroup.objects.get(slug=group_slug) except CosinnusGroup.DoesNotExist: raise PermissionDenied user = request.user if not (check_user_superuser(user) or check_ug_membership(user, self.group)): raise PermissionDenied
def user_dashboard_announcement_activate(request, slug): """ Toggles an announcement active/inactive """ if not check_user_superuser(request.user): return HttpResponseForbidden('Not authenticated') announcement = get_object_or_None(UserDashboardAnnouncement, portal=CosinnusPortal.get_current(), slug=slug) if announcement is None: return HttpResponseNotFound() announcement.is_active = not announcement.is_active announcement.save() if announcement.is_active: messages.success(request, _('Your Announcement was activated successfully.')) else: messages.success(request, _('Your Announcement was deactivated successfully.')) return redirect('cosinnus:user-dashboard-announcement-list')
def get_header_notification(self, obj): user = self.context['request'].user # show a premium notification for admins if (settings.COSINNUS_PREMIUM_CONFERENCES_ENABLED and not obj.is_premium) \ and (check_ug_admin(user, obj) or check_user_superuser(user)): header_notification = { 'notification_text': _('Your conference is still in trial mode. You have access to all features, but can only use them with a few people without restrictions. To ensure full performance for your conference with multiple users, book sufficient capacities here for free:' ), 'link_text': _('Conference Bookings'), 'link_url': render_to_string( 'cosinnus/v2/urls/conference_premium_booking_url.html', context={ 'COSINNUS_CURRENT_LANGUAGE': get_language(), }), } return header_notification return {}
def get_results(self, request, term, page, context): term = term.lower() start = (page - 1) * 10 end = page * 10 q = Q(name__icontains=term) # add all extra lookup fields defined by swapped out group models for lookup_field in get_cosinnus_group_model().NAME_LOOKUP_FIELDS: if lookup_field != 'name': q = q | Q(**{lookup_field + '__icontains': term}) qs = get_cosinnus_group_model().objects.filter(q).filter( portal_id=CosinnusPortal.get_current().id, is_active=True) # non-superusers may only select groups they are in if not check_user_superuser(request.user): user_group_ids = get_cosinnus_group_model( ).objects.get_for_user_pks(request.user) qs = qs.filter(id__in=user_group_ids) if request.GET.get('except', None): qs = qs.exclude(id=int(request.GET.get('except'))) # TODO: also search russian/other extension fields of name, make a good interface to generically grab those count = qs.count() if count < start: raise Http404 has_more = count > end groups = [] for group in qs[start:end]: # do/do not return the forum group #if group.slug == getattr(settings, 'NEWW_FORUM_GROUP_SLUG', None): # continue # access group.name by its dict lookup to support translation magic groups.append((group.id, group['name'])) return (NO_ERR_RESP, has_more, groups)
def dispatch(self, request, *args, **kwargs): if not self.request.user.is_authenticated: return super(PaymentSuccessView, self).dispatch(request, *args, **kwargs) self.object = self.get_object() # must be owner of the payment if not self.object.user == self.request.user and not check_user_superuser( self.request.user): raise PermissionDenied() # if the payment has not been completed, redirect to the process page if self.object.status == Payment.STATUS_STARTED or self.object.status == Payment.STATUS_COMPLETED_BUT_UNCONFIRMED: return redirect( reverse('wechange-payments:payment-process', kwargs={'pk': self.object.pk})) elif self.object.status != Payment.STATUS_PAID: messages.error( request, str(_('There was an error with your payment.')) + ' ' + str(_('Please contact our support for assistance!'))) return redirect('wechange-payments:overview') return super(PaymentSuccessView, self).dispatch(request, *args, **kwargs)
def get_queryset(self): queryset = self.queryset if not check_user_superuser(self.request.user): user_group_ids = get_cosinnus_group_model().objects.get_for_user_pks(self.request.user) queryset = queryset.filter(room__group__id__in=user_group_ids, room__is_visible=True) return queryset
def grant_extra_read_permissions(self, user): return self.user == user or check_user_superuser(user)
def is_superuser(user): """ Template filter to check if a user has admin priviledges or is a portal admin. """ return check_user_superuser(user)