summaryrefslogtreecommitdiffstats
path: root/users/views
diff options
context:
space:
mode:
Diffstat (limited to 'users/views')
-rw-r--r--users/views/__init__.py1
-rw-r--r--users/views/auth.py15
-rw-r--r--users/views/identity.py132
3 files changed, 148 insertions, 0 deletions
diff --git a/users/views/__init__.py b/users/views/__init__.py
new file mode 100644
index 0000000..1e88b4e
--- /dev/null
+++ b/users/views/__init__.py
@@ -0,0 +1 @@
+from .auth import * # noqa
diff --git a/users/views/auth.py b/users/views/auth.py
new file mode 100644
index 0000000..f9e6ce1
--- /dev/null
+++ b/users/views/auth.py
@@ -0,0 +1,15 @@
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth.views import LoginView, LogoutView
+
+from core.forms import FormHelper
+
+
+class Login(LoginView):
+ class form_class(AuthenticationForm):
+ helper = FormHelper(submit_text="Login")
+
+ template_name = "auth/login.html"
+
+
+class Logout(LogoutView):
+ pass
diff --git a/users/views/identity.py b/users/views/identity.py
new file mode 100644
index 0000000..63b7fb8
--- /dev/null
+++ b/users/views/identity.py
@@ -0,0 +1,132 @@
+from django import forms
+from django.conf import settings
+from django.contrib.auth.decorators import login_required
+from django.http import Http404, JsonResponse
+from django.shortcuts import redirect
+from django.utils.decorators import method_decorator
+from django.views.generic import FormView, TemplateView, View
+
+from core.forms import FormHelper
+from users.models import Identity
+from users.shortcuts import by_handle_or_404
+
+
+class ViewIdentity(TemplateView):
+
+ template_name = "identity/view.html"
+
+ def get_context_data(self, handle):
+ identity = by_handle_or_404(self.request, handle, local=False)
+ statuses = identity.statuses.all()[:100]
+ return {
+ "identity": identity,
+ "statuses": statuses,
+ }
+
+
+@method_decorator(login_required, name="dispatch")
+class SelectIdentity(TemplateView):
+
+ template_name = "identity/select.html"
+
+ def get_context_data(self):
+ return {
+ "identities": Identity.objects.filter(users__pk=self.request.user.pk),
+ }
+
+
+@method_decorator(login_required, name="dispatch")
+class CreateIdentity(FormView):
+
+ template_name = "identity/create.html"
+
+ class form_class(forms.Form):
+ handle = forms.CharField()
+ name = forms.CharField()
+
+ helper = FormHelper(submit_text="Create")
+
+ def clean_handle(self):
+ # Remove any leading @
+ value = self.cleaned_data["handle"].lstrip("@")
+ # Don't allow custom domains here quite yet
+ if "@" in value:
+ raise forms.ValidationError(
+ "You are not allowed an @ sign in your handle"
+ )
+ # Ensure there is a domain on the end
+ if "@" not in value:
+ value += "@" + settings.DEFAULT_DOMAIN
+ # Check for existing users
+ if Identity.objects.filter(handle=value).exists():
+ raise forms.ValidationError("This handle is already taken")
+ return value
+
+ def form_valid(self, form):
+ new_identity = Identity.objects.create(
+ handle=form.cleaned_data["handle"],
+ name=form.cleaned_data["name"],
+ local=True,
+ )
+ new_identity.users.add(self.request.user)
+ new_identity.generate_keypair()
+ return redirect(new_identity.urls.view)
+
+
+class Actor(View):
+ """
+ Returns the AP Actor object
+ """
+
+ def get(self, request, handle):
+ identity = by_handle_or_404(self.request, handle)
+ return JsonResponse(
+ {
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ ],
+ "id": f"https://{settings.DEFAULT_DOMAIN}{identity.urls.actor}",
+ "type": "Person",
+ "preferredUsername": "alice",
+ "inbox": f"https://{settings.DEFAULT_DOMAIN}{identity.urls.inbox}",
+ "publicKey": {
+ "id": f"https://{settings.DEFAULT_DOMAIN}{identity.urls.actor}#main-key",
+ "owner": f"https://{settings.DEFAULT_DOMAIN}{identity.urls.actor}",
+ "publicKeyPem": identity.public_key,
+ },
+ }
+ )
+
+
+class Webfinger(View):
+ """
+ Services webfinger requests
+ """
+
+ def get(self, request):
+ resource = request.GET.get("resource")
+ if not resource.startswith("acct:"):
+ raise Http404("Not an account resource")
+ handle = resource[5:]
+ identity = by_handle_or_404(request, handle)
+ return JsonResponse(
+ {
+ "subject": f"acct:{identity.handle}",
+ "aliases": [
+ f"https://{settings.DEFAULT_DOMAIN}/@{identity.short_handle}",
+ ],
+ "links": [
+ {
+ "rel": "http://webfinger.net/rel/profile-page",
+ "type": "text/html",
+ "href": f"https://{settings.DEFAULT_DOMAIN}{identity.urls.view}",
+ },
+ {
+ "rel": "self",
+ "type": "application/activity+json",
+ "href": f"https://{settings.DEFAULT_DOMAIN}{identity.urls.actor}",
+ },
+ ],
+ }
+ )