diff --git a/tollgate/frontend/migrations/0005_auto__add_field_userprofile_maximum_quota_signins__add_field_userprofi.py b/tollgate/frontend/migrations/0005_auto__add_field_userprofile_maximum_quota_signins__add_field_userprofi.py new file mode 100644 index 0000000..5f13945 --- /dev/null +++ b/tollgate/frontend/migrations/0005_auto__add_field_userprofile_maximum_quota_signins__add_field_userprofi.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'UserProfile.maximum_quota_signins' + db.add_column('frontend_userprofile', 'maximum_quota_signins', + self.gf('django.db.models.fields.PositiveIntegerField')(default=0), + keep_default=False) + + # Adding field 'UserProfile.maximum_quota_resets' + db.add_column('frontend_userprofile', 'maximum_quota_resets', + self.gf('django.db.models.fields.PositiveIntegerField')(default=0), + keep_default=False) + + def backwards(self, orm): + # Deleting field 'UserProfile.maximum_quota_signins' + db.delete_column('frontend_userprofile', 'maximum_quota_signins') + + # Deleting field 'UserProfile.maximum_quota_resets' + db.delete_column('frontend_userprofile', 'maximum_quota_resets') + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'frontend.event': { + 'Meta': {'ordering': "['start']", 'object_name': 'Event'}, + 'end': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'}), + 'start': ('django.db.models.fields.DateTimeField', [], {}) + }, + 'frontend.eventattendance': { + 'Meta': {'ordering': "['event', 'user_profile']", 'object_name': 'EventAttendance'}, + 'coffee': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.Event']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'quota_amount': ('django.db.models.fields.BigIntegerField', [], {'default': '157286400L'}), + 'quota_multiplier': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'quota_unmetered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'quota_used': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'registered_by'", 'null': 'True', 'to': "orm['frontend.UserProfile']"}), + 'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.UserProfile']"}) + }, + 'frontend.ip4portforward': { + 'Meta': {'object_name': 'IP4PortForward'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.UserProfile']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'external_port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'host': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.NetworkHost']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'protocol': ('django.db.models.fields.related.ForeignKey', [], {'default': '6', 'to': "orm['frontend.IP4Protocol']"}) + }, + 'frontend.ip4protocol': { + 'Meta': {'ordering': "['name']", 'object_name': 'IP4Protocol'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'has_port': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'frontend.networkhost': { + 'Meta': {'ordering': "['mac_address']", 'object_name': 'NetworkHost'}, + 'computer_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'first_connection': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip_address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}), + 'mac_address': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'online': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.UserProfile']", 'null': 'True', 'blank': 'True'}) + }, + 'frontend.networkhostownerchangeevent': { + 'Meta': {'ordering': "['when']", 'object_name': 'NetworkHostOwnerChangeEvent'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'network_host': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.NetworkHost']"}), + 'new_owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'new_owner'", 'null': 'True', 'to': "orm['frontend.UserProfile']"}), + 'old_owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'old_owner'", 'null': 'True', 'to': "orm['frontend.UserProfile']"}), + 'when': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + 'frontend.networkusagedatapoint': { + 'Meta': {'ordering': "['event_attendance', 'when']", 'object_name': 'NetworkUsageDataPoint'}, + 'bytes': ('django.db.models.fields.BigIntegerField', [], {}), + 'event_attendance': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.EventAttendance']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'when': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + 'frontend.oui': { + 'Meta': {'ordering': "['hex']", 'object_name': 'Oui'}, + 'full_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'hex': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '6'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_console': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}) + }, + 'frontend.quotaresetevent': { + 'Meta': {'ordering': "['when']", 'object_name': 'QuotaResetEvent'}, + 'event_attendance': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['frontend.EventAttendance']"}), + 'excuse': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'performer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'performer'", 'to': "orm['frontend.UserProfile']"}), + 'when': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + 'frontend.userprofile': { + 'Meta': {'ordering': "['user__username']", 'object_name': 'UserProfile'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internet_on': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'maximum_quota_resets': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'maximum_quota_signins': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'theme': ('django.db.models.fields.CharField', [], {'default': "'cake'", 'max_length': '30'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user'", 'unique': 'True', 'to': "orm['auth.User']"}) + } + } + + complete_apps = ['frontend'] \ No newline at end of file diff --git a/tollgate/frontend/models.py b/tollgate/frontend/models.py index 9ecd1c1..1b7a15c 100644 --- a/tollgate/frontend/models.py +++ b/tollgate/frontend/models.py @@ -79,6 +79,32 @@ class Meta: internet_on = BooleanField(default=True) theme = CharField(default='cake', max_length=30, choices=THEME_CHOICES) + maximum_quota_signins = PositiveIntegerField( + default=0, + help_text=_("""\ + Sets the maximum amount of quota in MiB that the user may grant to + users they sign in. If set to 0, they will be able to set any quota + amount. Setting this value disallows setting unlimited quota. + + This will only have effect if the user has been granted permission + to sign in users. Otherwise, they will not be able to sign in users. + """) + ) + + maximum_quota_resets = PositiveIntegerField( + default=0, + help_text=_("""\ + Sets the maximum amount of quota resets that the user may perform on + other users. If set to 0, they will be able to reset quota an + unlimited number of times. If set to 1, this will mean that the user + can only perform the "one free reset" on behalf of another user. + + This will only have effect if the user has been granted permission + to reset user quota for other users. Otherwise, they will not be able + to reset quota for other users at all. + """) + ) + def get_hosts(self): return NetworkHost.objects.filter(user_profile=self) @@ -179,6 +205,8 @@ class Meta: ("can_view_quota", "View quota"), ("can_reset_quota", "Reset quota"), ("can_change_coffee", "Coffee request access change"), # this is a seperate ACL because of ravenge and dasman + ('can_reset_own_quota', 'Reset own quota multiple times'), + ('can_revoke_access', 'Revoke internet access for a user'), ) event = ForeignKey(Event) user_profile = ForeignKey(UserProfile) diff --git a/tollgate/frontend/templates/frontend/quota.html b/tollgate/frontend/templates/frontend/quota.html index 83c4013..3b7646a 100644 --- a/tollgate/frontend/templates/frontend/quota.html +++ b/tollgate/frontend/templates/frontend/quota.html @@ -170,9 +170,17 @@

