Skip to content

Commit

Permalink
Merge 1223ea5 into bc0ed5f
Browse files Browse the repository at this point in the history
  • Loading branch information
atodorov committed Dec 20, 2020
2 parents bc0ed5f + 1223ea5 commit 8d65351
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 2 deletions.
24 changes: 24 additions & 0 deletions tcms_tenants/forms.py
Expand Up @@ -37,3 +37,27 @@ class NewTenantForm(forms.Form): # pylint: disable=must-inherit-from-model-form
widget=forms.HiddenInput)
organization = forms.CharField(max_length=64, required=False,
widget=forms.HiddenInput)


class InviteUsersForm(forms.Form): # pylint: disable=must-inherit-from-model-form
number_of_fields = 10

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

for i in self.range:
self.fields["email_%d" % i] = forms.CharField(required=False)

def clean(self):
emails = set()

for i in self.range:
email = self.cleaned_data["email_%d" % i]
if email:
emails.add(email)

self.cleaned_data["emails"] = emails

@property
def range(self):
return range(self.number_of_fields)
1 change: 1 addition & 0 deletions tcms_tenants/menu.py
Expand Up @@ -11,6 +11,7 @@
(_('Tenant'), [
(_('Create'), reverse_lazy('tcms_tenants:create-tenant')),
('-', '-'),
(_('Invite users'), reverse_lazy('tcms_tenants:invite-users')),
(_('Authorized users'), '/admin/tcms_tenants/tenant_authorized_users/'),
]),
]
27 changes: 27 additions & 0 deletions tcms_tenants/templates/tcms_tenants/invite_users.html
@@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load i18n %}
{% load static %}

{% block head %}
{{ form.media }}
{% endblock %}
{% block title %}
{% trans "Invite users" %}
{% endblock %}


{% block contents %}
<div class="container-fluid container-cards-pf">
<form class="form-horizontal" action="{% url 'tcms_tenants:invite-users' %}" method="post">
{% for i in form.range %}
<div class="form-group">
<label class="col-md-1 col-lg-1" for="email_{{ i }}">{% trans "Email" %}</label>
<div class="col-sm-4 col-md-4 col-lg-4">
<input type="text" id="email_{{ i }}" name="email_{{ i }}" class="form-control">
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-default btn-lg">{% trans "Save" %}</button>
</form>
</div>
{% endblock %}
1 change: 1 addition & 0 deletions tcms_tenants/urls.py
Expand Up @@ -9,6 +9,7 @@

urlpatterns = [
re_path(r'^create/$', views.NewTenantView.as_view(), name='create-tenant'),
re_path(r'^invite/$', views.InviteUsers.as_view(), name='invite-users'),
re_path(r'^go/to/(?P<tenant>\w+)/(?P<path>.*)$',
views.RedirectTo.as_view(), name='redirect-to'),
]
50 changes: 49 additions & 1 deletion tcms_tenants/utils.py
Expand Up @@ -3,6 +3,7 @@
# Licensed under the GPL 3.0: https://www.gnu.org/licenses/gpl-3.0.txt

import datetime
import uuid

from django.conf import settings
from django.contrib.sites.models import Site
Expand All @@ -13,10 +14,14 @@

from django_tenants.utils import schema_context, tenant_context
from tcms.core.utils.mailto import mailto
from tcms.kiwi_auth.forms import RegistrationForm

from tcms_tenants.models import Domain, Tenant


UserModel = get_user_model()


def can_access(user, tenant):
# everybody can access the public schema
if tenant.schema_name == 'public':
Expand Down Expand Up @@ -115,7 +120,7 @@ class FakeRequest: # pylint: disable=too-few-public-methods,nested-class-found
user = None

def __init__(self, username):
self.user = get_user_model().objects.get(username=username)
self.user = UserModel.objects.get(username=username)

data = {
'name': name,
Expand All @@ -128,3 +133,46 @@ def __init__(self, username):
request = FakeRequest(owner)

return create_tenant(data, request)


def create_user_account(email_address):
desired_username = username = email_address.split("@")[0]
password = uuid.uuid4().hex

i = 1
while UserModel.objects.filter(username=username).exists():
username = "%s.%d" % (desired_username, i)
i += 1

# =====> how to deal with captcha
form = RegistrationForm(data={
"username": username,
"password1": password,
"password2": password,
"email": email_address,
})

user = form.save()

# activate their account instead of sending them email with actiovation key
user.is_active = True
user.save()

return user


def invite_users(tenant, email_addresses):
for email in email_addresses:
# note: users are on public_schema
user = UserModel.objects.filter(email=email).first()

# email not found, need to create account for them
if not user:
user = create_user_account(email)

# user already authorized for tenant
if tenant.authorized_users.filter(pk=user.pk).exists():
continue

tenant.authorized_users.add(user)
# =====> send them email
16 changes: 15 additions & 1 deletion tcms_tenants/views.py
Expand Up @@ -11,7 +11,7 @@
from django.contrib.auth.decorators import permission_required

from tcms_tenants import utils
from tcms_tenants.forms import NewTenantForm, VALIDATION_RE
from tcms_tenants.forms import InviteUsersForm, NewTenantForm, VALIDATION_RE


@method_decorator(permission_required('tcms_tenants.add_tenant'), name='dispatch')
Expand Down Expand Up @@ -66,3 +66,17 @@ def get_redirect_url(self, *args, **kwargs):
tenant = kwargs['tenant']
path = kwargs['path']
return '%s/%s' % (utils.tenant_url(self.request, tenant), path)


@method_decorator(permission_required('tcms_tenants.change_tenant'), name='dispatch')
class InviteUsers(FormView):
"""
Invite users to tenant via email.
"""
form_class = InviteUsersForm
template_name = "tcms_tenants/invite_users.html"

def form_valid(self, form):
utils.invite_users(self.request.tenant, form.cleaned_data["emails"])

return HttpResponseRedirect('/')

0 comments on commit 8d65351

Please sign in to comment.