# Path: account/models.py
# class PasswordExpiry(models.Model):
#     """
#     Holds the password expiration period for a single user.
#     """
#     user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name="password_expiry", verbose_name=_("user"), on_delete=models.CASCADE)
#     expiry = models.PositiveIntegerField(default=0)
# 
# class PasswordHistory(models.Model):
#     """
#     Contains single password history for user.
#     """
#     class Meta:
#         verbose_name = _("password history")
#         verbose_name_plural = _("password histories")
# 
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="password_history", on_delete=models.CASCADE)
#     password = models.CharField(max_length=255)  # encrypted password
#     timestamp = models.DateTimeField(default=timezone.now)  # password creation time
# 
# Path: account/utils.py
# def check_password_expired(user):
#     """
#     Return True if password is expired and system is using
#     password expiration, False otherwise.
#     """
#     if not settings.ACCOUNT_PASSWORD_USE_HISTORY:
#         return False
# 
#     if hasattr(user, "password_expiry"):
#         # user-specific value
#         expiry = user.password_expiry.expiry
#     else:
#         # use global value
#         expiry = settings.ACCOUNT_PASSWORD_EXPIRY
# 
#     if expiry == 0:  # zero indicates no expiration
#         return False
# 
#     try:
#         # get latest password info
#         latest = user.password_history.latest("timestamp")
#     except PasswordHistory.DoesNotExist:
#         return False
# 
#     now = datetime.datetime.now(tz=pytz.UTC)
#     expiration = latest.timestamp + datetime.timedelta(seconds=expiry)
# 
#     if expiration < now:
#         return True
#     else:
#         return False


import datetime
import django
import pytz
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import User
from django.test import TestCase, modify_settings, override_settings
from django.urls import reverse
from ..models import PasswordExpiry, PasswordHistory
from ..utils import check_password_expired
        url_name = "account_settings"
        response = self.client.get(reverse(url_name))

        # verify desired page is set as "?next=" in redirect URL
        redirect_url = "{}?next={}".format(reverse("account_password"), url_name)
        self.assertRedirects(response, redirect_url)

    def test_password_expiration_reset(self):
        """
        Ensure changing password results in new PasswordHistory.
        """
        history_count = self.user.password_history.count()

        # get login
        self.client.login(username=self.username, password=self.password)

        # post new password to reset PasswordHistory
        new_password = "lynyrdskynyrd"
        post_data = {
            "password_current": self.password,
            "password_new": new_password,
            "password_new_confirm": new_password,
        }
        self.client.post(
            reverse("account_password"),
            post_data
        )
        # Should see one more history entry for this user
        self.assertEquals(self.user.password_history.count(), history_count + 1)


# Path: account/models.py
# class PasswordExpiry(models.Model):
#     """
#     Holds the password expiration period for a single user.
#     """
#     user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name="password_expiry", verbose_name=_("user"), on_delete=models.CASCADE)
#     expiry = models.PositiveIntegerField(default=0)
# 
# class PasswordHistory(models.Model):
#     """
#     Contains single password history for user.
#     """
#     class Meta:
#         verbose_name = _("password history")
#         verbose_name_plural = _("password histories")
# 
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="password_history", on_delete=models.CASCADE)
#     password = models.CharField(max_length=255)  # encrypted password
#     timestamp = models.DateTimeField(default=timezone.now)  # password creation time
# 
# Path: account/utils.py
# def check_password_expired(user):
#     """
#     Return True if password is expired and system is using
#     password expiration, False otherwise.
#     """
#     if not settings.ACCOUNT_PASSWORD_USE_HISTORY:
#         return False
# 
#     if hasattr(user, "password_expiry"):
#         # user-specific value
#         expiry = user.password_expiry.expiry
#     else:
#         # use global value
#         expiry = settings.ACCOUNT_PASSWORD_EXPIRY
# 
#     if expiry == 0:  # zero indicates no expiration
#         return False
# 
#     try:
#         # get latest password info
#         latest = user.password_history.latest("timestamp")
#     except PasswordHistory.DoesNotExist:
#         return False
# 
#     now = datetime.datetime.now(tz=pytz.UTC)
#     expiration = latest.timestamp + datetime.timedelta(seconds=expiry)
# 
#     if expiration < now:
#         return True
#     else:
#         return False


# Path: account/tests/test_password.py
import datetime
import django
import pytz
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.models import User
from django.test import TestCase, modify_settings, override_settings
from django.urls import reverse
from ..models import PasswordExpiry, PasswordHistory
from ..utils import check_password_expired

        url_name = "account_settings"
        response = self.client.get(reverse(url_name))

        # verify desired page is set as "?next=" in redirect URL
        redirect_url = "{}?next={}".format(reverse("account_password"), url_name)
        self.assertRedirects(response, redirect_url)

    def test_password_expiration_reset(self):
        """
        Ensure changing password results in new PasswordHistory.
        """
        history_count = self.user.password_history.count()

        # get login
        self.client.login(username=self.username, password=self.password)

        # post new password to reset PasswordHistory
        new_password = "lynyrdskynyrd"
        post_data = {
            "password_current": self.password,
            "password_new": new_password,
            "password_new_confirm": new_password,
        }
        self.client.post(
            reverse("account_password"),
            post_data
        )
        # Should see one more history entry for this user
        self.assertEquals(self.user.password_history.count(), history_count + 1)


        latest = PasswordHistory.objects.latest("timestamp")