Internet Switch

{% endif %}

Your Computers and Devices

diff --git a/tollgate/frontend/templates/frontend/usage-info.html b/tollgate/frontend/templates/frontend/usage-info.html index cf13e19..5e7a322 100644 --- a/tollgate/frontend/templates/frontend/usage-info.html +++ b/tollgate/frontend/templates/frontend/usage-info.html @@ -19,8 +19,8 @@ {% load url from future %} {% load i18n %} {% load humanize %} -{% block windowtitle %}internet usage report for {{ a.user_profile.user.username }} {% endblock %} -{% block title %}internet usage report for {{ a.user_profile.user.username }} {% endblock %} +{% block windowtitle %}internet usage report for {{ a.user_profile.user.username }} at {{ a.event.name }}{% endblock %} +{% block title %}internet usage report for {{ a.user_profile.user.username }} at {{ a.event.name }}{% endblock %} {% block content %} {% if quota_update_fail %} @@ -46,9 +46,17 @@

Internet Switch (currently {% if a.user_profile.internet_on %}Switch on {{ a.user_profile.user.username }}'s internet connectivity. If they have quota available, internet access will be granted to all of their computers and devices. +
  • +
    {% csrf_token %} + If they have quota available, internet access will be granted to all of their computers and devices. +
    +
  • {% endif %} -
  • Switch off {{ a.user_profile.user.username }}'s internet connectivity. All computers listed here will loose internet access immediately, and all unfinished downloads will be terminated. Internet access will resume when you or they opt to, or when they try to connect another computer to the internet in their name.
  • +
  • +
    {% csrf_token %} + All computers listed here will loose internet access immediately, and all unfinished downloads will be terminated. Internet access will resume when you or they opt to, or when they try to connect another computer to the internet in their name. +
    +
  • {% else %}
  • You're not authorised to toggle other users' internet access, you need can_toggle_internet.
  • {% endif %} @@ -65,9 +73,17 @@

    Internet Switch (currently {% if a.user_profile.internet_on %}Revoke internet access rights. The user will loose their unlimited status (if any), and their available quota multiplier will be set to zero. Internet access will be terminated, and can only be reinstated by an administrator. {% else %} -
  • You're not authorised to reset user quotas or revoke internet access, you need can_reset_quota.
  • +
  • You're not authorised to reset user quotas, you need can_reset_quota.
  • + {% endif %} + {% if perms.frontend.can_revoke_access %} +
  • +
    {% csrf_token %} + The user will loose their unlimited status (if any), and their available quota multiplier will be set to zero. Internet access will be terminated, and can only be reinstated by an administrator. +
    +
  • + {% else %} +
  • You're not authorised to revoke internet access, you need can_revoke_access.
  • {% endif %} diff --git a/tollgate/frontend/templates/frontend/usage.html b/tollgate/frontend/templates/frontend/usage.html index e146e8a..6bae0f8 100644 --- a/tollgate/frontend/templates/frontend/usage.html +++ b/tollgate/frontend/templates/frontend/usage.html @@ -30,9 +30,21 @@
      {% if perms.frontend.can_toggle_internet %} -
    • Turn on everyone's internet access that has opted to switch it on
    • -
    • Turn on everyone's internet access, even if they have disabled it
    • -
    • Turn off everyone's internet access.
    • +
    • +
      {% csrf_token %} + +
      +
    • +
    • +
      {% csrf_token %} + +
      +
    • +
    • +
      {% csrf_token %} + +
      +
    • {% else %}
    • You're not authorised to toggle other users' internet access, you need can_toggle_internet.
    • {% endif %} diff --git a/tollgate/frontend/urls.py b/tollgate/frontend/urls.py index 9bd0d95..295c9d4 100644 --- a/tollgate/frontend/urls.py +++ b/tollgate/frontend/urls.py @@ -67,7 +67,6 @@ url(r'^usage/(?P\d+)/off/$', 'usage_off', name='usage-off'), url(r'^usage/(?P\d+)/reset/$', 'usage_reset', name='usage-reset'), url(r'^usage/(?P\d+)/disable/$', 'usage_disable', name='usage-disable'), - url(r'^usage/(?P\d+)/coffee/$', 'usage_coffee', name='usage-coffee'), #url(r'^usage/(?P\d+)/graph.png$', 'usage_graph', name='usage-graph'), url(r'^usage/(?P\d+)/$', 'usage_info', name='usage-info'), url(r'^usage/$', 'usage', name='usage'), diff --git a/tollgate/frontend/views.py b/tollgate/frontend/views.py index d8a6c0c..b35e274 100644 --- a/tollgate/frontend/views.py +++ b/tollgate/frontend/views.py @@ -401,25 +401,26 @@ def quota(request): @login_required def quota_on(request): - user = request.user - profile = get_userprofile(user) - current_event = get_current_event() - if current_event == None: - return render_to_response('frontend/event-not-active.html', - context_instance=RequestContext(request)) + if request.method == 'POST': + user = request.user + profile = get_userprofile(user) + current_event = get_current_event() + if current_event == None: + return render_to_response('frontend/event-not-active.html', + context_instance=RequestContext(request)) - attendance = get_userprofile_attendance(current_event, profile) - if attendance == None: - return render_to_response('frontend/not-signed-in.html', dict( - event=current_event - ), context_instance=RequestContext(request)) + attendance = get_userprofile_attendance(current_event, profile) + if attendance == None: + return render_to_response('frontend/not-signed-in.html', dict( + event=current_event + ), context_instance=RequestContext(request)) - if not attendance.is_revoked: - try: - enable_user_quota(attendance) - sync_user_connections(profile) - except: - return controller_error(request) + if not attendance.is_revoked: + try: + enable_user_quota(attendance) + sync_user_connections(profile) + except: + return controller_error(request) return redirect('quota') @@ -489,21 +490,23 @@ def quota_user_reset(request): @login_required def quota_off(request): - user = request.user - profile = get_userprofile(user) - current_event = get_current_event() - if current_event == None: - return render_to_response('frontend/event-not-active.html', - context_instance=RequestContext(request)) - attendance = get_userprofile_attendance(current_event, profile) - if attendance == None: - return render_to_response('frontend/not-signed-in.html', dict( - event=current_event - ), context_instance=RequestContext(request)) - try: - disable_user_quota(attendance) - except: - return controller_error(request) + if request.method == 'POST': + user = request.user + profile = get_userprofile(user) + current_event = get_current_event() + if current_event == None: + return render_to_response('frontend/event-not-active.html', + context_instance=RequestContext(request)) + attendance = get_userprofile_attendance(current_event, profile) + if attendance == None: + return render_to_response('frontend/not-signed-in.html', dict( + event=current_event + ), context_instance=RequestContext(request)) + try: + disable_user_quota(attendance) + except: + return controller_error(request) + return redirect('quota') @@ -667,13 +670,24 @@ def usage_reset(request, aid): # check if I'm trying to reset quota for the current user. my_profile = get_userprofile(request.user) - if a.user_profile == my_profile and a.quota_multiplier > 1: + if not request.user.has_perm('frontend.can_reset_own_quota') and \ + (a.user_profile == my_profile and a.quota_multiplier > 1): # current user is trying to reset their own quota, and they have already - # reset quota before. + # reset quota before, and they do not have permission to reset their own + # quota. return render_to_response('frontend/cant-reset-yourself.html', context_instance=RequestContext(request)) - - if not a.quota_unmetered: + + if my_profile.maximum_quota_resets > 0 and \ + my_profile.maximum_quota_resets < a.quota_multiplier: + # maximum quota resets exceeded. + messages.error(request, + _("""\ + The user has already had their quota more times than you are + allowed to reset it for them. + """) + ) + elif not a.quota_unmetered: # do the log event first as that's more important. excuse = reset_form.cleaned_data['excuse'] QuotaResetEvent.objects.create( @@ -695,55 +709,59 @@ def usage_reset(request, aid): @user_passes_test(lambda u: u.has_perm('frontend.can_toggle_internet')) def usage_all_on(request): - # find all users that are in attendance this lan - current_event = get_current_event() - if current_event == None: - return render_to_response('frontend/event-not-active.html', - context_instance=RequestContext(request)) + if request.method == 'POST': + # find all users that are in attendance this lan + current_event = get_current_event() + if current_event == None: + return render_to_response('frontend/event-not-active.html', + context_instance=RequestContext(request)) - attendances = EventAttendance.objects.filter(event__exact=current_event) - for attendance in attendances: - if attendance.user_profile.internet_on: - enable_user_quota(attendance) + attendances = EventAttendance.objects.filter(event__exact=current_event) + for attendance in attendances: + if attendance.user_profile.internet_on: + enable_user_quota(attendance) + return redirect('usage') @user_passes_test(lambda u: u.has_perm('frontend.can_toggle_internet')) def usage_all_really_on(request): - # find all users that are in attendance this lan - current_event = get_current_event() - if current_event == None: - return render_to_response('frontend/event-not-active.html', - context_instance=RequestContext(request)) + if request.method == 'POST': + # find all users that are in attendance this lan + current_event = get_current_event() + if current_event == None: + return render_to_response('frontend/event-not-active.html', + context_instance=RequestContext(request)) - attendances = EventAttendance.objects.filter(event__exact=current_event) + attendances = EventAttendance.objects.filter(event__exact=current_event) - sid = transaction.savepoint() - for attendance in attendances: - attendance.internet_on = True - enable_user_quota(attendance) - attendance.save() - transaction.savepoint_commit(sid) + sid = transaction.savepoint() + for attendance in attendances: + attendance.internet_on = True + enable_user_quota(attendance) + attendance.save() + transaction.savepoint_commit(sid) return redirect('usage') @user_passes_test(lambda u: u.has_perm('frontend.can_toggle_internet')) def usage_all_off(request): - # find all users that are in attendance this lan - current_event = get_current_event() - if current_event == None: - return render_to_response('frontend/event-not-active.html', - context_instance=RequestContext(request)) + if request.method == 'POST': + # find all users that are in attendance this lan + current_event = get_current_event() + if current_event == None: + return render_to_response('frontend/event-not-active.html', + context_instance=RequestContext(request)) - attendances = EventAttendance.objects.filter(event__exact=current_event) + attendances = EventAttendance.objects.filter(event__exact=current_event) - sid = transaction.savepoint() - for attendance in attendances: - attendance.user_profile.internet_on = False - attendance.user_profile.save() - disable_user_quota(attendance) - transaction.savepoint_commit(sid) + sid = transaction.savepoint() + for attendance in attendances: + attendance.user_profile.internet_on = False + attendance.user_profile.save() + disable_user_quota(attendance) + transaction.savepoint_commit(sid) return redirect('usage') @@ -751,37 +769,32 @@ def usage_all_off(request): @user_passes_test(lambda u: u.has_perm('frontend.can_toggle_internet')) def usage_on(request, aid): a = get_object_or_404(EventAttendance, id=aid) - enable_user_quota(a) + + if request.method == 'POST': + enable_user_quota(a) return redirect('usage-info', a.id) @user_passes_test(lambda u: u.has_perm('frontend.can_toggle_internet')) def usage_off(request, aid): a = get_object_or_404(EventAttendance, id=aid) - disable_user_quota(a) + if request.method == 'POST': + disable_user_quota(a) + return redirect('usage-info', a.id) -@user_passes_test(lambda u: u.has_perm('frontend.can_reset_quota')) +@user_passes_test(lambda u: u.has_perm('frontend.can_revoke_access')) def usage_disable(request, aid): + # revoke interent access for the user. a = get_object_or_404(EventAttendance, id=aid) - a.quota_multiplier = 0 - a.quota_unmetered = False - a.save() - disable_user_quota(a) - return redirect('usage-info', a.id) - -@user_passes_test(lambda u: u.has_perm('frontend.can_change_coffee')) -def usage_coffee(request, aid): - a = get_object_or_404(EventAttendance, id=aid) if request.method == "POST": - coffee_form = CoffeeForm(request.POST) - if coffee_form.is_valid(): - a.coffee = coffee_form.cleaned_data["coffee"] - a.save() + a.quota_multiplier = 0 + a.quota_unmetered = False + a.save() + disable_user_quota(a) - # we're done now, redirect back. return redirect('usage-info', a.id) @@ -952,7 +965,7 @@ def signin1(request): ), context_instance=RequestContext(request)) -@user_passes_test(lambda u: u.has_perm('frontend.can_signin')) +@user_passes_test(lambda u: u.has_perm('frontend.can_register_attendance')) def signin2(request): event = get_current_event() if event == None: @@ -1012,7 +1025,8 @@ def signin2(request): @user_passes_test(lambda u: u.has_perm('frontend.can_register_attendance')) def signin3(request, uid): u = get_object_or_404(User, id=uid) - + my_profile = get_userprofile(request.user) + current_event = get_current_event() if current_event == None: messages.warning(request, @@ -1036,31 +1050,50 @@ def signin3(request, uid): # create an attendance! if f.cleaned_data['quota_unlimited']: - # create unmetered attendance - a = EventAttendance( - quota_unmetered=True, - event=current_event, - user_profile=u.get_profile(), - registered_by=request.user.get_profile() - ) + # check if setting unlimited quota is allowed. + if my_profile.maximum_quota_signins == 0: + # create unmetered attendance + a = EventAttendance( + quota_unmetered=True, + event=current_event, + user_profile=u.get_profile(), + registered_by=request.user.get_profile() + ) + else: + a = None + messages.error(request, _("""\ + You are not permitted to sign in users with unlimited quota. + """)) else: - a = EventAttendance( - quota_amount=f.cleaned_data['quota_amount'] * 1048576, - event=current_event, - user_profile=u.get_profile(), - registered_by=request.user.get_profile() + quota_amount = f.cleaned_data['quota_amount'] + if my_profile.maximum_quota_signins == 0 or \ + my_profile.maximum_quota_signins >= quota_amount: + + a = EventAttendance( + quota_amount=quota_amount * 1048576, + event=current_event, + user_profile=u.get_profile(), + registered_by=request.user.get_profile() + ) + else: + a = None + messages.error(request, _("""\ + You are not permitted to sign in users with more than + %(max_quota)d MiB of quota. + """) % dict(max_quota=my_profile.maximum_quota_signins)) + + if a != None: + # attendance created, proceed + a.save() + + # now sync user connections + enable_user_quota(a) + + # attendance created, go back to signin page + messages.success(request, + _('Attendance registered, and enabled internet access for user.') ) - - a.save() - - # now sync user connections - enable_user_quota(a) - - # attendance created, go back to signin page - messages.success(request, - _('Attendance registered, and enabled internet access for user.') - ) - return redirect('signin') + return redirect('signin') else: f = SignInForm3()