digitaleagenturnc/users/views.py

673 lines
24 KiB
Python

from django.shortcuts import render, redirect, reverse
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.decorators import login_required
from django.conf import settings
from .usersforms import UsersAddNewUser, UsersAddProfileForm, UsersChangeProfil, AgencyUpdateForm, UsersPermForm, UserAreaTaskForm, SupportForm
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView, View
from django.contrib import messages
from django.contrib.auth.models import User, Permission
from django.db import models
from .models import Profile, Agency
from django.core.mail import send_mail
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from areas.models import Areas
from tasks.models import Tasks
from quicklinks.models import QuickLinks
from .priomodel import Prio
from standards.models import Standards
from datetime import datetime
from django.utils import formats
from news.models import News
import requests
import json
import random
import string
from PIL import Image
from django.template.loader import render_to_string
from django.contrib.auth.forms import PasswordResetForm
from django.template.loader import render_to_string
from io import StringIO
from users.models import AgencyJob, AgencyGroup
from django.contrib.auth.models import Group
from cloud.models import DataDir
def randomString(stringLength=10):
"""Generate a random string of fixed length """
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
@login_required
def toUpdate(request):
# NO AGENVYJOBS
# CREATE DEFAULT
'''
Agenturleiter
Außendienst
Innendienst
Auszubildender
'''
agencyjobsobject = AgencyJob.objects.filter(agency__pk=request.user.profile.agency.pk)
if(len(agencyjobsobject) == 0):
defaultAgencyJobs = ['Agenturleiter', 'Außendienst', 'Innendienst', 'Auszubildender']
for ele in defaultAgencyJobs:
tempAgencyJob = AgencyJob(name=ele, agency=request.user.profile.agency)
tempAgencyJob.save()
agencygroups = AgencyGroup.objects.filter(agency__pk=request.user.profile.agency.pk)
if(len(agencygroups) == 0):
print("default groups not existing - creating")
# MITARBEITER
letters = string.ascii_lowercase
temgroup_mitarbeiter = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8))
temgroup_mitarbeiter.save()
temgroup_mitarbeiter_ag = AgencyGroup(savefordel=True, group=temgroup_mitarbeiter, agency=request.user.profile.agency, agencygroupname="Mitarbeiter")
temgroup_mitarbeiter_ag.save()
# VERWALTUNG
temgroup_verwaltung = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8))
temgroup_verwaltung.save()
temgroup_verwaltung_ag = AgencyGroup(savefordel=True, is_admin=True, group=temgroup_verwaltung, agency=request.user.profile.agency, agencygroupname="Administratoren")
temgroup_verwaltung_ag.save()
print("default groups created...adding users...")
users_of_agency = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
for user in users_of_agency:
#print(temgroup_verwaltung_ag)
#print(temgroup_verwaltung_ag.group)
temgroup_verwaltung_ag.group.user_set.add(user)
temgroup_mitarbeiter_ag.group.user_set.add(user)
# ADDING ALL RIGHTS TO GROUP "VERWALTUNG"
perms = AgencyGroup._meta.permissions
for p in perms:
tempperm = Permission.objects.get(codename=p[0])
temgroup_verwaltung_ag.group.permissions.add(tempperm)
print("default groups created and users added")
else:
print("default groups existing")
# INITIAL ROOT DIR
rootdir = DataDir.objects.filter(is_root=True, agency__pk=request.user.profile.agency.pk)
if(len(rootdir) == 0):
print("NO MAIN DIR FOUND - CREATE")
rootdir = DataDir(is_root=True, agency=request.user.profile.agency)
rootdir.save()
print("AGENCY ROOT DIR CREATED")
else:
print("MAIN ROOT DIR FOUND - FILESMODULE READY")
# DEF STANDARD DIR
defstandard = DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk)
if(len(defstandard) == 0):
print("NO DEF STANDARD FOUND - CREATE")
rootdir = list(DataDir.objects.filter(is_root=True, agency__pk=request.user.profile.agency.pk))[0]
defstandard = DataDir(is_defaultstandard=True, agency=request.user.profile.agency, name="Standards Uploaddateien", parent_id=rootdir.pk)
defstandard.save()
print("AGENCY DEF STANDARD DIR CREATED")
else:
print("AGENCY DEF STANDARD DIR - FILESMODULE READY")
'''
DASHBOARD-View
View nach erfolgreichem Login Dashboard
Templates: welcomeusers.html und base.html
'''
class AgencyCreateView(CreateView):
model = User
fields = ['first_name', 'last_name','username', 'email']
success_url = '/register/done'
def form_valid(self, form):
# Send message to the site
messages.success(self.request, f'Agentur erstellt! Es wurde eine E-Mail verschickt mit weitere Infos zur Passworterstellung.')
# SAVE OBJECTS TO SIGNALE!
agency = Agency()
agency.name = self.request.POST.get("agency_name")
agency.save()
newuser_name = form.cleaned_data.get('first_name') + ' ' + form.cleaned_data.get('last_name')
form.instance.agency = agency
form.instance.parent = None
msg_html = render_to_string('users/register_mail.html', {'username': newuser_name})
# E-Mail für Passwort-Setzung!
send_mail(
'Agenturanmeldung',
'Hallo ' + form.cleaned_data.get('first_name') + ' ' + form.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://digitale-agentur.com/password-reset/ ein Passwort. Anschließend können Sie weitere Details Ihrer Agentur eingeben.',
'support@digitale-agentur.com',
[form.cleaned_data.get('email')],
html_message=msg_html,
fail_silently=False
)
return super().form_valid(form)
@login_required
def dashboard(request):
# UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA
toUpdate(request)
context = {
'active_link' : 'dashboard'
}
# Adding active_link
# Loading only user same agency
# Change context and return for template-data
# # Get all Users of the Same Agency as logged user
standards_of_agency = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(public=True).order_by('-last_modified_on')[:5]
filterdate = datetime.now()
news = News.objects.filter(agency__pk=request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__gt=filterdate).order_by('-go_online_on')[:4]
context.update({'active_link' : 'dashboard', 'standards_of_agency' : standards_of_agency, 'news' : news})
#return context
return render (request, 'users/dashboard.html', context)
class UsersManagement(LoginRequiredMixin, ListView):
model = User
# Adding active_link
# Loading only user same agency
# Change context and return for template-data
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Get all Users of the Same Agency as logged user
users_of_agency = User.objects.filter(profile__agency__pk=self.request.user.profile.agency.pk).order_by('last_name')
context.update({'active_link' : 'usersmanagement', 'users_of_agency':users_of_agency})
return context
'''
Class AddNewUser()
Erstellt einen neuen Nutzer mit SIGNALS, Profile und Agency (des aktuellen Users mit Rechten)
'''
class UsersCreateUser(LoginRequiredMixin, CreateView):
model = User
fields = ['first_name', 'last_name', 'email']
success_url = '/settings/newuser/s2/'
# Adding active_link
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'settings'})
return context
def form_valid(self, form):
# Send message to the site
messages.success(self.request, f'Neuer Mitarbeiter angelegt!')
# SAVE OBJECTS TO SIGNALE!
form.instance.agency = self.request.user.profile.agency
form.instance.parent = None
newuser_name = form.cleaned_data.get('first_name') + " " + form.cleaned_data.get('last_name')
msg_html = render_to_string('users/newusers_email.html', {'username': newuser_name})
'''
if(self.request.POST.get("sendmailnewuser")):
send_mail(
self.request.user.profile.agency.name + ' Account',
'Hallo ' + form.cleaned_data.get('first_name') + ' ' + form.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://digitale-agentur.com/password-reset/ ein Passwort.',
'support@digitale-agentur.com',
[form.cleaned_data.get('email')],
html_message=msg_html,
fail_silently=False,
)
'''
return super().form_valid(form)
# USER muss eingeloggt sein, um diese Seite zu sehen
@login_required
def profile(request):
if request.method == 'POST':
u_form = UsersChangeProfil(request.POST, instance=request.user)
if u_form.is_valid():
u_form.save()
prename = request.user.first_name
name = request.user.last_name
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
# Daten neu laden und nicht die "Mächten sie die Daten speichern...?"
return redirect('users-dashboard')
else:
# Form in Klammern sind die aktuellen Daten :)
u_form = UsersChangeProfil(instance=request.user)
#p_form = UsersAddProfileForm(instance=request.user.profile)
context = {
'u_form' : u_form,
#'p_form' : p_form,
'active_link' : 'dashboard'
}
return render(request, 'users/profile.html', context)
# Hier andere Nutzer ändern, wenn man Usersmanagement darf!
class UserManagementUpdateForm(LoginRequiredMixin, UpdateView):
model = Profile
labels = {
"phoneland" : "Telefon",
"phonemobile" : "Mobil",
"compfunc" : "Agenturfunktion",
}
fields = ['phoneland','phonemobile','compfunc']
# Update der Zugrifssrechte eines Users
class UsersPermUpdateView(LoginRequiredMixin, View):
template_name = 'users/users_perm.html'
form_class = UsersPermForm
success_url = '/dashboard/usersman/'
# Form wird geladen; Checkboxen werden vorbereitet und hier rausgerendert.
def get(self,request,*args, **kwargs):
# User ist der hier Aufgerufene, bzw. das Profil!
user_tochange = Profile.objects.get(pk=kwargs['pk']).user
return render (request, self.template_name, {'form':self.form_class(user_tochange), 'active_link': 'usersmanagement', 'user_tochange': user_tochange})
# Handle POST GTTP requests
def post(self, request, *args, **kwargs):
permissions_loaded = dict(request.POST.lists())
user_tochange = Profile.objects.get(pk=kwargs['pk']).user
# ITERATION Über alle Elemente gehen und Rechte entziehen (nicht vorhanden) oder adden (wenn vorhanden)
# Hat ein user ein Recht NICHT, ist es NICHT in permissions
# LOAD PERMISSIONS
temprof = Profile
for ele in temprof._meta.permissions:
tempperm = Permission.objects.get(codename=ele[0])
if ele[0] in permissions_loaded:
user_tochange.user_permissions.add(tempperm)
else:
# Eingeloggter User darf sich nicht selbst die Userverwaltungsrechte entziehen
if user_tochange == request.user and ele[0]=='usermanager':
messages.warning(request, f'Benutzerverwaltungsrechte für {user_tochange.first_name} {user_tochange.last_name} kann nicht entfernt werden.')
else:
user_tochange.user_permissions.remove(tempperm)
user_tochange.save()
messages.success(request, f'Berechtigungen für {user_tochange.first_name} {user_tochange.last_name} aktualisiert!')
return HttpResponseRedirect('/dashboard/usersman/')
# Benutzerprofil wird aktualisiert
@login_required
def ProfileUpdateView(request, pk):
prof_user = User.objects.get(profile__pk=pk)
if request.method == 'POST':
profileform_form = UsersAddProfileForm(request.POST, request.FILES, instance=prof_user.profile)
#profileform_parents = UsersAddProfileFormParents(request.POST, instance=request.user)
prename = prof_user.first_name
name = prof_user.last_name
if profileform_form.is_valid():
profileform_form.save()
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
return redirect('users-management')
else:
# Form in Klammern sind die aktuellen Daten :)
profileform_form = UsersAddProfileForm(instance=prof_user.profile)
# Nur User, die im Organigramm auch sichtbar sein, können ausgewählt werden
possible_users = User.objects.filter(profile__agency__pk=prof_user.profile.agency.pk).filter(profile__visible=True)
context = {
'prof_user' : prof_user,
'profileform_form' : profileform_form,
'active_link' : 'usersmanagement',
'possible_users' : possible_users
}
return render(request, 'users/profile_update.html', context)
'''
Set users Parent by AJAX
'''
@login_required
def setuserparent(request):
if request.method == 'GET':
if request.GET['action'] == 'adduserp':
userid = request.GET['objectid']
toadd = request.GET['userid']
toadd_user = User.objects.get(pk=toadd)
workinguser = User.objects.get(pk=userid)
username_clean = toadd_user.first_name + " " + toadd_user.last_name
workinguser.profile.parent = toadd_user
workinguser.save()
# Getting Remaining-Users
possible_users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
possible_users_js = list(possible_users.values())
# Cleaned out, that only data is neede will send to the side (first/last-name and id)
final_possible_users = {}
for ele in possible_users_js:
final_possible_users.update({'first_name':ele['first_name'],'last_name':ele['last_name'],'id':ele['id']})
# Counter for remaining users to show/hide "Keine Mitarbeiter"-Div
return JsonResponse({'userid' : userid, 'username_clean' : username_clean, 'remaining_users':possible_users_js})
else:
return HttpResponse("Request method is not a GET")
'''
# DELETE A USER
Hier wird das Profil gelöscht, aber damit auch der User. Zusätzlich werden
alle Standards, Bereiche und Tasks des zu löschenden Nutzers dem User
zugeschrieben, welcher eingeloggt ist. Das passiert VOR dem löschen!
'''
class ProfileDeleteView(LoginRequiredMixin, DeleteView):
model = User
success_url = '/dasettings/main'
template_name = 'users/user_confirm_delete.html'
def delete(self, request, *args, **kwargs):
user = User.objects.get(pk=kwargs['pk'])
logged_user = request.user
areas_fs = Areas.objects.filter(created_area_by=user)
for a in areas_fs:
a.created_area_by = logged_user
a.save()
# ACHTUNG! Bei Tasks heißt es leider auch created_area...
task_fs = Tasks.objects.filter(created_area_by=user)
for t in task_fs:
t.created_area_by = logged_user
t.save()
standards_fs = Standards.objects.filter(created_standard_by=user)
#print(standards_fs)
for a in standards_fs:
a.created_standard_by = logged_user
a.save()
standards_fs = Standards.objects.filter(last_modified_by=user)
for a in standards_fs:
a.last_modified_by = logged_user
a.save()
standards_fs = Standards.objects.filter(published_by=user)
for a in standards_fs:
a.published_by = logged_user
a.save()
response = super(ProfileDeleteView, self).delete(request, *args, **kwargs)
name = user.first_name + " " + user.last_name
messages.success(request, f'Benutzer ' +name+ ' wurde gelöscht!')
return response
@login_required
def agency(request):
context = {
'active_link' : 'agencyinfo'
}
return render(request, 'users/agency.html', context)
class AgencyUpdateView(LoginRequiredMixin, UpdateView):
model = Agency
form_class = AgencyUpdateForm
template_name = 'users/agency_update.html'
success_url = '/dashboard/agencyinfo'
def get_context_data(self, **kwargs):
context = super(AgencyUpdateView, self).get_context_data(**kwargs)
context['active_link'] = 'agencyinfo'
return context
# PRIORISIERUNG
'''
Es werden alle Aufgabenbereiche den Bereichen der Agentur zugeordnet und ausgegeben.
'''
@login_required
def UsersPrio(request, pk):
user = User.objects.get(pk=pk)
if(user.profile.agency.pk != request.user.profile.agency.pk):
return HttpResponseRedirect('users-dashboard')
else:
prios = Prio.objects.filter(user__pk=pk)
areas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk)
user_first_name = user.first_name
user_last_name = user.last_name
user_id = user.pk
context = {
'active_link' : '',
'areas' : areas,
'user_first_name' : user_first_name,
'user_last_name' : user_last_name,
'user_id' : user_id,
'prios' : prios
}
return render(request, 'users/users_prio.html', context)
'''
Ajax-Call für Prio.Updates seitens des Users
im Profil
'''
@login_required
def UsersPrioUpdate(request):
tempuser = User.objects.get(pk=request.GET['userid'])
if request.method == 'GET' and tempuser.profile.agency.pk == request.user.profile.agency.pk:
prio = Prio.objects.filter(user__pk=request.GET['userid']).filter(task__pk=request.GET['taskid'])
prio = list(prio)[0]
prio.prio = request.GET['value']
prio.save()
return HttpResponse("udated...")
else:
return HttpResponse("Request method is not a GET")
import re
def cleanhtml(raw_html):
cleanr = re.compile('<.*?>')
cleantext = re.sub(cleanr, '', raw_html)
return cleantext
# Searxh for Standards by name, content, creator - standards needs to be public!
@login_required
def GlobalSearch(request):
if request.method == 'GET':
searchfor = request.GET['searchstring']
ag = request.user.profile.agency.pk
res_standard = Standards.objects.filter(agency__pk=ag, public=True).filter(name__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(content__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(area__name__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(task__name__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(created_standard_by__last_name__icontains=searchfor)|Standards.objects.filter(agency__pk=ag, public=True).filter(created_standard_by__first_name__icontains=searchfor)
res_news = News.objects.filter(agency__pk=ag).filter(name__icontains=searchfor) | News.objects.filter(agency__pk=ag).filter(content__icontains=searchfor) | News.objects.filter(agency__pk=ag).filter(created_by__last_name__icontains=searchfor)|News.objects.filter(agency__pk=ag).filter(created_by__first_name__icontains=searchfor)
res_areas = Areas.objects.filter(agency__pk=ag).filter(name__icontains=searchfor)
res_tasks = Tasks.objects.filter(agency__pk=ag).filter(name__icontains=searchfor) |Tasks.objects.filter(agency__pk=ag).filter(area__name__icontains=searchfor)
res_pers = User.objects.filter(profile__agency__pk=ag).filter(first_name__icontains=searchfor) | User.objects.filter(profile__agency__pk=ag).filter(last_name__icontains=searchfor)
links = QuickLinks.objects.filter(agency__pk=ag).filter(name__icontains=searchfor) | QuickLinks.objects.filter(agency__pk=ag).filter(link__icontains=searchfor)
html = render_to_string('users/searchres.html', {'links': links, 'res_standard': res_standard, 'res_areas': res_areas, 'res_tasks': res_tasks, 'res_pers': res_pers, 'res_news' : res_news})
return HttpResponse(html)
else:
return HttpResponse("Request method is not a GET")
@login_required
def searchStandardRouter(request):
if request.method == 'GET':
return redirect('/standards/standard/'+request.GET['s_id']+'/single')
else:
return redirect('dashboard')
'''
Hier werden die Zuständigkeiten eines Benutzers über alle Bereiche/Aufgaben hinweg gesetzt.
Das Update erfolgt per Booleanfields.
'''
@login_required
def UsersAreaTaskUpdate(request, pk):
user = User.objects.get(pk=pk)
if request.user.profile.agency.pk != user.profile.agency.pk:
return redirect('dashboard')
else:
finaldata = {}
context = {
'active_link' : 'usersmanagement',
'user_id' : user.pk,
}
if request.method == 'POST':
form = request.POST
areatask_formdata = list(form)
# CRSF-Token löschen
del areatask_formdata[0]
# Formular übertragen
area_ids = []
task_ids = []
# Areas in Formular laden
for ar in areatask_formdata:
tempdata = ar.split("_")
if(tempdata[0] == 'area'):
area_ids.append(int(tempdata[1]))
elif(tempdata[0] == 'task'):
task_ids.append(int(tempdata[1]))
# Alle Areas und Tasks laden
areas = Areas.objects.filter(agency__pk=user.profile.agency.pk)
tasks = Tasks.objects.filter(agency__pk=user.profile.agency.pk)
# Prüfen, ob der User in Area ist oder nicht und ihn ggf. hinzufügen/entfernen
for area in areas:
if area.pk in area_ids:
area.usersfield.add(user)
else:
area.usersfield.remove(user)
area.save()
'''
Prüfen, ob ein User einem Aufgabenbereich hinzugeprdnet ist.
Ist er im Bereich, passiert nichts. Ist er nicht in diesem
Bereich, wird er dem usersfield der Aufgabe und der Tabelle
Prio hinzugeüfügt. Damit kann der User seine individuellen
Prios im Profil anpassen.
'''
for task in tasks:
if task.pk in task_ids:
prio_check = Prio.objects.filter(user__pk=pk, task=task)
if(len(prio_check) == 0):
prio = Prio(user=User.objects.get(pk=pk), task=task)
prio.save()
task.usersfield.add(user)
else:
task.usersfield.remove(user)
Prio.objects.filter(user__pk=pk).filter(task__pk=task.pk).delete()
task.save()
username_message = user.first_name + " " + user.last_name
messages.success(request, f'Zuständigkeiten für {username_message} aktualisiert!')
return redirect('users-management')
else:
form = UserAreaTaskForm(user)
user_first_name = user.first_name
user_last_name = user.last_name
user_id = user.pk
context = {
'active_link' : '',
'user_first_name' : user_first_name,
'user_last_name' : user_last_name,
'user_id' : user_id,
'form' : form
}
return render(request, 'users/users_areatasks.html', context)
@login_required
def support(request):
context = {
'active_link' : 'support',
'form' : SupportForm(request.user)
}
if request.method == 'POST':
form = request.POST
#image = request.FILES
supportdata = dict(form)
# Data from Form to JSON-Format
name = str(supportdata['name'][0])
mail = str(supportdata['mail'][0])
problemconc = str(supportdata['problemconc'][0])
problem = str(supportdata['problem'][0])
# HEADERS CURL
headers = {'X-API-Key': 'F025A238EB74914E3653BA2989BFF7C4'}
subject = "Digitale Agentur: " + str(problemconc)
#final_img = image['image']
#fi = Image.open(final_img)
#print(fi)
# DataJSON
ostdata = {
"topicId" : '12',
"name": name,
"email": mail,
"subject": 'Digitale Agentur: '+problemconc,
"ip": "1.1.1.1",
"message": "*****************************\nAgentur: "+ request.user.profile.agency.name +" (ID: "+ str(request.user.profile.agency.pk) +")\nBenutzer: "+request.user.first_name+" "+request.user.last_name+" (ID: "+ str(request.user.pk) +")\n*******************************\n\n" + problem
}
json_data = json.dumps(ostdata)
r = requests.post("https://support.vh-solutions.de/api/http.php/tickets.json", data=json_data, headers=headers)
# IF request FAILED error-Message
if(r.status_code != 201):
messages.warning(request, f'Supportanfrage fehlgeschlagen!' + str(r))
else:
messages.success(request, f'Supportanfrage erfolgreich! Ihre Ticketnummer ist '+ str(r.json()) +'!')
return render(request, 'users/support_done.html', context)
else:
return render(request, 'users/support.html', context)
'''
Schickt eine E-Mail an den User inkl. Passwortlink zum zurücksetzen.
'''
def sendpassmail(request):
if(request.method == 'GET'):
userid = request.GET['userid']
tempuser = User.objects.get(pk=userid)
form = PasswordResetForm({'email': tempuser.email})
if form.is_valid():
request.META['SERVER_NAME'] = 'digitale-agentur.com'
request.META['SERVER_PORT'] = '443'
form.save(request= request,use_https=True,from_email="support@digitale-agentur.com",html_email_template_name='users/password_reset_mail.html')
return JsonResponse({'message' : 0})
def datenschutz(request):
if request.user.is_authenticated:
return render(request, 'users/datenschutz.html')
else:
return render(request, 'users/datenschutz_p.html')
def impressum(request):
if request.user.is_authenticated:
return render(request, 'users/impressum.html')
else:
return render(request, 'users/impressum_p.html')