Compare commits
5 Commits
master
...
helpdesk-e
Author | SHA1 | Date |
---|---|---|
Nate Smith | 31ea760f9d | |
Nate Smith | bfbf37fceb | |
Nate Smith | e0caeefce2 | |
Nate Smith | 004353343f | |
Nate Smith | 05d5898fa9 |
|
@ -9,4 +9,4 @@ VENV=/town/venvs/ttadmin
|
|||
source $VENV/bin/activate
|
||||
export DJANGO_SETTINGS_MODULE=settings_live
|
||||
cd $APP_ROOT
|
||||
gunicorn -t120 -b0.0.0.0:$PORT ttadmin.wsgi
|
||||
gunicorn -b0.0.0.0:$PORT ttadmin.wsgi
|
||||
|
|
4
setup.py
4
setup.py
|
@ -15,9 +15,9 @@ setup(
|
|||
'License :: OSI Approved :: Affero GNU General Public License v3 (AGPLv3)',
|
||||
],
|
||||
packages=['ttadmin'],
|
||||
install_requires = ['Django==1.11.29',
|
||||
install_requires = ['Django==1.10.2',
|
||||
'sshpubkeys==2.2.0',
|
||||
'psycopg2-binary==2.8.5',
|
||||
'psycopg2==2.7.6.1',
|
||||
'gunicorn==19.6.0',
|
||||
'Mastodon.py==1.4.5',
|
||||
'tweepy==3.7.0'],
|
||||
|
|
|
@ -20,15 +20,15 @@
|
|||
</head>
|
||||
<body>
|
||||
<h1>tilde.town guestbook</h1>
|
||||
<p><em>don't try to post urls. it won't work.</em></p>
|
||||
<marquee>~*~*~*~*say hello*~*~*~*~</marquee>
|
||||
<form class="tilde" action="{% url 'guestbook:guestbook' %}" method="post">
|
||||
<!-- <form class="tilde" action="{% url 'guestbook:guestbook' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{form.as_table}}
|
||||
</table>
|
||||
<input type="submit" value="sign" >
|
||||
</form>
|
||||
-->
|
||||
|
||||
{% for m in messages %}
|
||||
<p>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import re
|
||||
|
||||
from django.shortcuts import redirect
|
||||
from django.views.generic import TemplateView
|
||||
from django.views.generic.edit import FormView
|
||||
|
@ -7,8 +5,6 @@ from django.views.generic.edit import FormView
|
|||
from .forms import GuestbookForm
|
||||
from .models import GuestbookMessage
|
||||
|
||||
SUSPICIOUS_RE = re.compile(r'https?://')
|
||||
|
||||
|
||||
class GuestbookView(FormView):
|
||||
form_class = GuestbookForm
|
||||
|
@ -21,7 +17,5 @@ class GuestbookView(FormView):
|
|||
|
||||
def form_valid(self, form):
|
||||
del form.cleaned_data['captcha']
|
||||
if SUSPICIOUS_RE.search(form.cleaned_data['msg']) != None:
|
||||
return redirect('guestbook:guestbook')
|
||||
t = GuestbookMessage.objects.create(**form.cleaned_data)
|
||||
return redirect('guestbook:guestbook')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.conf.urls import url
|
||||
from django.contrib import admin
|
||||
from django.forms import ModelForm
|
||||
from .models import Ticket, Note
|
||||
from .models import Ticket, Note, EmailTemplate
|
||||
|
||||
|
||||
class ImmutableNoteInline(admin.TabularInline):
|
||||
|
@ -23,6 +24,11 @@ class NewNoteInline(admin.StackedInline):
|
|||
return queryset.none()
|
||||
|
||||
|
||||
@admin.register(EmailTemplate)
|
||||
class EmailTemplateAdmin(admin.ModelAdmin):
|
||||
fields = ('name', 'body')
|
||||
|
||||
|
||||
@admin.register(Ticket)
|
||||
class TicketAdmin(admin.ModelAdmin):
|
||||
inlines = [ImmutableNoteInline, NewNoteInline]
|
||||
|
@ -31,6 +37,8 @@ class TicketAdmin(admin.ModelAdmin):
|
|||
list_filter = ('issue_status', 'issue_type', 'assigned')
|
||||
fields = ('submitted', 'name', 'email', 'assigned', 'issue_status', 'issue_type', 'issue_text')
|
||||
|
||||
change_form_template = "admin/ticket_with_email.html"
|
||||
|
||||
def save_related(self, request, form, formsets, change):
|
||||
# THIS IS EXTREMELY BOOTLEG AND MAY BREAK IF MORE INLINES ARE ADDED TO THIS ADMIN.
|
||||
for formset in formsets:
|
||||
|
@ -42,3 +50,23 @@ class TicketAdmin(admin.ModelAdmin):
|
|||
note_form.save(commit=False)
|
||||
note_form.save_m2m()
|
||||
return super().save_related(request, form, formsets, change)
|
||||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
if extra_context is None:
|
||||
extra_context = {}
|
||||
extra_context['email_templates'] = EmailTemplate.objects.all()
|
||||
return super().change_view(request, object_id, form_url, extra_context=extra_context)
|
||||
|
||||
def get_urls(self):
|
||||
urls = super().get_urls()
|
||||
custom_urls = [
|
||||
url(r'emails/send$', self.admin_site.admin_view(self.send_email_view)),
|
||||
]
|
||||
return urls + custom_urls
|
||||
|
||||
|
||||
def send_email_view(self, request):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2019-07-20 01:53
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('help', '0008_auto_20190718_2223'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EmailTemplate',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=50)),
|
||||
('body', models.TextField()),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -46,3 +46,11 @@ class Note(Model):
|
|||
|
||||
def __str__(self):
|
||||
return "admin note"
|
||||
|
||||
|
||||
class EmailTemplate(Model):
|
||||
name = CharField(blank=False, null=False, max_length=50)
|
||||
body = TextField(blank=False, null=False)
|
||||
|
||||
def __str__(self):
|
||||
return f"'{self.name}' email template"
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
{% extends 'admin/change_form.html' %}
|
||||
|
||||
{% block after_field_sets %}
|
||||
<h2>Send an email</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<textarea id="send_email_body" rows="20" cols="60"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<h3>Copy a template over?</h3>
|
||||
<table>
|
||||
<!-- loop over email_templates -->
|
||||
{% for tmpl in email_templates %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ tmpl }}
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td><button>copy</button></td>
|
||||
<td>
|
||||
<h4>lost key</h4>
|
||||
<p>Hi!<br>to update your key, please respond to this message with your new pub key.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button>copy</button></td>
|
||||
<td>
|
||||
<h4>delete confirmation</h4>
|
||||
<p>Hi,<br>this email is to confirm you would like your town account deleted. would you
|
||||
like your public html files to remain accessible?</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button>Send!</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
|
@ -2,8 +2,8 @@ from django.conf.urls import url, include
|
|||
from django.contrib import admin
|
||||
|
||||
urlpatterns = [
|
||||
# url(r'^help/', include('help.urls')),
|
||||
url(r'^help/', include('help.urls')),
|
||||
url(r'^users/', include('users.urls')),
|
||||
# url(r'^guestbook/', include('guestbook.urls')),
|
||||
url(r'^guestbook/', include('guestbook.urls')),
|
||||
url(r'^admin/', admin.site.urls),
|
||||
]
|
||||
|
|
|
@ -11,7 +11,7 @@ class PubkeyInline(admin.TabularInline):
|
|||
|
||||
def bulk_accept(madmin, req, qs):
|
||||
for townie in qs:
|
||||
townie.state = Townie.ACCEPTED
|
||||
townie.state = 'accepted'
|
||||
townie.save()
|
||||
post_users_to_social(qs)
|
||||
|
||||
|
@ -19,7 +19,7 @@ bulk_accept.short_description = 'mark selected townies as accepted'
|
|||
|
||||
def bulk_reject(madmin, req, qs):
|
||||
for townie in qs:
|
||||
townie.state = Townie.REJECTED
|
||||
townie.state = 'rejected'
|
||||
townie.save()
|
||||
|
||||
bulk_reject.short_description = 'mark selected townies as rejected'
|
||||
|
|
|
@ -12,9 +12,9 @@ submission_throttle = {}
|
|||
throttle_submission = throttler(submission_throttle)
|
||||
|
||||
|
||||
USERNAME_RE = re.compile(r'^[a-z][a-z0-9_]+$')
|
||||
USERNAME_MIN_LENGTH = 2
|
||||
DISPLAY_NAME_RE = re.compile(r"^[a-zA-Z0-9_\-']+$")
|
||||
USERNAME_RE = re.compile(r'[a-z][a-z0-9_]+')
|
||||
USERNAME_MIN_LENGTH = 3
|
||||
DISPLAY_NAME_RE = re.compile(r"[a-zA-Z0-9_\-']+")
|
||||
DISPLAY_MIN_LENGTH = 2
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ SSH_TYPE_CHOICES = (
|
|||
('ssh-rsa', 'ssh-rsa',),
|
||||
('ssh-dss', 'ssh-dss',),
|
||||
('ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp256'),
|
||||
('ssh-ed25519', 'ssh-ed25519'),
|
||||
)
|
||||
|
||||
DEFAULT_INDEX_PATH = '/etc/skel/public_html/index.html'
|
||||
|
@ -79,13 +78,6 @@ class Townie(User):
|
|||
def home(self):
|
||||
return os.path.join('/home', self.username)
|
||||
|
||||
def generate_gift(self):
|
||||
command = '/town/bin/generate_welcome_present.sh'
|
||||
error = _guarded_run(['sudo', command, self.username])
|
||||
if error:
|
||||
logger.error(error)
|
||||
return
|
||||
|
||||
def send_welcome_email(self):
|
||||
welcome_tmpl = get_template('users/welcome_email.txt')
|
||||
context = {
|
||||
|
@ -254,15 +246,9 @@ def on_townie_pre_save(sender, instance, **kwargs):
|
|||
# See if we need to create the user on disk.
|
||||
if existing.unreviewed and instance.accepted:
|
||||
logger.info('Creating user {} on disk.'.format(instance.username))
|
||||
try:
|
||||
instance.create_on_disk()
|
||||
instance.write_authorized_keys()
|
||||
except Exception as e:
|
||||
logger.error('Failed syncing user {} to disk: {}'.format(instance.username, e))
|
||||
else:
|
||||
instance.send_welcome_email()
|
||||
instance.generate_gift()
|
||||
|
||||
instance.create_on_disk()
|
||||
instance.send_welcome_email()
|
||||
instance.write_authorized_keys()
|
||||
return
|
||||
else:
|
||||
# This user state transition is currently undefined. In the future, we can check for things
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<li><a href="https://tilde.town/~kc/blackout/">black out</a></li>
|
||||
<li><a href="https://tilde.town/~subtransience/machinecode/index.html">the machine room</a></li>
|
||||
</ul>
|
||||
<h2>or a <a href="https://cgi.tilde.town/users/random">random page</a></h2>
|
||||
<h2>or a <a href="https://tilde.town/cgi/random">random page</a></h2>
|
||||
</td>
|
||||
<td style="padding:1em">
|
||||
<a href="http://giphy.com/gifs/cyndipop-golden-girls-bea-arthur-ToMjGpK80QLT7KLWPLO">
|
||||
|
|
|
@ -12,17 +12,10 @@ from django.views.generic.edit import FormView
|
|||
from .forms import TownieForm
|
||||
from .models import Townie, Pubkey
|
||||
|
||||
SIGNUPS_ENABLED = True
|
||||
|
||||
class SignupView(FormView):
|
||||
form_class = TownieForm
|
||||
template_name = 'users/signup.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['signups_enabled'] = SIGNUPS_ENABLED
|
||||
return ctx
|
||||
|
||||
extra_context = {"signups_enabled": False}
|
||||
|
||||
@transaction.atomic
|
||||
def form_valid(self, form):
|
||||
|
|
Loading…
Reference in New Issue