Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions accounts/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def apply_change_password(sender, **kwargs):
Depending on settings SHOW_PROFILE_EDIT_PASSWORD
'''
from django.conf import settings
from django.contrib.auth.models import User, Permission
from django.contrib.auth.models import Permission, User
if hasattr(settings, 'SHOW_PROFILE_EDIT_PASSWORD'):
print('\033[1m! \033[92mSHOW_PROFILE_EDIT_PASSWORD is found inside settings.py\033[0m')
print('\033[1m* \033[92mApplying permission can_change_password for all users\033[0m')
Expand All @@ -29,8 +29,8 @@ def create_admin(sender, **kwargs):
'''
Create initial admin user
'''
from django.contrib.auth.models import User
from accounts.models import UserAttributes
from django.contrib.auth.models import User

plan = kwargs.get('plan', [])
for migration, rolled_back in plan:
Expand Down
5 changes: 2 additions & 3 deletions accounts/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Generated by Django 2.2.10 on 2020-01-28 07:01

from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):
Expand Down
3 changes: 2 additions & 1 deletion accounts/templatetags/tags_fingerprint.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django import template
import base64
import hashlib

from django import template

register = template.Library()


Expand Down
16 changes: 8 additions & 8 deletions accounts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,27 @@ def validate_ssh_key(key):
return False
# unpack the contents of data, from data[:4] , property of ssh key .
try:
str_len = struct.unpack('>I', data[:4])[0]
str_len = struct.unpack(">I", data[:4])[0]
except struct.error:
return False
# data[4:str_len] must have string which matches with the typeofkey, another ssh key property.
if data[4:4 + str_len] == typeofkey:
if data[4 : 4 + str_len] == typeofkey:
return True
else:
else:
return False


def send_email_with_otp(user, device):
send_mail(
_('OTP QR Code'),
_('Please view HTML version of this message.'),
_("OTP QR Code"),
_("Please view HTML version of this message."),
None,
[user.email],
html_message=render_to_string(
'accounts/email/otp.html',
"accounts/email/otp.html",
{
'totp_url': device.config_url,
'user': user,
"totp_url": device.config_url,
"user": user,
},
),
fail_silently=False,
Expand Down
97 changes: 58 additions & 39 deletions accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,52 @@ def profile(request):

if profile_form.is_valid():
profile_form.save()
messages.success(request, _('Profile updated'))
return redirect('accounts:profile')
messages.success(request, _("Profile updated"))
return redirect("accounts:profile")

return render(request, "profile.html", {
'publickeys': publickeys,
'profile_form': profile_form,
'ssh_key_form': ssh_key_form,
})
return render(
request,
"profile.html",
{
"publickeys": publickeys,
"profile_form": profile_form,
"ssh_key_form": ssh_key_form,
},
)


def ssh_key_create(request):
key_form = UserSSHKeyForm(request.POST or None, user=request.user)
if key_form.is_valid():
key_form.save()
messages.success(request, _('SSH key added'))
return redirect('accounts:profile')
messages.success(request, _("SSH key added"))
return redirect("accounts:profile")

return render(request, 'common/form.html', {
'form': key_form,
'title': _('Add SSH key'),
})
return render(
request,
"common/form.html",
{
"form": key_form,
"title": _("Add SSH key"),
},
)


def ssh_key_delete(request, pk):
ssh_key = get_object_or_404(UserSSHKey, pk=pk, user=request.user)
if request.method == 'POST':
if request.method == "POST":
ssh_key.delete()
messages.success(request, _('SSH key deleted'))
return redirect('accounts:profile')
messages.success(request, _("SSH key deleted"))
return redirect("accounts:profile")

return render(request, 'common/confirm_delete.html', {
'object': ssh_key,
'title': _('Delete SSH key'),
})
return render(
request,
"common/confirm_delete.html",
{
"object": ssh_key,
"title": _("Delete SSH key"),
},
)


@superuser_only
Expand All @@ -67,13 +79,16 @@ def account(request, user_id):
publickeys = UserSSHKey.objects.filter(user_id=user_id)

return render(
request, "account.html", {
'user': user,
'user_insts': user_insts,
'instances': instances,
'publickeys': publickeys,
'otp_enabled': settings.OTP_ENABLED,
})
request,
"account.html",
{
"user": user,
"user_insts": user_insts,
"instances": instances,
"publickeys": publickeys,
"otp_enabled": settings.OTP_ENABLED,
},
)


@permission_required("accounts.change_password", raise_exception=True)
Expand Down Expand Up @@ -118,7 +133,7 @@ def user_instance_update(request, pk):

return render(
request,
'common/form.html',
"common/form.html",
{
"form": form,
"title": _("Update User Instance"),
Expand Down Expand Up @@ -150,29 +165,33 @@ def email_otp(request):
if form.is_valid():
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=form.cleaned_data['email'])
user = UserModel.objects.get(email=form.cleaned_data["email"])
except UserModel.DoesNotExist:
pass
else:
device = get_user_totp_device(user)
send_email_with_otp(user, device)

messages.success(request, _('OTP Sent to %s') % form.cleaned_data['email'])
return redirect('accounts:login')
messages.success(request, _("OTP Sent to %(email)s") % {"email": form.cleaned_data["email"]})
return redirect("accounts:login")

return render(request, 'accounts/email_otp_form.html', {
'form': form,
'title': _('Email OTP'),
})
return render(
request,
"accounts/email_otp_form.html",
{
"form": form,
"title": _("Email OTP"),
},
)


@superuser_only
def admin_email_otp(request, user_id):
user = get_object_or_404(get_user_model(), pk=user_id)
device = get_user_totp_device(user)
if user.email != '':
if user.email != "":
send_email_with_otp(user, device)
messages.success(request, _('OTP QR code was emailed to user %s') % user)
messages.success(request, _("OTP QR code was emailed to user %(user)s") % {"user": user})
else:
messages.error(request, _('User email not set, failed to send QR code'))
return redirect('accounts:account', user.id)
messages.error(request, _("User email not set, failed to send QR code"))
return redirect("accounts:account", user.id)
76 changes: 42 additions & 34 deletions admin/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django import forms
from django.contrib.auth.models import Group, User
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.models import Group, User
from django.urls import reverse_lazy
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
Expand All @@ -13,7 +13,7 @@
class GroupForm(forms.ModelForm):
permissions = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Permission.objects.filter(content_type__model='permissionset'),
queryset=Permission.objects.filter(content_type__model="permissionset"),
required=False,
)

Expand All @@ -25,12 +25,12 @@ class GroupForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
super(GroupForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
instance = getattr(self, "instance", None)
if instance and instance.id:
self.fields['users'].initial = self.instance.user_set.all()
self.fields["users"].initial = self.instance.user_set.all()

def save_m2m(self):
self.instance.user_set.set(self.cleaned_data['users'])
self.instance.user_set.set(self.cleaned_data["users"])

def save(self, *args, **kwargs):
instance = super(GroupForm, self).save()
Expand All @@ -39,49 +39,57 @@ def save(self, *args, **kwargs):

class Meta:
model = Group
fields = '__all__'
fields = "__all__"


class UserForm(forms.ModelForm):
user_permissions = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Permission.objects.filter(content_type__model='permissionset'),
label=_('Permissions'),
queryset=Permission.objects.filter(content_type__model="permissionset"),
label=_("Permissions"),
required=False,
)

groups = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Group.objects.all(),
label=_('Groups'),
label=_("Groups"),
required=False,
)

class Meta:
model = User
fields = [
'username',
'groups',
'first_name',
'last_name',
'email',
'user_permissions',
'is_staff',
'is_active',
'is_superuser',
"username",
"groups",
"first_name",
"last_name",
"email",
"user_permissions",
"is_staff",
"is_active",
"is_superuser",
]

def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
if self.instance.id:
password = ReadOnlyPasswordHashField(
label=_("Password"),
help_text=format_lazy(_("""Raw passwords are not stored, so there is no way to see
this user's password, but you can change the password using <a href='{}'>this form</a>."""),
reverse_lazy('admin:user_update_password',
args=[self.instance.id,]))
help_text=format_lazy(
_(
"""Raw passwords are not stored, so there is no way to see this user's password,
but you can change the password using <a href='{}'>this form</a>."""
),
reverse_lazy(
"admin:user_update_password",
args=[
self.instance.id,
],
),
),
)
self.fields['Password'] = password
self.fields["Password"] = password


class UserCreateForm(UserForm):
Expand All @@ -90,20 +98,20 @@ class UserCreateForm(UserForm):
class Meta:
model = User
fields = [
'username',
'password',
'groups',
'first_name',
'last_name',
'email',
'user_permissions',
'is_staff',
'is_active',
'is_superuser',
"username",
"password",
"groups",
"first_name",
"last_name",
"email",
"user_permissions",
"is_staff",
"is_active",
"is_superuser",
]


class UserAttributesForm(forms.ModelForm):
class Meta:
model = UserAttributes
exclude = ['user', 'can_clone_instances']
exclude = ["user", "can_clone_instances"]
Loading