Skip to content
Snippets Groups Projects
Commit c8ed258f authored by Flavio TARSETTI's avatar Flavio TARSETTI
Browse files

[accounts/ui/utils/navigation] added remove supervisee endpoint for godfather...

[accounts/ui/utils/navigation] added remove supervisee endpoint for godfather + management to block users + patched key relation for supervisee + started new endpoint to make request for supervision
parent 42348ef0
No related branches found
No related tags found
1 merge request!224Security accounts
Pipeline #
Showing
with 405 additions and 3 deletions
...@@ -52,12 +52,13 @@ from .models import SupervisionTrack, Profile ...@@ -52,12 +52,13 @@ from .models import SupervisionTrack, Profile
from ..common.models import Shareable from ..common.models import Shareable
from ..common.exceptions import ShareError from ..common.exceptions import ShareError
from ..common.mixins import CommonContextMixin from ..common.mixins import CommonContextMixin
from ..ui.registration.models import RegistrationProfile
from itertools import chain from itertools import chain
from datetime import datetime, timedelta from datetime import datetime, timedelta
from .permissions import IsGodfatherAndAuthor from .permissions import IsGodfatherAndAuthor, IsAuthorAndNotGodfather
from ..common.responses import BadRequestResponse, ForbiddenResponse from ..common.responses import BadRequestResponse, ForbiddenResponse
...@@ -168,3 +169,194 @@ class GodfatherAddSuperviseeView(BaseUpdateSupervisionTrackView): ...@@ -168,3 +169,194 @@ class GodfatherAddSuperviseeView(BaseUpdateSupervisionTrackView):
#---------------------------------------------------------- #----------------------------------------------------------
class GodfatherRemoveSuperviseeView(BaseUpdateSupervisionTrackView):
permission_classes = BaseUpdateSupervisionTrackView.permission_classes
def put(self, request, supervisee_name):
supervisee = User.objects.get(username=supervisee_name)
supervisiontrack = SupervisionTrack.objects.get(godfather=request.user, supervisee=supervisee, supervisee__profile__supervision_key=models.F('supervision_key'))
from django.core.mail import send_mail
parsed_url = urlparse(settings.URL_PREFIX)
server_address = '%s://%s' % (parsed_url.scheme, parsed_url.hostname)
c = Context({ 'supervisor': supervisiontrack.godfather,
'supervisee': supervisee,
'prefix': server_address,
})
if supervisee.profile.status == Profile.WAITINGVALIDATION:
#New user account waiting validation, so delete this account and inform by email the user
try:
t = loader.get_template('registration/mail.godfather_rejected.subject.txt')
subject = t.render(c)
# Note: e-mail subject *must not* contain newlines
subject = settings.EMAIL_SUBJECT_PREFIX + ''.join(subject.splitlines())
t = loader.get_template('registration/mail.godfather_rejected_delete_account.message.txt')
message = t.render(c)
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [supervisee.email])
except:
pass
registration_profile = RegistrationProfile.objects.get(user=supervisee)
supervisee.profile.delete()
supervisee.delete()
supervisiontrack.delete()
registration_profile.delete()
else:
#Reject this account and inform by email the user
now = datetime.datetime.now()
expiration_date_delta = datetime.timedelta(days=settings.ACCOUNT_BLOCKAGE_AFTER_FIRST_REJECTION_DAYS)
supervisiontrack.expiration_date = now
supervisiontrack.is_valid = False
supervisee.profile.status = Profile.REJECTED
supervisee.profile.supervision_key = None
if supervisee.profile.rejection_date == None:
supervisee.profile.rejection_date = now + expiration_date_delta
supervisiontrack.save()
supervisee.profile.save()
supervisee.save()
try:
t = loader.get_template('registration/mail.godfather_rejected.subject.txt')
subject = t.render(c)
# Note: e-mail subject *must not* contain newlines
subject = settings.EMAIL_SUBJECT_PREFIX + ''.join(subject.splitlines())
t = loader.get_template('registration/mail.godfather_rejected.message.txt')
message = t.render(c)
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [supervisee.email])
except:
pass
#New supervision request refused
if supervisiontrack.start_date is None:
supervisiontrack.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
##----------------------------------------------------------
#
#
#class BaseCreateSupervisionTrackViewSupervisee(generics.CreateAPIView):
# model = SupervisionTrack
# serializer_class = SupervisionTrackUpdateSerializer
#
# def get_permissions(self):
# permission_classes = [permissions.IsAuthenticated, IsAuthorAndNotGodfather]
#
# self.permission_classes = permission_classes
#
# return super(BaseCreateSupervisionTrackViewSupervisee, self).get_permissions()
#
#
##----------------------------------------------------------
#
#
#class SuperviseeAddGodfatherView(BaseCreateSupervisionTrackViewSupervisee):
# permission_classes = BaseCreateSupervisionTrackViewSupervisee.permission_classes
#
# def post(self, request, supervisor_name):
# godfather = User.objects.get(username=supervisor_name)
# supervisee = request.user
# print godfather
# print supervisee
# supervisee.profile.supervision_key = supervisee.profile._generate_current_supervision_key()
# #godfather = User.objects.get(username = self.cleaned_data['godfather'])
# supervisiontrack = SupervisionTrack.objects.create(
# supervisee = supervisee,
# godfather = godfather,
# is_valid = False,
# )
#
# #Assign key to supervision track
# supervisiontrack.supervision_key = supervisee.profile.supervision_key
# supervisiontrack.save()
# supervisee.profile.supervision.add(supervisiontrack)
# supervisee.save()
#
# #supervisiontrack = SupervisionTrack.objects.get(godfather=request.user, supervisee=supervisee, supervisee__profile__supervision_key=models.F('supervision_key'))
#
# #from django.core.mail import send_mail
#
# #parsed_url = urlparse(settings.URL_PREFIX)
# #server_address = '%s://%s' % (parsed_url.scheme, parsed_url.hostname)
#
# #c = Context({ 'supervisor': supervisiontrack.godfather,
# # 'supervisee': supervisee,
# # 'prefix': server_address,
# # })
#
# #if supervisee.profile.status == Profile.WAITINGVALIDATION:
# # #New user account waiting validation, so delete this account and inform by email the user
# # try:
# # t = loader.get_template('registration/mail.godfather_rejected.subject.txt')
# # subject = t.render(c)
#
# # # Note: e-mail subject *must not* contain newlines
# # subject = settings.EMAIL_SUBJECT_PREFIX + ''.join(subject.splitlines())
#
# # t = loader.get_template('registration/mail.godfather_rejected_delete_account.message.txt')
# # message = t.render(c)
#
# # send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [supervisee.email])
# # except:
# # pass
#
# # registration_profile = RegistrationProfile.objects.get(user=supervisee)
# # supervisee.profile.delete()
# # supervisee.delete()
# # supervisiontrack.delete()
# # registration_profile.delete()
# #else:
# # #Reject this account and inform by email the user
# # now = datetime.datetime.now()
# # expiration_date_delta = datetime.timedelta(days=settings.ACCOUNT_BLOCKAGE_AFTER_FIRST_REJECTION_DAYS)
#
#
# # supervisiontrack.expiration_date = now
# # supervisiontrack.is_valid = False
#
# # supervisee.profile.status = Profile.REJECTED
# # supervisee.profile.supervision_key = None
# # if supervisee.profile.rejection_date == None:
# # supervisee.profile.rejection_date = now + expiration_date_delta
#
# # supervisiontrack.save()
# # supervisee.profile.save()
# # supervisee.save()
#
# # try:
# # t = loader.get_template('registration/mail.godfather_rejected.subject.txt')
# # subject = t.render(c)
#
# # # Note: e-mail subject *must not* contain newlines
# # subject = settings.EMAIL_SUBJECT_PREFIX + ''.join(subject.splitlines())
#
# # t = loader.get_template('registration/mail.godfather_rejected.message.txt')
# # message = t.render(c)
#
# # send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [supervisee.email])
# # except:
# # pass
#
# # #if supervisiontrack.start_date is None:
# # # supervisiontrack.delete()
#
# return Response(status=status.HTTP_204_NO_CONTENT)
#
#
##----------------------------------------------------------
...@@ -41,4 +41,15 @@ urlpatterns = [ ...@@ -41,4 +41,15 @@ urlpatterns = [
name='validate_supervisee' name='validate_supervisee'
), ),
url(
r'^(?P<supervisee_name>[\w\W]+)/remove/$',
api.GodfatherRemoveSuperviseeView.as_view(),
name='remove_supervisee'
),
url(
r'^(?P<supervisor_name>[\w\W]+)/add/$',
api.SuperviseeAddGodfatherView.as_view(),
name='add_supervisor'
),
] ]
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# encoding: utf-8
###############################################################################
# #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.web module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
from django.core.management.base import BaseCommand, CommandError
from datetime import date
import datetime
from django.contrib.auth.models import User
from django.conf import settings
from ...models import SupervisionTrack
from ...models import Profile
from ....ui.registration.models import RegistrationProfile
import sys
import random
class Command(BaseCommand):
help = 'Block rejected users after rejection date with no valid supervisor'
def add_arguments(self, parser):
parser.add_argument('--noinput', action='store_false', dest='interactive', default=False,
help=('Tells Django to NOT prompt the user for input of any kind.'))
def handle(self, *args, **options):
block = True
if options['interactive']:
try:
answer = self.get_input_data('Block rejected user(s) that have not been validated by a supervisor? (y/n)? ', 'y').lower()
except KeyboardInterrupt:
self.stderr.write("\nOperation canceled.")
sys.exit(1)
if answer != 'y':
self.stdout.write('Block users operation canceled')
sys.exit(1)
if block:
rejected_profiles = Profile.objects.filter(status=Profile.REJECTED)
count = 0
for rejected_profile in rejected_profiles:
user = rejected_profile.user
if user.profile.rejection_date < datetime.datetime.now():
count +=1
user.profile.status = Profile.BLOCKED
user.profile.rejection_date = None
user.is_active = False
if user.profile.supervision_key != None:
supervisiontrack = SupervisionTrack.objects.get(supervision_key=rejected_profile.supervision_key)
if supervisiontrack.is_valid == False and supervisiontrack.start_date is None:
user.profile.supervision_key = None
supervisiontrack.delete()
user.profile.save()
user.save()
self.stdout.write('{} Rejected user(s) successfully blocked/'.format(count) + '{} Total user(s) checked'.format(rejected_profiles.count()))
def get_input_data(self, message, default=None):
"""
Override this method if you want to customize data inputs or
validation exceptions.
"""
raw_value = raw_input(message)
if default and raw_value == '':
raw_value = default
return raw_value
...@@ -95,7 +95,7 @@ class Command(BaseCommand): ...@@ -95,7 +95,7 @@ class Command(BaseCommand):
supervisiontrack.delete() supervisiontrack.delete()
registration_profile.delete() registration_profile.delete()
self.stdout.write('{} Invalid user(s) successfully cleaned/'.format(count) + '{} Total user(s) checked:'.format(invalid_userprofiles_new_users.count()+invalid_userprofiles_waiting_validation.count())) self.stdout.write('{} Invalid user(s) successfully cleaned/'.format(count) + '{} Total user(s) checked'.format(invalid_userprofiles_new_users.count()+invalid_userprofiles_waiting_validation.count()))
def get_input_data(self, message, default=None): def get_input_data(self, message, default=None):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2017-06-26 14:06
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0006_auto_20170608_1451'),
]
operations = [
migrations.AddField(
model_name='profile',
name='first_rejection_date',
field=models.DateTimeField(blank=True, null=True),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2017-06-26 15:16
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_profile_first_rejection_date'),
]
operations = [
migrations.RenameField(
model_name='profile',
old_name='first_rejection_date',
new_name='rejection_date',
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2017-06-27 09:56
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('accounts', '0008_auto_20170626_1516'),
]
operations = [
migrations.AlterField(
model_name='supervisiontrack',
name='supervisee',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisors', to=settings.AUTH_USER_MODEL),
),
]
...@@ -50,7 +50,7 @@ class SupervisionTrack(models.Model): ...@@ -50,7 +50,7 @@ class SupervisionTrack(models.Model):
#_____ Fields __________ #_____ Fields __________
supervisee = models.OneToOneField(User, on_delete=models.CASCADE, supervisee = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='supervisors') related_name='supervisors')
godfather = models.ForeignKey(User, on_delete=models.CASCADE, godfather = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='supervisees') related_name='supervisees')
...@@ -97,6 +97,7 @@ class Profile(models.Model): ...@@ -97,6 +97,7 @@ class Profile(models.Model):
supervision = models.ManyToManyField(SupervisionTrack, related_name='profiles', blank=True) supervision = models.ManyToManyField(SupervisionTrack, related_name='profiles', blank=True)
supervision_key = models.CharField(max_length=40, null=True, blank=True) supervision_key = models.CharField(max_length=40, null=True, blank=True)
registration_date = models.DateTimeField(null=True, blank=True) registration_date = models.DateTimeField(null=True, blank=True)
rejection_date = models.DateTimeField(null=True, blank=True)
def __unicode__(self): def __unicode__(self):
return u'User: %s' % self.user.username return u'User: %s' % self.user.username
......
...@@ -99,6 +99,8 @@ class UserAdmin(UserAdmin): ...@@ -99,6 +99,8 @@ class UserAdmin(UserAdmin):
def supervision_key(self, obj): def supervision_key(self, obj):
return obj.profile.supervision_key return obj.profile.supervision_key
def rejection_date(self, obj):
return obj.profile.rejection_date
list_display = ( list_display = (
...@@ -112,6 +114,7 @@ class UserAdmin(UserAdmin): ...@@ -112,6 +114,7 @@ class UserAdmin(UserAdmin):
'status', 'status',
'supervision', 'supervision',
'supervision_key', 'supervision_key',
'rejection_date',
) )
ordering = ( ordering = (
...@@ -166,6 +169,7 @@ class ProfileAdmin(admin.ModelAdmin): ...@@ -166,6 +169,7 @@ class ProfileAdmin(admin.ModelAdmin):
'registration_date', 'registration_date',
'is_godfather', 'is_godfather',
'supervision_key', 'supervision_key',
'rejection_date',
) )
ordering = ( ordering = (
......
...@@ -218,6 +218,7 @@ DATASETS_ROOT_PATH = None ...@@ -218,6 +218,7 @@ DATASETS_ROOT_PATH = None
ACCOUNT_ACTIVATION_DAYS = 2 ACCOUNT_ACTIVATION_DAYS = 2
ACCOUNT_ACTIVATION_DAYS_FROM_GODFATHER = 7 ACCOUNT_ACTIVATION_DAYS_FROM_GODFATHER = 7
ACCOUNT_EXPIRATION_DAYS = 365 ACCOUNT_EXPIRATION_DAYS = 365
ACCOUNT_BLOCKAGE_AFTER_FIRST_REJECTION_DAYS = 56
LOGIN_REDIRECT_URL = '/' LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/login/' LOGIN_URL = '/login/'
......
Dear {{ supervisee.first_name }},
Your supervision request was not accepted and has been rejected by the supervisor {{ supervisor.username }}.
Either you made a mistake or you are not a supervisee anymore for {{ supervisor.username }}
Your account {{ supervisee.username }} is currently not fully validated.
You can request to validate your account through a new supervision request
either through an existing validated supervisor from the platform or by asking your current supervisor
to register on the platform as a supervisor and when his account is validated,
you can request a supervision from him and get a re-activation of your
account.
Your account will be blocked on {{ supervisee.profile.rejection_date }}. You have until this date to find a
supervisor. Passed this date your account will be blocked and you will need to
proceed with an unblock account request.
Account not confirmed - Supervision Rejected
Dear {{ supervisee.first_name }},
Your supervision request was not accepted and has been rejected by the supervisor {{ supervisor.username }}.
Either you made a mistake or you are not a supervisee of {{ supervisor.username }}
Your newly created account {{ supervisee.username }} has therefore currently been deleted.
You can re-create a new account and make a proper supervision request.
...@@ -55,3 +55,6 @@ class Command(BaseCommand): ...@@ -55,3 +55,6 @@ class Command(BaseCommand):
# Clean and remove invalid users # Clean and remove invalid users
call_command('clean_invalid_users') call_command('clean_invalid_users')
# Block rejected users with no supervision after specific rejection date
call_command('block_rejected_users')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment