add method for generate new password to students

feature/fix_generate_pass
Dmitriy Shesterkin 8 years ago
parent 6ca8139a68
commit b92e6d0435
  1. 26
      access/serializers.py
  2. 7
      access/urls.py
  3. 39
      access/views.py
  4. 2
      api_v1/urls.py
  5. 10
      lms/settings.py
  6. 3
      pytest.ini
  7. 2
      requirements.txt
  8. 28
      tests/conftest.py
  9. 0
      tests/fixtures/__init__.py
  10. 24
      tests/fixtures/users.py
  11. 42
      tests/test_user.py

@ -1,5 +1,6 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework.generics import get_object_or_404
from access.models.other import Account
from achievements.serialers import DiplomaSerializer, AchievementsSerializer
@ -101,3 +102,28 @@ class UserSearchSerializer(serializers.ModelSerializer):
@staticmethod
def get_last_request(self):
return self.useractivity.last_request
class UserEmailSerializer(serializers.Serializer):
"""
Serializer for set new password to the student in admin area by manager.
"""
email = serializers.EmailField()
def __init__(self, *args, **kwargs):
super(UserEmailSerializer, self).__init__(*args, **kwargs)
self.user = None
self.password = None
def validate_email(self, email):
self.user = get_object_or_404(get_user_model(), email=email)
if not self.user.is_active:
raise serializers.ValidationError('Учетная запись еще не активирована.')
if not self.user:
raise serializers.ValidationError('Email не зарегистрирован.')
return email
def save(self):
self.password = get_user_model().objects.make_random_password()
self.user.set_password(self.password)
self.user.save()

@ -18,4 +18,9 @@ urlpatterns = [
url(r'logout/$', views.LogoutView.as_view()),
url(r'reset/$', views.ResetPasswordView.as_view()),
url(r'progress_detail/upload/(?P<token>[0-9A-Fa-f-]+)/$', progress.views.UploadCourseProgressUserView.as_view()),
]
url(
r'management/password/$',
views.ManagementPassword.as_view(),
name='management-password'
)
]

@ -1,6 +1,7 @@
import datetime
import random
import string
import logging
from django.contrib import auth
from django.conf import settings
@ -8,15 +9,21 @@ from django.contrib.auth import get_user_model
from django.core.mail import send_mail
from django.db.models import Q
from django.shortcuts import redirect
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import permissions, generics, status
from access.models.other import Invite, ResetPassword, Account
from access.serializers import UserSelfSerializer, UserSearchSerializer
from access.serializers import (UserSelfSerializer, UserSearchSerializer,
UserEmailSerializer)
from lms.tools import decode_base64
logger = logging.getLogger(__name__)
class TeacherListView(APIView):
renderer_classes = (JSONRenderer,)
status_code = 200
@ -283,3 +290,33 @@ class MinUserView(APIView):
return Response(UserSearchSerializer(get_user_model().objects.get(out_key=out_key)).data, status=200)
except get_user_model().DoesNotExist:
return Response("User not found", status=404)
class ManagementPassword(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
serializer_class = UserEmailSerializer
def post(self, request):
"""
Set password to the student in admin area by manager
---
Generate new password to the student and send email with new password
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
logger.info(f'set password: {serializer.password} to the '
f'student with email: {serializer.user.email}')
send_mail(
subject='Установлен новый пароль',
message=f'Ваш новый пароль {serializer.password} '
f'(в последствии вы сможите сменить его в личном кабинете).',
from_email='robo@skillbox.ru',
recipient_list=[serializer.user.email],
)
logger.info(f'send email to {serializer.user.email} '
f'with new password')
return Response(
data={'message': 'Письмо с новым паролем отправлено на email студента.'},
status=status.HTTP_201_CREATED
)

@ -5,7 +5,7 @@ schema_view = get_swagger_view(title='Skillbox LMS API')
urlpatterns = [
url(r'courses/', include('courses.urls')),
url(r'users/', include('access.urls')),
url(r'users/', include('access.urls', namespace='users')),
url(r'library/', include('library.urls')),
url(r'finance/', include('finance.urls')),
url(r'storage/', include('storage.urls')),

@ -232,6 +232,16 @@ LOGGING = {
},
}
# Configure loggers for all local apps
LOCAL_APPS_LOGGERS = {}
for app in apps:
LOCAL_APPS_LOGGERS[app] = {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
}
LOGGING['loggers'].update(LOCAL_APPS_LOGGERS)
SWAGGER_SETTINGS = {
'USE_SESSION_AUTH': True,
'LOGIN_URL': 'admin:login',

@ -2,7 +2,8 @@
DJANGO_SETTINGS_MODULE = lms.settings
norecursedirs = env/* docs/* misc/* static/*
addopts = --flake8 -vvs
;addopts = --flake8 -vvs
addopts = -vvs
python_files =
test_*.py

@ -50,6 +50,8 @@ pytest-sugar==0.9.1
pytest-django==3.1.2
coverage==4.5.1
pytest-cov==2.5.1
mock==2.0.0
pytest-mock==1.7.0
# factories
Faker==0.8.11
factory-boy==2.10.0

@ -0,0 +1,28 @@
import pytest
from tests.client import BetterAPIClient
pytest_plugins = [
'tests.fixtures.users',
]
@pytest.fixture
def api_client():
"""Anonymous client for REST API."""
client = BetterAPIClient()
return client
@pytest.fixture
def staff_client(user_staff):
"""Authorized as staff client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=user_staff)
return client
@pytest.fixture
def student_client(user_student):
"""Authorized as staff client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=user_student)
return client

@ -4,11 +4,12 @@ from factories.users import UserFactory
@pytest.fixture
def user_admin():
def user_staff():
"""
Create user as administration with data:
Create user as staff with data:
email = 'admin@example.com'
password = 'test'
is_staff=True
is_active = True
is_superuser = True
"""
@ -16,7 +17,26 @@ def user_admin():
last_name='Иванов',
first_name='Иван',
email='admin@example.com',
is_staff=True,
is_active=True,
is_superuser=True
)
return admin
@pytest.fixture
def user_student():
"""
Create user as student with data:
email = 'student@example.com'
password = 'test'
is_active = True
"""
student = UserFactory(
last_name='Иванов',
first_name='Иван',
email='student@example.com',
is_staff=False,
is_active=True,
)
return student

@ -0,0 +1,42 @@
import mock
import pytest
from django.contrib.auth import get_user_model
from django.urls import reverse
from rest_framework import status
from rest_framework.generics import get_object_or_404
@pytest.mark.django_db
@mock.patch('django.core.mail.send_mail')
def test_generate_password_by_manager(mocked_send_mail, staff_client,
student_client, user_student):
"""
Test generate new password from admin area by manager
"""
assert staff_client.get(
reverse('users:management-password'),
status=status.HTTP_405_METHOD_NOT_ALLOWED
)
assert student_client.get(
reverse('users:management-password'),
status=status.HTTP_403_FORBIDDEN
)
data = {
'email': user_student.email,
}
assert staff_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_201_CREATED
)
test_user = get_object_or_404(get_user_model(), email=user_student.email)
assert not test_user.check_password('test')
assert mocked_send_mail.call_count == 1
assert student_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_403_FORBIDDEN
)
Loading…
Cancel
Save