# -*- encoding: utf-8 -*- from datetime import date, datetime, timedelta # timeSlices from collections import OrderedDict import csv import django from django.http import HttpResponse, HttpResponseRedirect from django.template import Template, RequestContext, loader from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.urls import reverse from django.views.decorators.csrf import ensure_csrf_cookie from django import forms from django.forms import ModelForm from django.contrib import messages from django.utils.translation import ugettext_lazy as _ from django.utils.translation import pgettext, pgettext_lazy from django.db import transaction from django.db.models import F from django.core.exceptions import ValidationError import logging from django.conf import settings as appSettings from . import models from . import forms from . import auth as nalodeni_auth # Logger instance logger = logging.getLogger(__name__) def role_required(roles=[]): def decorate(func): def call(request, *args, **kwargs): for r in roles: if not r in request.session['site_perms']: messages.error(request, "Nedostatečné oprávnění pro přístup. Detaily byly zaznamenány.") return HttpResponseRedirect('/') result = func(request, *args, **kwargs) return result return call return decorate def get_AppUser_objects(request): ''' Zkontroluje, že všechny objekty v 'objs' vyhovují přiděleným rolím. Nevyhovující vyřadí. ''' sp = request.session['site_perms'] if 'sso_kodo' not in sp: return models.AppUser.objects.none() if 'sso_admin' in sp: return models.AppUser.objects.all() objs = models.AppUser.objects.filter(district__in=request.session['spc']['dist']) return objs def get_AppUser_districts(request): '''Vrátí dostupné kraje podle rolí.''' if 'sso_admin' in request.session['site_perms']: return list(models.AppUser.DISTRICT_CHOICES) rslt = [] for d in models.AppUser.DISTRICT_CHOICES: if d[0] in request.session['spc']['dist']: rslt.append(d) return rslt @ensure_csrf_cookie @login_required(login_url="/prihlaseni") @role_required(['sso_kodo']) def confirmed(request, newOnly=False, dist=None): if dist is None: dist = int(request.POST.get('dist', -1)) doCsvExport = None != request.POST.get('doCsvExport', None) objs = get_AppUser_objects(request).order_by('last_name', 'first_name' ,'email') if newOnly: objs = objs.filter(status=models.AppUser.STATUS_NEW) else: objs = objs.filter(status=models.AppUser.STATUS_REG) districts = [(-1, ' -- vše dostupné -- ')] + get_AppUser_districts(request) # filtrujeme jen povolene kraje, nebo vse pro adminy if dist != -1 and (dist in request.session['spc']['dist'] or 'sso_admin' in request.session['site_perms']): selDist = dist objs = objs.filter(district=selDist) else: selDist = -1 if doCsvExport: response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="nalodeni-kraj-%s-%s.csv"' % (selDist, date.today()) row_headers = [ "ID", "Jméno", "Příjmení", "E-mail registrační", "E-mail kontaktní", "Kraj", "PSČ", "Město", "Druh", "Poznámka", "Stav", "Datum souhlasu o.ú.", "Poznámka dovednosti", ] col_count = len(row_headers) row_nums = {} for abbr, mdl in [ ('IR',models.InterestRegion ), ('US',models.UserSkill ), ('UT',models.UserTopic ), ]: for i in mdl.objects.all(): row_nums[abbr+'_'+str(i.id)] = col_count row_headers.append(i.name) col_count += 1 writer = csv.writer(response) writer.writerow(row_headers) for obj in objs: row = len(row_headers) * [None] row[0] = obj.id row[1] = obj.first_name row[2] = obj.last_name row[3] = obj.email row[4] = obj.email_contact_active row[5] = obj.DISTRICT_CHOICES_STR[obj.district] row[6] = obj.postcode row[7] = obj.city row[8] = obj.KIND_CHOICES_STR[obj.kind] row[9] = obj.interestedIn row[10] = obj.STATUS_CHOICES_STR[obj.status] row[11] = obj.dc_stamp row[12] = obj.userform.skills_note if obj.userform else None if obj.userform: for abbr, mdl in [ ('IR', obj.userform.regions ), ('US', obj.userform.skills ), ('UT', obj.userform.topics ), ]: for i in mdl.all(): row[row_nums[abbr+"_"+str(i.id)]] = "x" writer.writerow(row) return response template = 'people/list.html' context = { 'people' : objs, 'newOnly' : newOnly, 'distAvail' : districts, 'selDist' : selDist, } return render(request, template, context) @ensure_csrf_cookie @login_required(login_url="/prihlaseni") @role_required(['sso_kodo']) def pending(request): ''' List pending registrations from AppRegEmail. ''' show_all = request.GET.get("show_all","no") == "yes" if request.method == "POST": act = request.POST.get("action", None) ids = request.POST.getlist('r[]') objs = models.AppRegEmail.objects.filter(id__in = ids) if act == "token": email_counter = 0 skipped_counter = 0 for o in objs: # kontrola, jestli uživatel již není registrován rslt = models.AppUser.objects.filter(email__iexact=o.email.strip()) if len(rslt) != 0: messages.info(request,'Uživatel s emailem %s již je registrován, požadavek na registaci odstraněn.' % o.email) o.delete() else: if not ( o.etStamp and (datetime.now() - o.etStamp).total_seconds() < int(appSettings.TOKEN_VALID_SEC)): # token not valid or not sent nalodeni_auth.sendRegisterToken(o.email) email_counter += 1 else: skipped_counter += 1 if email_counter > 0: messages.info(request,'Registrační emaily odeslány, celkem odesláno %s zpráv.' % email_counter) if skipped_counter > 0: messages.info(request,'Celkem %s registrací přeskočeno, ještě jsou platné.' % skipped_counter) elif act == "delete": objs.delete() messages.info(request,'Registrace odstraněny.') tokenValidAfter = datetime.now() - timedelta(seconds=int(appSettings.TOKEN_VALID_SEC)) objs = models.AppRegEmail.objects.all() if not show_all: # zobrazovat pouze nové registrace objs = objs.filter(emailToken = None) objs = objs.order_by('etStamp') template = 'people/pending.html' context = { 'people' : objs, 'tokenValidAfter' : tokenValidAfter, 'show_all' : show_all, } return render(request, template, context) @ensure_csrf_cookie @login_required(login_url="/prihlaseni") @role_required(['sso_kodo']) def update(request): ids = request.POST.getlist('r[]') val = request.POST.get('setStatus', None) if val and val in ['reg','new']: objs = get_AppUser_objects(request).filter(id__in=ids) rec = 0 for o in objs: rec += 1 o.status = o.STATUS_REG if val == 'reg' else o.STATUS_NEW o.save() messages.info(request, 'Upraveno celkem %s záznamů.' % rec) if val == 'new': return HttpResponseRedirect('/people/list/') elif val == "reg": return HttpResponseRedirect('/people/list-new/') else: messages.error(request, 'Špatný požadavek.') return HttpResponseRedirect('/people/list/') @login_required(login_url="/prihlaseni") @transaction.atomic @role_required(['sso_kodo']) def person_detail(request, id): obj = models.USER_MODEL.objects.get(pk=id) sp = request.session['site_perms'] sp_sso_kodo = 'sso_kodo' in sp sp_sso_admin = 'sso_admin' in sp # Check permissions to edit this object if not sp_sso_admin and not obj.district in get_AppUser_districts(request): messages.error(request, 'K tomuto záznamu nemáte přístup. ') return redirect('nalodeni:people_list') template = 'person/detail.html' context = { 'obj' : obj, } return render(request, template, context) @login_required(login_url="/prihlaseni") @transaction.atomic @role_required(['sso_kodo']) def person_edit(request, id): obj = models.USER_MODEL.objects.get(pk=id) sp = request.session['site_perms'] sp_sso_kodo = 'sso_kodo' in sp sp_sso_admin = 'sso_admin' in sp # Check permissions to edit this object if not sp_sso_admin and not obj.district in get_AppUser_districts(request): messages.error(request, 'K tomuto záznamu nemáte přístup. ') return redirect('nalodeni:people_list') if obj.ssoUid: _form = forms.AppUserSsoForm else: _form = forms.AppUserForm if request.method == "GET": form = _form(instance=obj) elif request.method == "POST": with obj.audit_context(request.user) as ac: form = _form(request.POST, instance=obj) if form.is_valid(): form.save() messages.info(request, "Údaje byly uloženy.") return redirect('nalodeni:person_detail', form.instance.id) else: messages.error(request, "Opravte prosím chyby v zadání.") raise ac.DataNotSavedException else: form = None template = 'person/edit.html' context = { 'obj' : obj, 'form' : form, 'AUTH_SERVER' : appSettings.AUTH_SERVER, } return render(request, template, context)