Merge pull request #5 from nathanielksmith/master

welcome emails and other user improvements
pull/16/head
Nathaniel Smith 2017-01-25 19:55:01 -08:00 committed by GitHub
commit 9f9d84c548
6 changed files with 90 additions and 18 deletions

View File

@ -17,6 +17,7 @@ setup(
packages=['ttadmin'], packages=['ttadmin'],
install_requires = ['Django==1.10.2', install_requires = ['Django==1.10.2',
'sshpubkeys==2.2.0', 'sshpubkeys==2.2.0',
'psycopg2==2.6.2',], 'psycopg2==2.6.2',
'requests==2.12.5'],
include_package_data = True, include_package_data = True,
) )

View File

@ -0,0 +1,32 @@
import logging
import requests
from django.conf import settings
logger = logging.getLogger()
FROM='root@tilde.town'
def send_email(to, body, subject='a message from tilde.town', frum=FROM,):
"""Sends an email using mailgun. Logs on failure."""
response = requests.post(
settings.MAILGUN_URL,
auth=('api', settings.MAILGUN_KEY),
data={
'from': frum,
'to': to,
'subject': subject,
'text': body
}
)
success = response.status_code == 200
if not success:
logger.error('{}: failed to send email "{}" to {}'.format(
response.status_code,
subject,
to))
return success

View File

@ -6,6 +6,7 @@ To run this For Real, you'll want to:
* set a different SECRET_KEY * set a different SECRET_KEY
* change the password for the database or delete the password and use ident * change the password for the database or delete the password and use ident
* change DEBUG to False * change DEBUG to False
* set mailgun api info
""" """
import os import os
@ -99,3 +100,6 @@ STATIC_URL = '/static/'
# Not used during local development, but used in staging+live environments # Not used during local development, but used in staging+live environments
STATIC_ROOT = 'static' STATIC_ROOT = 'static'
MAILGUN_URL = "OVERWRITE THIS"
MAILGUN_KEY = "OVERWRITE THIS"

View File

@ -9,9 +9,20 @@ admin.site.unregister(Group)
class PubkeyInline(admin.TabularInline): class PubkeyInline(admin.TabularInline):
model = Pubkey model = Pubkey
extra = 1
def bulk_review(madmin, req, qs):
for townie in qs:
townie.reviewed = True
townie.save()
bulk_review.short_description = 'mark selected townies as reviewed'
@admin.register(Townie) @admin.register(Townie)
class TownieAdmin(admin.ModelAdmin): class TownieAdmin(admin.ModelAdmin):
inlines = [PubkeyInline] inlines = [PubkeyInline]
list_display = ('reviewed', 'username', 'email') list_display = ('username', 'reviewed', 'email')
ordering = ('reviewed',) ordering = ('reviewed',)
exclude = ('first_name', 'last_name', 'password', 'groups', 'user_permissions', 'last_login')
actions = (bulk_review,)
search_fields = ('username', 'email', 'displayname')

View File

@ -1,11 +1,14 @@
import re import re
from django.db.models import Model from django.db.models import Model
from django.db.models.signals import post_save from django.db.models.signals import pre_save
from django.dispatch import receiver from django.dispatch import receiver
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models import TextField, BooleanField, CharField, ForeignKey from django.db.models import TextField, BooleanField, CharField, ForeignKey
from django.template.loader import get_template
from common.mailing import send_email
from help.models import Ticket
SSH_TYPE_CHOICES = ( SSH_TYPE_CHOICES = (
('ssh-rsa', 'ssh-rsa',), ('ssh-rsa', 'ssh-rsa',),
@ -24,14 +27,22 @@ class Townie(User):
reasons = TextField(blank=True, null=False, default='') reasons = TextField(blank=True, null=False, default='')
displayname = CharField(max_length=100, blank=False, null=False) displayname = CharField(max_length=100, blank=False, null=False)
# TODO consider a generic ensure method that syncs this model with the def send_welcome_email(self, admin_name='vilmibm'):
# system. there will likely be things besides shell that we want to keep welcome_tmpl = get_template('users/welcome_email.txt')
# track of in the DB. context = {
def ensure_shell(self): 'username': self.username,
"""Runs chsh for the user to set their shell to whatever self.shell 'admin_name': admin_name,
is.""" }
raise NotImplementedError() text = welcome_tmpl.render(context)
from_address = '{}@tilde.town'.format(admin_name)
success = send_email(self.email, text, subject='tilde.town!', frum=from_address)
if not success:
Ticket.objects.create(name='system',
email='root@tilde.town',
issue_type='other',
issue_text='was not able to send welcome email to {} ({})'.format(
self.username,
self.email))
class Pubkey(Model): class Pubkey(Model):
key_type = CharField(max_length=50, key_type = CharField(max_length=50,
@ -43,11 +54,11 @@ class Pubkey(Model):
townie = ForeignKey(Townie) townie = ForeignKey(Townie)
@receiver(post_save, sender=Townie) @receiver(pre_save, sender=Townie)
def sync_system_state(sender, instance, created, **kwargs): def on_townie_pre_save(sender, instance, **kwargs):
if created: existing = Townie.objects.filter(username=instance.username)
print('TODO would create new user on system') if not existing: # we're making a new user
else:
print('TODO would update existing user on system')
return return
if not existing[0].reviewed and instance.reviewed == True:
instance.send_welcome_email()

View File

@ -0,0 +1,13 @@
Welcome to tilde.town, ~{{username}}!
Please take a moment to review our code of conduct: https://tilde.town/~wiki/conduct.html
and login with:
ssh -i /path/to/private/key {{username}}@tilde.town
File a help ticket if you have problems logging in (or other issues): https://cgi.tilde.town/help/tickets
See you on the server!!
~{{admin_name}}