Browse Source

REGISTRATION_OPEN setting. superuser accounts by default have team access enabled. Fixes #97 and #113

pull/117/head
Pēteris Caune 8 years ago
parent
commit
965accaedb
9 changed files with 58 additions and 14 deletions
  1. +9
    -0
      README.md
  2. +1
    -6
      hc/accounts/middleware.py
  3. +11
    -0
      hc/accounts/models.py
  4. +9
    -0
      hc/accounts/tests/test_login.py
  5. +14
    -7
      hc/accounts/views.py
  6. +7
    -0
      hc/front/tests/test_basics.py
  7. +2
    -1
      hc/front/views.py
  8. +1
    -0
      hc/settings.py
  9. +4
    -0
      templates/front/welcome.html

+ 9
- 0
README.md View File

@ -87,6 +87,15 @@ Example:
SITE_NAME = "My Monitoring Project" SITE_NAME = "My Monitoring Project"
`REGISTRATION_OPEN` controls whether site visitors can create new accounts.
Set it to `False` if you are setting up a private healthchecks instance, but
it needs to be publicly accessible (so, for example, your cloud services
can send pings).
If you close new user registration, you can still selectively invite users
to your team account.
## Database Configuration ## Database Configuration
Database configuration is stored in `hc/settings.py` and can be overriden Database configuration is stored in `hc/settings.py` and can be overriden


+ 1
- 6
hc/accounts/middleware.py View File

@ -11,12 +11,7 @@ class TeamAccessMiddleware(object):
teams_q = teams_q.select_related("user") teams_q = teams_q.select_related("user")
request.teams = list(teams_q) request.teams = list(teams_q)
try:
profile = request.user.profile
except Profile.DoesNotExist:
profile = Profile(user=request.user)
profile.save()
profile = Profile.objects.for_user(request.user)
if profile.current_team: if profile.current_team:
request.team = profile.current_team request.team = profile.current_team
else: else:


+ 11
- 0
hc/accounts/models.py View File

@ -13,6 +13,15 @@ from django.utils import timezone
from hc.lib import emails from hc.lib import emails
class ProfileManager(models.Manager):
def for_user(self, user):
profile = self.filter(user=user).first()
if profile is None:
profile = Profile(user=user, team_access_allowed=user.is_superuser)
profile.save()
return profile
class Profile(models.Model): class Profile(models.Model):
# Owner: # Owner:
user = models.OneToOneField(User, blank=True, null=True) user = models.OneToOneField(User, blank=True, null=True)
@ -25,6 +34,8 @@ class Profile(models.Model):
api_key = models.CharField(max_length=128, blank=True) api_key = models.CharField(max_length=128, blank=True)
current_team = models.ForeignKey("self", null=True) current_team = models.ForeignKey("self", null=True)
objects = ProfileManager()
def __str__(self): def __str__(self):
return self.team_name or self.user.email return self.team_name or self.user.email


+ 9
- 0
hc/accounts/tests/test_login.py View File

@ -1,6 +1,7 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core import mail from django.core import mail
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from hc.api.models import Check from hc.api.models import Check
from django.conf import settings from django.conf import settings
@ -57,3 +58,11 @@ class LoginTestCase(TestCase):
self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox), 1)
subject = "Log in to %s" % settings.SITE_NAME subject = "Log in to %s" % settings.SITE_NAME
self.assertEqual(mail.outbox[0].subject, subject) self.assertEqual(mail.outbox[0].subject, subject)
@override_settings(REGISTRATION_OPEN=False)
def test_it_obeys_registration_open(self):
form = {"email": "[email protected]"}
r = self.client.post("/accounts/login/", form)
assert r.status_code == 200
self.assertContains(r, "Incorrect email")

+ 14
- 7
hc/accounts/views.py View File

@ -1,6 +1,7 @@
import uuid import uuid
import re import re
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import login as auth_login from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout from django.contrib.auth import logout as auth_logout
@ -25,8 +26,8 @@ def _make_user(email):
user.set_unusable_password() user.set_unusable_password()
user.save() user.save()
profile = Profile(user=user)
profile.save()
# Ensure a profile gets created
Profile.objects.for_user(user)
channel = Channel() channel = Channel()
channel.user = user channel.user = user
@ -74,14 +75,20 @@ def login(request, show_password=False):
bad_credentials = True bad_credentials = True
show_password = True show_password = True
else: else:
user = None
try: try:
user = User.objects.get(email=email) user = User.objects.get(email=email)
except User.DoesNotExist: except User.DoesNotExist:
user = _make_user(email)
_associate_demo_check(request, user)
user.profile.send_instant_login_link()
return redirect("hc-login-link-sent")
if settings.REGISTRATION_OPEN:
user = _make_user(email)
_associate_demo_check(request, user)
else:
bad_credentials = True
if user:
profile = Profile.objects.for_user(user)
profile.send_instant_login_link()
return redirect("hc-login-link-sent")
else: else:
form = EmailPasswordForm() form = EmailPasswordForm()


+ 7
- 0
hc/front/tests/test_basics.py View File

@ -1,4 +1,5 @@
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from hc.api.models import Check from hc.api.models import Check
@ -20,3 +21,9 @@ class BasicsTestCase(TestCase):
assert r.status_code == 200 assert r.status_code == 200
assert code != "x" assert code != "x"
assert Check.objects.filter(code=code).exists() assert Check.objects.filter(code=code).exists()
@override_settings(REGISTRATION_OPEN=False)
def test_it_obeys_registration_open(self):
r = self.client.get("/")
self.assertNotContains(r, "Get Started")

+ 2
- 1
hc/front/views.py View File

@ -93,7 +93,8 @@ def index(request):
"ping_url": check.url(), "ping_url": check.url(),
"enable_pushbullet": settings.PUSHBULLET_CLIENT_ID is not None, "enable_pushbullet": settings.PUSHBULLET_CLIENT_ID is not None,
"enable_pushover": settings.PUSHOVER_API_TOKEN is not None, "enable_pushover": settings.PUSHOVER_API_TOKEN is not None,
"enable_discord": settings.DISCORD_CLIENT_ID is not None
"enable_discord": settings.DISCORD_CLIENT_ID is not None,
"registration_open": settings.REGISTRATION_OPEN
} }
return render(request, "front/welcome.html", ctx) return render(request, "front/welcome.html", ctx)


+ 1
- 0
hc/settings.py View File

@ -21,6 +21,7 @@ DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = []
DEFAULT_FROM_EMAIL = '[email protected]' DEFAULT_FROM_EMAIL = '[email protected]'
USE_PAYMENTS = False USE_PAYMENTS = False
REGISTRATION_OPEN = True
INSTALLED_APPS = ( INSTALLED_APPS = (


+ 4
- 0
templates/front/welcome.html View File

@ -95,6 +95,7 @@
</div> </div>
</div> </div>
{% if registration_open %}
<div class="get-started-bleed"> <div class="get-started-bleed">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@ -126,6 +127,7 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %}
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@ -308,6 +310,7 @@
<div class="row"> <div class="row">
{% if registration_open %}
<div class="footer-jumbo-bleed"> <div class="footer-jumbo-bleed">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="jumbotron"> <div class="jumbotron">
@ -348,6 +351,7 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %}
</div> </div>


Loading…
Cancel
Save