diff --git a/beat/web/accounts/management/commands/year_revalidation_users.py b/beat/web/accounts/management/commands/year_revalidation_users.py new file mode 100644 index 0000000000000000000000000000000000000000..b00a3669cea53b8cc3f62f814925bbdec04a8848 --- /dev/null +++ b/beat/web/accounts/management/commands/year_revalidation_users.py @@ -0,0 +1,158 @@ +#!/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.db.models import Q +from django.contrib.auth.models import User +from django.conf import settings +from django.core.mail import send_mail +from django.template import loader +from django.template import Context + +from ...models import SupervisionTrack +from ...models import Profile +from ....ui.registration.models import RegistrationProfile + +import sys +import random +from urlparse import urlparse + +class Command(BaseCommand): + + help = 'Check users for yearly revalidation' + + 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): + yearrevalidate = True + + if options['interactive']: + try: + answer = self.get_input_data('Check user(s) for yearly revalidation by a supervisor? (y/n)? ', 'y').lower() + except KeyboardInterrupt: + self.stderr.write("\nOperation canceled.") + sys.exit(1) + + if answer != 'y': + self.stdout.write('Check users yearly revalidation operation canceled') + sys.exit(1) + + if yearrevalidate: + torevalidate_profiles = Profile.objects.filter(Q(status=Profile.ACCEPTED)|Q(status=Profile.YEARREVALIDATION)) + + now = datetime.datetime.now() + blocked_count = 0 + warned_count = 0 + + for torevalidate_profile in torevalidate_profiles: + user = torevalidate_profile.user + if user.profile.is_godfather == False: + #Not godfather + if user.profile.supervision_key != None: + supervisiontrack = SupervisionTrack.objects.get(supervision_key=torevalidate_profile.supervision_key) + if supervisiontrack.is_valid: + #Check expiration date + expiration_date_delta = datetime.timedelta(days=settings.ACCOUNT_BLOCKAGE_AFTER_FIRST_REJECTION_DAYS) + if supervisiontrack.expiration_date < now + expiration_date_delta: + #check if need to block account + if now > supervisiontrack.expiration_date: + blocked_count += 1 + #terminate supervision + supervisiontrack.expiration_date = now + supervisiontrack.is_valid = False + + #block user + user.profile.status = Profile.BLOCKED + user.profile.rejection_date = None + user.profile.supervision_key = None + user.is_active = False + + #save all changes + supervisiontrack.save() + user.profile.save() + user.save() + else: + #send the warning information + #set user to YEARREVALIDATION + if user.profile.status == Profile.ACCEPTED: + user.profile.status = Profile.YEARREVALIDATION + user.profile.save() + #send email to user + for expiration_reminder in settings.EXPIRATION_REMINDERS_REVALIDATION: + if supervisiontrack.expiration_date.date() - now.date() == datetime.timedelta(days=expiration_reminder): + warned_count += 1 + + parsed_url = urlparse(settings.URL_PREFIX) + server_address = '%s://%s' % (parsed_url.scheme, parsed_url.hostname) + + c = Context({ 'user': user, + 'expiration_date': supervisiontrack.expiration_date.date(), + }) + + try: + t = loader.get_template('registration/mail.account_revalidation.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.account_revalidation.message.txt') + message = t.render(c) + + send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [supervisiontrack.supervisee.email]) + except: + pass + + + else: + #Is godfather + #TODO implement this procedure + pass + + self.stdout.write('{} blocked user(s) and '.format(blocked_count)+'{} warned user(s)/'.format(warned_count) + '{} Total user(s) that need revalidation'.format(torevalidate_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 diff --git a/beat/web/settings/settings.py b/beat/web/settings/settings.py index 6dfc77da8b6eb3201c3e78a663e68b1a2c721096..61ec9923e3be878a19d47649852d11bc6190fe0d 100755 --- a/beat/web/settings/settings.py +++ b/beat/web/settings/settings.py @@ -471,6 +471,7 @@ REST_FRAMEWORK = { #In days EXPIRATION_DELTA = 180 EXPIRATION_REMINDERS = [1, 7, 30] +EXPIRATION_REMINDERS_REVALIDATION = [1, 7, 30, 50] ############################################################################## # diff --git a/beat/web/ui/registration/templates/registration/mail.account_revalidation.message.txt b/beat/web/ui/registration/templates/registration/mail.account_revalidation.message.txt new file mode 100644 index 0000000000000000000000000000000000000000..28ee5f959c56b4a244c2d946fa4f0a66cf825e41 --- /dev/null +++ b/beat/web/ui/registration/templates/registration/mail.account_revalidation.message.txt @@ -0,0 +1,13 @@ +Dear {{ user.first_name }}, + +Your need to re-confirm that you still use your account on the BEAT Platform. +This check is done on a yearly basis. + +This can be done by going to your profile and making a revalidation request by +clicking on the corresponding button. + +If you haven't done this by this expiration date: {{ expiration_date }}, your account +will be blocked and you will then need to go trough an unblock account +procedure to re-activate it. + +BEAT Administrators at the Idiap Research Institute diff --git a/beat/web/ui/registration/templates/registration/mail.account_revalidation.subject.txt b/beat/web/ui/registration/templates/registration/mail.account_revalidation.subject.txt new file mode 100644 index 0000000000000000000000000000000000000000..1de7fbb2d93421d8508fa45aeb420ab044bb6c40 --- /dev/null +++ b/beat/web/ui/registration/templates/registration/mail.account_revalidation.subject.txt @@ -0,0 +1 @@ +Account re-validation - Required Confirmation diff --git a/beat/web/utils/management/commands/daily_cron_actions.py b/beat/web/utils/management/commands/daily_cron_actions.py index dcbcf13a5e81bd6283ad1ec7c87cc96e7b245d4c..88d08e1d02d394fa5375779154846e5a71215a6d 100644 --- a/beat/web/utils/management/commands/daily_cron_actions.py +++ b/beat/web/utils/management/commands/daily_cron_actions.py @@ -61,3 +61,6 @@ class Command(BaseCommand): # Clean blocked users with no supervision after specific rejection date call_command('clean_blocked_users_expired_requests') + + # Yearly revalidation process with warnings, status change and blockage + call_command('year_revalidation_users')