Skip to content

Commit

Permalink
Improve type hints in hc.accounts.views
Browse files Browse the repository at this point in the history
  • Loading branch information
cuu508 committed Sep 6, 2023
1 parent 0c83ca4 commit 65b3acf
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 58 deletions.
15 changes: 11 additions & 4 deletions hc/accounts/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,34 @@

import secrets
from functools import wraps
from typing import TYPE_CHECKING, Any

from django.core.signing import SignatureExpired, TimestampSigner
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect, render

from hc.api.models import TokenBucket
from hc.lib import emails

if TYPE_CHECKING:
from typing import Callable

def _session_unsign(request, key, max_age):
ViewFunc = Callable[..., HttpResponse]


def _session_unsign(request: HttpRequest, key: str, max_age: int) -> str | None:
if key not in request.session:
return None

try:
return TimestampSigner().unsign(request.session[key], max_age=max_age)
except SignatureExpired:
pass
return None


def require_sudo_mode(f):
def require_sudo_mode(f: ViewFunc) -> ViewFunc:
@wraps(f)
def wrapper(request, *args, **kwds):
def wrapper(request: HttpRequest, *args: Any, **kwds: Any) -> HttpResponse:
assert request.user.is_authenticated

# is sudo mode active and has not expired yet?
Expand Down
23 changes: 13 additions & 10 deletions hc/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import random
import sys
import uuid
from datetime import datetime
from datetime import timedelta as td
from secrets import token_urlsafe
from urllib.parse import quote, urlencode
Expand All @@ -12,7 +13,7 @@
from django.contrib.auth.models import User
from django.core.signing import BadSignature, TimestampSigner
from django.db import models
from django.db.models import Q
from django.db.models import Q, QuerySet
from django.db.models.functions import Lower
from django.urls import reverse
from django.utils.timezone import now
Expand Down Expand Up @@ -126,7 +127,9 @@ def check_token(self, token):

return "login" in self.token and check_password(token, self.token)

def send_instant_login_link(self, membership=None, redirect_url=None):
def send_instant_login_link(
self, membership: "Member" | None = None, redirect_url: str | None = None
) -> None:
token = self.prepare_token()
path = reverse("hc-check-token", args=[self.user.username, token])
if redirect_url:
Expand All @@ -139,7 +142,7 @@ def send_instant_login_link(self, membership=None, redirect_url=None):
}
emails.login(self.user.email, ctx)

def send_change_email_link(self, new_email):
def send_change_email_link(self, new_email: str) -> None:
payload = {
"u": self.user.username,
"t": self.prepare_token(),
Expand All @@ -154,7 +157,7 @@ def send_change_email_link(self, new_email):
}
emails.login(new_email, ctx)

def send_transfer_request(self, project):
def send_transfer_request(self, project: "Project") -> None:
token = self.prepare_token()
settings_path = reverse("hc-project-settings", args=[project.code])
path = reverse("hc-check-token", args=[self.user.username, token])
Expand Down Expand Up @@ -310,7 +313,7 @@ def num_checks_used(self) -> int:
def num_checks_available(self) -> int:
return self.check_limit - self.num_checks_used()

def can_accept(self, project) -> bool:
def can_accept(self, project: "Project") -> bool:
return project.num_checks() <= self.num_checks_available()

def update_next_nag_date(self) -> None:
Expand All @@ -322,7 +325,7 @@ def update_next_nag_date(self) -> None:
self.next_nag_date = None
self.save(update_fields=["next_nag_date"])

def choose_next_report_date(self):
def choose_next_report_date(self) -> datetime:
"""Calculate the target date for the next monthly/weekly report.
Monthly reports should get sent on 1st of each month, between
Expand Down Expand Up @@ -381,7 +384,7 @@ def num_checks(self) -> int:
def num_checks_available(self) -> int:
return self.owner_profile.num_checks_available()

def invite_suggestions(self):
def invite_suggestions(self) -> QuerySet[User]:
q = User.objects.filter(memberships__project__owner_id=self.owner_id)
q = q.exclude(memberships__project=self)
return q.distinct().order_by("email")
Expand All @@ -391,7 +394,7 @@ def can_invite_new_users(self) -> bool:
used = q.distinct().count()
return used < self.owner_profile.team_limit

def invite(self, user, role):
def invite(self, user: User, role: str) -> bool:
if Member.objects.filter(user=user, project=self).exists():
return False

Expand Down Expand Up @@ -433,7 +436,7 @@ def have_channel_issues(self) -> bool:
# It's a problem if any integration has a logged error
return True if max(errors) else False

def transfer_request(self):
def transfer_request(self) -> "Member" | None:
return self.member_set.filter(transfer_request_date__isnull=False).first()

def dashboard_url(self):
Expand Down Expand Up @@ -469,7 +472,7 @@ class Meta:
)
]

def can_accept(self):
def can_accept(self) -> bool:
return self.user.profile.can_accept(self.project)

@property
Expand Down
Loading

0 comments on commit 65b3acf

Please sign in to comment.