Coverage for src/django_resume/tokens.py: 49%

1 import random

2 import string

3 from datetime import datetime

4

5 from django import forms

6 from django.urls import reverse

7 from django.utils import timezone

8 from django.utils.safestring import mark_safe

9

10 from .plugins import ListPlugin, ListItemFormMixin

11

12

13 def generate_random_string(length=20):

14 return "".join(random.choices(string.ascii_letters + string.digits, k=length))

15

16

17 class HTMLLinkWidget(forms.Widget):

18 def render(self, name, value, attrs=None, renderer=None):

19 return mark_safe(value) if value else ""

20

21

22 class TokenItemForm(ListItemFormMixin, forms.Form):

23 token = forms.CharField(max_length=255, required=True, label="Token")

24 receiver = forms.CharField(max_length=255)

25 created = forms.DateTimeField(widget=forms.HiddenInput(), required=False)

26 cv_link = forms.CharField(required=False, label="CV Link", widget=HTMLLinkWidget())

27

28 def __init__(self, *args, **kwargs):

29 super().__init__(*args, **kwargs)

30

31 if not self.initial.get("token"):

32 self.fields["token"].initial = generate_random_string()

33 self.token = self.initial.get("token") or self.fields["token"].initial

34

35 if "created" in self.initial and isinstance(self.initial["created"], str):

36 self.initial["created"] = datetime.fromisoformat(self.initial["created"])

37 else:

38 # Set the 'created' field to the current time if it's not already set

39 self.fields["created"].initial = timezone.now()

40

41 self.generate_cv_link(self.person)

42

43 def generate_cv_link(self, person):

44 base_url = reverse("django_resume:cv", kwargs={"slug": person.slug})

45 link = f"{base_url}?token={self.token}"

46 self.fields["cv_link"].initial = mark_safe(

47 f'<a href="{link}" target="_blank">{link}</a>'

48 )

49

50 def clean_token(self):

51 token = self.cleaned_data["token"]

52 if not token:

53 raise forms.ValidationError("Token required.")

54 return token

55

56 def clean_created(self):

57 created = self.cleaned_data["created"]

58 return created.isoformat()

59

60 def clean(self):

61 cleaned_data = super().clean()

62 cleaned_data.pop("cv_link", None) # Remove 'cv_link' from cleaned_data

63 return cleaned_data

64

65

66 class TokenForm(forms.Form):

67 token_required = forms.BooleanField(required=False, label="Token Required")

68

69

70 class TokenPlugin(ListPlugin):

71 """

72 Generate tokens for a person.

73

74 If you want to restrict access to a person's resume, you can generate a token.

75 The token can be shared with the person and they can access their resume using the token.

76 """

77

78 name = "token"

79 verbose_name = "CV Token"

80 flat_template = "django_resume/plain/token_flat.html"

81 flat_form_template = "django_resume/plain/token_flat_form.html"

82

83 def get_admin_item_form(self):

84 return TokenItemForm

85

86 def get_admin_form(self):

87 return TokenForm

88

89 def get_context(self, plugin_data, _person_pk, *, context):

90 print("token_data: ", plugin_data)

91 return {}