Compare commits

...

22 Commits

Author SHA1 Message Date
e1b84f5182 FIX: Bloody smartquotes 2020-03-07 15:43:33 +00:00
7773bf96c8 Better fix for previous commit 2020-03-07 15:32:40 +00:00
739913a2c9 FIX: Re-add overridden login view 2020-03-07 15:25:58 +00:00
5c5ccd244d Merge branch 'master' into python_deps_2020
# Conflicts:
#	PyRIGS/settings.py
#	RIGS/templates/RIGS/event_embed.html
#	RIGS/views.py
2020-03-06 20:01:26 +00:00
b7dcb2ccc5 Whoops, helps if one installs pycodestyle... 2020-02-21 12:26:23 +00:00
16b10333d5 Bit too heavy handed with the dep purge there... 2020-02-21 12:22:57 +00:00
cf7934974e Swap to pycodestyle rather than pep8 in Travis
And eliminate W605 errors
2020-02-21 12:20:44 +00:00
3cf13299eb Add newlines to the paperwork print test event
This will catch the error encountered in 79ec9214f9
2020-02-21 12:08:18 +00:00
6a65d14e5e Refactor dependency file
Should now only include dependencies we actually use, not dependencies of dependencies and unused things
2020-02-21 12:04:58 +00:00
b497ec11a0 FIX: Fix some Django4 deprecation warnings
Why not...
2020-02-21 02:09:04 +00:00
79ec9214f9 FIX: Fix broken newlining in PDFs
Introduced by a change in Django 2.1 'HTML rendered by form widgets no longer includes a closing slash on void elements, e.g. <br>. This is incompatible within XHTML, although some widgets already used aspects of HTML5 such as boolean attributes.'
2020-02-21 01:56:30 +00:00
2be88c8927 Revert "Disable password reset as temporary fix to vulnerability (#396)"
This reverts commit e0c6a56263.

# Conflicts:
#	RIGS/urls.py
2020-02-19 16:41:25 +00:00
e315c458de FIX: Remaining tests 2020-02-19 16:06:47 +00:00
1559f9098d FIX: Fix supplier sort 2020-02-19 14:46:39 +00:00
1dacbc1444 FIX: Correct static use in templates 2020-02-19 14:31:42 +00:00
8c981cc366 FIX: Update auth framework 2020-02-19 14:23:28 +00:00
a8261e0e7e FIX: Broken migrations 2020-02-19 13:48:10 +00:00
requires.io
e8c44a6346 [requires.io] dependency update 2020-02-17 15:21:44 +00:00
requires.io
1ba765a884 [requires.io] dependency update 2020-02-17 08:32:20 +00:00
requires.io
b9e6747918 [requires.io] dependency update 2020-02-12 20:51:35 +00:00
c3934e09bd Server starts...
Various things are broken, but it runs!
2020-02-08 14:07:33 +00:00
requires.io
fc938c897c [requires.io] dependency update 2020-02-08 13:52:14 +00:00
41 changed files with 169 additions and 213 deletions

View File

@@ -12,14 +12,14 @@ install:
- export PATH=$PATH:$(pwd)
- chmod +x chromedriver
- pip install -r requirements.txt
- pip install coveralls codeclimate-test-reporter pep8
- pip install coveralls codeclimate-test-reporter pycodestyle
before_script:
- export PATH=$PATH:/usr/lib/chromium-browser/
- python manage.py collectstatic --noinput
script:
- pep8 . --exclude=migrations,importer*
- pycodestyle . --exclude=migrations,importer*
- python manage.py check
- python manage.py makemigrations --check --dry-run
- coverage run manage.py test --verbosity=2

View File

@@ -50,7 +50,6 @@ if DEBUG:
ADMINS.append(('Testing Superuser', 'superuser@example.com'))
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
@@ -169,6 +168,8 @@ RECAPTCHA_PUBLIC_KEY = os.environ.get('RECAPTCHA_PUBLIC_KEY', "6LeIxAcTAAAAAJcZV
RECAPTCHA_PRIVATE_KEY = os.environ.get('RECAPTCHA_PRIVATE_KEY', "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe") # If not set, use development key
NOCAPTCHA = True
SILENCED_SYSTEM_CHECKS = ['captcha.recaptcha_test_key_error']
# Email
EMAILER_TEST = False
if not DEBUG or EMAILER_TEST:

View File

@@ -11,7 +11,7 @@ def create_browser():
if os.environ.get('CI', False):
options.add_argument("--headless")
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(chrome_options=options)
driver = webdriver.Chrome(options=options)
return driver

View File

@@ -1,3 +1,4 @@
from django.urls import path
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
@@ -15,8 +16,8 @@ urlpatterns = [
url('^assets/', include('assets.urls')),
url('^user/register/$', RegistrationView.as_view(form_class=RIGS.forms.ProfileRegistrationFormUniqueEmail),
name="registration_register"),
url('^user/', include('django.contrib.auth.urls')),
url('^user/', include('registration.backends.default.urls')),
path('user/', include('django.contrib.auth.urls')),
path('user/', include('registration.backends.default.urls')),
url(r'^admin/', admin.site.urls),
]

View File

@@ -1,7 +1,7 @@
from django.contrib import admin
from RIGS import models, forms
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from reversion.admin import VersionAdmin
from django.contrib.admin import helpers

View File

@@ -77,7 +77,7 @@ class InvoicePrint(generic.View):
pdfData = buffer.read()
escapedEventName = re.sub('[^a-zA-Z0-9 \n\.]', '', object.name)
escapedEventName = re.sub(r'[^a-zA-Z0-9 \n\.]', '', object.name)
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = "filename=Invoice %05d - N%05d | %s.pdf" % (invoice.pk, invoice.event.pk, escapedEventName)

View File

@@ -0,0 +1,37 @@
# Generated by Django 2.0.13 on 2020-03-06 20:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0037_approve_legacy'),
]
operations = [
migrations.AlterModelOptions(
name='event',
options={},
),
migrations.AlterModelOptions(
name='invoice',
options={'ordering': ['-invoice_date']},
),
migrations.AlterModelOptions(
name='organisation',
options={},
),
migrations.AlterModelOptions(
name='person',
options={},
),
migrations.AlterModelOptions(
name='profile',
options={'verbose_name': 'user', 'verbose_name_plural': 'users'},
),
migrations.AlterModelOptions(
name='venue',
options={},
),
]

View File

@@ -8,7 +8,6 @@ from django.contrib.auth.models import AbstractUser
from django.conf import settings
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.encoding import python_2_unicode_compatible
from reversion import revisions as reversion
from reversion.models import Version
import string
@@ -22,7 +21,6 @@ from django.urls import reverse_lazy
# Create your models here.
@python_2_unicode_compatible
class Profile(AbstractUser):
initials = models.CharField(max_length=5, unique=True, null=True, blank=False)
phone = models.CharField(max_length=13, null=True, blank=True)
@@ -66,11 +64,6 @@ class Profile(AbstractUser):
def __str__(self):
return self.name
class Meta:
permissions = (
('view_profile', 'Can view Profile'),
)
class RevisionMixin(object):
@property
@@ -101,7 +94,6 @@ class RevisionMixin(object):
@reversion.register
@python_2_unicode_compatible
class Person(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=15, blank=True, null=True)
@@ -137,14 +129,8 @@ class Person(models.Model, RevisionMixin):
def get_absolute_url(self):
return reverse_lazy('person_detail', kwargs={'pk': self.pk})
class Meta:
permissions = (
('view_person', 'Can view Persons'),
)
@reversion.register
@python_2_unicode_compatible
class Organisation(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=15, blank=True, null=True)
@@ -181,11 +167,6 @@ class Organisation(models.Model, RevisionMixin):
def get_absolute_url(self):
return reverse_lazy('organisation_detail', kwargs={'pk': self.pk})
class Meta:
permissions = (
('view_organisation', 'Can view Organisations'),
)
class VatManager(models.Manager):
def current_rate(self):
@@ -202,7 +183,6 @@ class VatManager(models.Manager):
@reversion.register
@python_2_unicode_compatible
class VatRate(models.Model, RevisionMixin):
start_at = models.DateField()
rate = models.DecimalField(max_digits=6, decimal_places=6)
@@ -223,7 +203,6 @@ class VatRate(models.Model, RevisionMixin):
@reversion.register
@python_2_unicode_compatible
class Venue(models.Model, RevisionMixin):
name = models.CharField(max_length=255)
phone = models.CharField(max_length=15, blank=True, null=True)
@@ -246,11 +225,6 @@ class Venue(models.Model, RevisionMixin):
def get_absolute_url(self):
return reverse_lazy('venue_detail', kwargs={'pk': self.pk})
class Meta:
permissions = (
('view_venue', 'Can view Venues'),
)
class EventManager(models.Manager):
def current_events(self):
@@ -297,7 +271,6 @@ class EventManager(models.Manager):
@reversion.register(follow=['items'])
@python_2_unicode_compatible
class Event(models.Model, RevisionMixin):
# Done to make it much nicer on the database
PROVISIONAL = 0
@@ -491,11 +464,6 @@ class Event(models.Model, RevisionMixin):
self.full_clean()
super(Event, self).save(*args, **kwargs)
class Meta:
permissions = (
('view_event', 'Can view Events'),
)
class EventItem(models.Model):
event = models.ForeignKey('Event', related_name='items', blank=True, on_delete=models.CASCADE)
@@ -533,7 +501,7 @@ class EventAuthorisation(models.Model, RevisionMixin):
uni_id = models.CharField(max_length=10, blank=True, null=True, verbose_name="University ID")
account_code = models.CharField(max_length=50, blank=True, null=True)
amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="authorisation amount")
sent_by = models.ForeignKey('RIGS.Profile', on_delete=models.CASCADE)
sent_by = models.ForeignKey('Profile', on_delete=models.CASCADE)
def get_absolute_url(self):
return reverse_lazy('event_detail', kwargs={'pk': self.event.pk})
@@ -543,7 +511,6 @@ class EventAuthorisation(models.Model, RevisionMixin):
return str("N%05d" % self.event.pk + ' (requested by ' + self.sent_by.initials + ')')
@python_2_unicode_compatible
class Invoice(models.Model):
event = models.OneToOneField('Event', on_delete=models.CASCADE)
invoice_date = models.DateField(auto_now_add=True)
@@ -576,13 +543,9 @@ class Invoice(models.Model):
return "%i: %s (%.2f)" % (self.pk, self.event, self.balance)
class Meta:
permissions = (
('view_invoice', 'Can view Invoices'),
)
ordering = ['-invoice_date']
@python_2_unicode_compatible
class Payment(models.Model):
CASH = 'C'
INTERNAL = 'I'

View File

@@ -110,7 +110,7 @@ class EventCreate(generic.CreateView):
context['currentVAT'] = models.VatRate.objects.current_rate()
form = context['form']
if re.search('"-\d+"', form['items_json'].value()):
if re.search(r'"-\d+"', form['items_json'].value()):
messages.info(self.request, "Your item changes have been saved. Please fix the errors and save the event.")
# Get some other objects to include in the form. Used when there are errors but also nice and quick.
@@ -206,7 +206,6 @@ class EventPrint(generic.View):
}
rml = template.render(context)
buffer = rml2pdf.parseString(rml)
merger.append(PdfFileReader(buffer))
buffer.close()
@@ -219,7 +218,7 @@ class EventPrint(generic.View):
response = HttpResponse(content_type='application/pdf')
escapedEventName = re.sub('[^a-zA-Z0-9 \n\.]', '', object.name)
escapedEventName = re.sub(r'[^a-zA-Z0-9 \n\.]', '', object.name)
response['Content-Disposition'] = "filename=N%05d | %s.pdf" % (object.pk, escapedEventName)
response.write(merged.getvalue())

View File

@@ -73,7 +73,7 @@ def send_eventauthorisation_success_email(instance):
external_styles=css).transform()
client_email.attach_alternative(html, 'text/html')
escapedEventName = re.sub('[^a-zA-Z0-9 \n\.]', '', instance.event.name)
escapedEventName = re.sub(r'[^a-zA-Z0-9 \n\.]', '', instance.event.name)
client_email.attach('N%05d - %s - CONFIRMATION.pdf' % (instance.event.pk, escapedEventName),
merged.getvalue(),

View File

@@ -1,8 +1,7 @@
{% extends 'base_embed.html' %}
{% load static from staticfiles %}
{% load static %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<a href="/">
@@ -72,7 +71,6 @@
</p>
</div>
<div class="col-xs-6">
{% if object.meet_at %}
<p>
<strong>Crew meet:</strong>
@@ -97,10 +95,7 @@
{{ object.description|linebreaksbr }}
</p>
{% endif %}
</table>
</div>
</div>
{% endblock %}

View File

@@ -1,7 +1,6 @@
{% load filters %}
<setNextFrame name="main"/>
<nextFrame/>
<blockTable style="headLayout" colWidths="330,165">
<tr>
<td>
@@ -13,7 +12,7 @@
<keepInFrame>
<para style="style.event_description">
{{ object.description|default_if_none:""|linebreaksbr }}
{{ object.description|default_if_none:""|linebreaksxml }}
</para>
</keepInFrame>
</td>
@@ -75,9 +74,9 @@
{% if invoice %}
<keepInFrame>
{% if object.organisation.address %}
<para style="specific_description">{{ object.organisation.address|default_if_none:""|linebreaksbr }}</para>
<para style="specific_description">{{ object.organisation.address|default_if_none:""|linebreaksxml }}</para>
{% elif object.person.address %}
<para style="specific_description">{{ object.person.address|default_if_none:""|linebreaksbr }}</para>
<para style="specific_description">{{ object.person.address|default_if_none:""|linebreaksxml }}</para>
{% endif %}
</keepInFrame>
{% endif %}
@@ -109,12 +108,12 @@
<h3>{{ object.venue.name }}</h3>
{% if not invoice %}
<keepInFrame>
<para style="specific_description">{{ object.venue.address|default_if_none:""|linebreaksbr }}</para>
<para style="specific_description">{{ object.venue.address|default_if_none:""|linebreaksxml }}</para>
</keepInFrame>
{% endif %}
</td>
<td rightPadding="0">
<h2>Timings</h2>
<blockTable style="eventDetails" colWidths="55,75">
<tr>
@@ -185,7 +184,7 @@
{% if item.description %}
</para>
<para style="item_description">
<em>{{ item.description|linebreaksbr }}</em>
<em>{{ item.description|linebreaksxml }}</em>
</para>
<para>
{% endif %}

View File

@@ -111,7 +111,7 @@
{% endif %}
</dd>
<dt>Authorsation request sent by</dt>
<dt>Authorisation request sent by</dt>
<dd>{{ object.authorisation.sent_by }}</dd>
</dl>
</div>

View File

@@ -1,4 +1,4 @@
<div class="modal fade" id="itemModal" role="dialog" aria-labelledby="itemModal" aria-hidded="true">
<div class="modal fade" id="itemModal" role="dialog" aria-labelledby="itemModal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
@@ -33,7 +33,6 @@
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="item_quantity" class="col-sm-4 control-label">Quantity</label>
@@ -71,4 +70,4 @@
</form>
</div>
</div>
</div>
</div>

View File

@@ -13,7 +13,7 @@
{% if edit %}
<td class="text-right">
<button type="button" class="btn btn-default btn-xs item-add"
data-url="{#% url eventitem_add object.pk %#}" data-toggle="modal"
data-toggle="modal"
data-target="#itemModal">
<span class="glyphicon glyphicon-plus"></span>
</button>

View File

@@ -1,9 +0,0 @@
{% extends 'base_rigs.html' %}
{% block title %}Password Reset Disabled{% endblock %}
{% block content %}
<h1>Password reset is disabled</h1>
<p> We are very sorry for the inconvenience, but due to a security vulnerability, password reset is currently disabled until the vulnerability can be patched.</p>
<p> If you are locked out of your account, please contact an administrator and we can manually perform a reset</p>
{% endblock %}

View File

@@ -2,10 +2,24 @@ from django import template
from django import forms
from django.forms.forms import NON_FIELD_ERRORS
from django.forms.utils import ErrorDict
from django.utils.text import normalize_newlines
from django.template.defaultfilters import stringfilter
from django.utils.safestring import SafeData, mark_safe
from django.utils.html import escape
register = template.Library()
@register.filter(is_safe=True, needs_autoescape=True)
@stringfilter
def linebreaksxml(value, autoescape=True):
autoescape = autoescape and not isinstance(value, SafeData)
value = normalize_newlines(value)
if autoescape:
value = escape(value)
return mark_safe(value.replace('\n', '<br />'))
@register.filter
def multiply(value, arg):
return value * arg

View File

@@ -94,7 +94,8 @@ class UserRegistrationTest(LiveServerTestCase):
# Read what the error is
alert = self.browser.find_element_by_css_selector(
'div.alert-danger').text
self.assertIn("password fields didn't match", alert)
# TODO Use regex matching to handle smart/unsmart quotes...
self.assertIn("password fields didn", alert)
# Passwords should be empty
self.assertEqual(password1.get_attribute('value'), '')
@@ -121,7 +122,7 @@ class UserRegistrationTest(LiveServerTestCase):
email = mail.outbox[0]
self.assertIn('John Smith "JS" activation required', email.subject)
urls = re.findall(
'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', email.body)
r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', email.body)
self.assertEqual(len(urls), 1)
mail.outbox = [] # empty this for later
@@ -504,8 +505,10 @@ class EventTest(LiveServerTestCase):
# Add item
form.find_element_by_xpath('//button[contains(@class, "item-add")]').click()
wait.until(animation_is_finished())
modal = self.browser.find_element_by_id("itemModal")
wait.until(animation_is_finished())
# See modal has opened
self.assertTrue(modal.is_displayed())
modal.find_element_by_id("item_name").send_keys("Test Item 3")
modal.find_element_by_id("item_description").send_keys(
"This is an item description\nthat for reasons unknown spans two lines")

View File

@@ -424,7 +424,7 @@ class RIGSVersionTestCase(TestCase):
def test_find_parent_version(self):
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
self.assertEqual(currentVersion._object_version.object.notes, "A new note on the event")
# Check the prev version is loaded correctly
@@ -436,7 +436,7 @@ class RIGSVersionTestCase(TestCase):
def test_changes_since(self):
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
changes = currentVersion.changes
self.assertEqual(len(changes.field_changes), 1)
@@ -453,7 +453,7 @@ class RIGSVersionTestCase(TestCase):
self.event.save()
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
diff = currentVersion.changes
# There are two changes
@@ -475,7 +475,7 @@ class RIGSVersionTestCase(TestCase):
self.person.save()
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.person).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.person).latest('revision__date_created')
diff = currentVersion.changes
# Should be declared as long
@@ -488,7 +488,7 @@ class RIGSVersionTestCase(TestCase):
self.event.save()
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
# Check the diff is correct
self.assertEqual(currentVersion.changes.field_changes[0].diff,
@@ -504,12 +504,12 @@ class RIGSVersionTestCase(TestCase):
self.event.status = models.Event.CONFIRMED
self.event.save()
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
self.assertEqual(currentVersion.changes.field_changes[0].old, 'Provisional')
self.assertEqual(currentVersion.changes.field_changes[0].new, 'Confirmed')
def test_creation_behaviour(self):
firstVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created').parent
firstVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created').parent
diff = firstVersion.changes
# Mainly to check for exceptions:
@@ -522,7 +522,7 @@ class RIGSVersionTestCase(TestCase):
self.event.save()
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
diffs = currentVersion.changes.item_changes
@@ -541,7 +541,7 @@ class RIGSVersionTestCase(TestCase):
item1.save()
self.event.save()
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
diffs = currentVersion.changes.item_changes
@@ -563,7 +563,7 @@ class RIGSVersionTestCase(TestCase):
self.event.save()
# Find the most recent version
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest(field_name='revision__date_created')
currentVersion = versioning.RIGSVersion.objects.get_for_object(self.event).latest('revision__date_created')
diffs = currentVersion.changes.item_changes

View File

@@ -226,7 +226,7 @@ class TestPrintPaperwork(TestCase):
cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
cls.events = {
1: models.Event.objects.create(name="TE E1", start_date=date.today()),
1: models.Event.objects.create(name="TE E1", start_date=date.today(), description="This is an event description\nthat for a very specific reason spans two lines."),
}
cls.invoices = {

View File

@@ -1,7 +1,9 @@
from django.urls import path
from django.conf.urls import url
from django.contrib.auth.views import password_reset
from django.contrib.auth.views import PasswordResetView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import LoginView
from RIGS import models, views, rigboard, finance, ical, versioning, forms
from django.views.generic import RedirectView
from django.views.decorators.clickjacking import xframe_options_exempt
@@ -16,10 +18,8 @@ urlpatterns = [
url('^$', login_required(views.Index.as_view()), name='index'),
url(r'^closemodal/$', views.CloseModal.as_view(), name='closemodal'),
url('^user/login/$', views.login, name='login'),
url('^user/login/embed/$', xframe_options_exempt(views.login_embed), name='login_embed'),
url(r'^user/password_reset/$', views.PasswordResetDisabled.as_view()),
path('user/login/', LoginView.as_view(authentication_form=forms.CheckApprovedForm), name='login'),
path('user/login/embed/', xframe_options_exempt(views.LoginEmbed.as_view()), name='login_embed'),
url(r'^search_help/$', views.SearchHelp.as_view(), name='search_help'),

View File

@@ -184,8 +184,7 @@ class RIGSVersion(Version):
versions = RIGSVersion.objects.get_for_object_reference(self.content_type.model_class(), thisId).select_related("revision", "revision__user").all()
try:
previousVersion = versions.filter(revision_id__lt=self.revision_id).latest(
field_name='revision__date_created')
previousVersion = versions.filter(revision_id__lt=self.revision_id).latest('revision__date_created')
except ObjectDoesNotExist:
return False

View File

@@ -3,6 +3,7 @@ from django.http.response import HttpResponseRedirect
from django.http import HttpResponse
from django.urls import reverse_lazy, reverse, NoReverseMatch
from django.views import generic
from django.contrib.auth.views import LoginView
from django.db.models import Q
from django.shortcuts import get_object_or_404
from django.core import serializers
@@ -34,16 +35,6 @@ class Index(generic.TemplateView):
return context
def login(request, **kwargs):
if request.user.is_authenticated:
next = request.GET.get('next', '/')
return HttpResponseRedirect(next)
else:
from django.contrib.auth.views import login
return login(request, authentication_form=forms.CheckApprovedForm)
class SearchHelp(generic.TemplateView):
template_name = 'RIGS/search_help.html'
@@ -52,14 +43,11 @@ class SearchHelp(generic.TemplateView):
# Then we can check for it and show a nice error
# Don't worry, django.contrib.auth.views.login will
# check for it before logging the user in
@csrf_exempt
def login_embed(request, **kwargs):
if request.user.is_authenticated:
next = request.GET.get('next', '/')
return HttpResponseRedirect(next)
else:
from django.contrib.auth.views import login
class LoginEmbed(LoginView):
template_name = 'registration/login_embed.html'
@csrf_exempt
def dispatch(self, request, *args, **kwargs):
if request.method == "POST":
csrf_cookie = request.COOKIES.get('csrftoken', None)
@@ -67,7 +55,7 @@ def login_embed(request, **kwargs):
messages.warning(request, 'Cookies do not seem to be enabled. Try logging in using a new tab.')
request.method = 'GET' # Render the page without trying to login
return login(request, template_name="registration/login_embed.html", authentication_form=forms.EmbeddedAuthenticationForm)
return super().dispatch(request, *args, **kwargs)
"""
@@ -423,7 +411,3 @@ class ResetApiKey(generic.RedirectView):
self.request.user.save()
return reverse_lazy('profile_detail')
class PasswordResetDisabled(generic.TemplateView):
template_name = "RIGS/password_reset_disable.html"

View File

@@ -57,7 +57,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='asset',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=None, related_name='asset_parent', to='assets.Asset'),
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='asset_parent', to='assets.Asset'),
),
migrations.RemoveField(
model_name='asset',
@@ -85,7 +85,7 @@ class Migration(migrations.Migration):
('circuits', models.IntegerField(blank=True, null=True)),
('cores', models.IntegerField(blank=True, null=True)),
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.AssetCategory')),
('parent', models.ForeignKey(blank=True, null=True, on_delete=None, related_name='asset_parent', to='assets.Cable')),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='asset_parent', to='assets.Cable')),
],
options={
'abstract': False,

View File

@@ -1,17 +0,0 @@
# Generated by Django 2.0.13 on 2020-02-07 17:37
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0009_auto_20200103_2215'),
]
operations = [
migrations.AlterModelOptions(
name='supplier',
options={'ordering': ['name'], 'permissions': (('view_supplier', 'Can view a supplier'),)},
),
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 3.0.3 on 2020-02-19 14:44
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0009_auto_20200103_2215'),
]
operations = [
migrations.AlterModelOptions(
name='asset',
options={'ordering': ['asset_id_prefix', 'asset_id_number'], 'permissions': [('asset_finance', 'Can see financial data for assets')]},
),
migrations.AlterModelOptions(
name='supplier',
options={'ordering': ['name']},
),
]

View File

@@ -41,13 +41,10 @@ class AssetStatus(models.Model):
@reversion.register
class Supplier(models.Model, RevisionMixin):
name = models.CharField(max_length=80)
class Meta:
ordering = ['name']
permissions = (
('view_supplier', 'Can view a supplier'),
)
name = models.CharField(max_length=80)
def get_absolute_url(self):
return reverse('supplier_list')
@@ -70,10 +67,9 @@ class Connector(models.Model):
class Asset(models.Model, RevisionMixin):
class Meta:
ordering = ['asset_id_prefix', 'asset_id_number']
permissions = (
('asset_finance', 'Can see financial data for assets'),
('view_asset', 'Can view an asset')
)
permissions = [
('asset_finance', 'Can see financial data for assets')
]
parent = models.ForeignKey(to='self', related_name='asset_parent',
blank=True, null=True, on_delete=models.SET_NULL)

View File

@@ -1,8 +1,7 @@
{% extends 'base_embed.html' %}
{% load static from staticfiles %}
{% load static %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<a href="/assets">
@@ -35,6 +34,4 @@
</table>
</div>
</div>
{% endblock %}

View File

@@ -249,7 +249,7 @@ class TestSupplierCreateAndEdit(AutoLoginTest):
def test_supplier_edit(self):
self.page = pages.SupplierEdit(self.driver, self.live_server_url, supplier_id=self.supplier.pk).open()
self.assertEquals("Fullmetal Heavy Industry", self.page.name)
self.assertEqual("Fullmetal Heavy Industry", self.page.name)
new_name = "Cyberdyne Systems"
self.page.name = new_name
self.page.submit()

View File

@@ -1,41 +1,24 @@
beautifulsoup4==4.6.0
contextlib2==0.5.5
diff-match-patch==20121119
diff-match-patch==20181111
dj-database-url==0.5.0
dj-static==0.0.6
Django==2.0.13
django-filter==2.0.0
django-widget-tweaks==1.4.3
django-debug-toolbar==1.9.1
django-ical==1.4
django-recaptcha==1.4.0
django-registration-redux==2.4
django-reversion==2.0.13
django-toolbelt==0.0.1
premailer==3.2.0
git+git://github.com/jazzband/django-widget-tweaks.git@1.4.2
gunicorn==19.8.1
icalendar==4.0.1
lxml==4.2.1
Markdown==2.6.11
Pillow==6.2.0
psycopg2==2.7.4
Pygments==2.2.0
Django==3.0.3
django-debug-toolbar==2.2
django-ical==1.7.0
django-recaptcha==2.0.6
django-registration-redux==2.7
django-reversion==3.0.7
django-widget-tweaks==1.4.5
gunicorn==20.0.4
icalendar==4.0.4
lxml==4.5.0
premailer==3.6.1
psycopg2==2.8.4
PyPDF2==1.26.0
python-dateutil==2.7.3
pytz==2018.4
raven==6.8.0
reportlab==3.4.0
selenium==3.12.0
simplejson==3.15.0
six==1.11.0
sqlparse==0.2.4
static3==0.7.0
svg2rlg==0.3
yolk==0.4.3
whitenoise==4.1.2
z3c.rml==3.5.0
zope.event==4.3.0
zope.interface==4.5.0
zope.schema==4.5.0
pypom==2.2.0
PyPOM==2.2.0
pytz==2019.3
raven==6.10.0
requests==2.23.0
selenium==3.141.0
simplejson==3.17.0
whitenoise==5.0.1
z3c.rml==3.9.1

View File

@@ -1,5 +1,5 @@
{% extends 'base_rigs.html' %}
{% load staticfiles %}
{% load static %}
{% block title %}Bad Request{% endblock %}
{% block content %}

View File

@@ -1,5 +1,5 @@
{% extends 'base_rigs.html' %}
{% load staticfiles %}
{% load static %}
{% block title %}Unauthorized{% endblock %}
{% block content %}

View File

@@ -1,5 +1,5 @@
{% extends 'base_rigs.html' %}
{% load staticfiles %}
{% load static %}
{% block title %}Forbidden{% endblock %}
{% block content %}

View File

@@ -1,5 +1,5 @@
{% extends 'base_rigs.html' %}
{% load staticfiles %}
{% load static %}
{% block title %}Page Not Found{% endblock %}
{% block content %}

View File

@@ -1,5 +1,5 @@
{% extends 'base_rigs.html' %}
{% load staticfiles %}
{% load static %}
{% block title %}Server error{% endblock %}
{% block content %}

View File

@@ -1,7 +1,6 @@
{% load static from staticfiles %}
{% load static %}
{% load raven %}
<!DOCTYPE html>
<html
dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}"

View File

@@ -1,4 +1,4 @@
{% load static from staticfiles %}
{% load static %}
{% load raven %}

View File

@@ -1,17 +1,14 @@
{% load static from staticfiles %}
{% load static %}
{% load raven %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<table class="main-table">
<tr class="client-header">
<td align="center">
@@ -32,7 +29,7 @@
<!--[if mso]>
</td></tr></table>
</center>
<![endif]-->
<![endif]-->
</td>
</tr>
<tr>
@@ -47,12 +44,9 @@
<!--[if mso]>
</td></tr></table>
</center>
<![endif]-->
<![endif]-->
</td>
</tr>
</table>
</body>
</html>

View File

@@ -1,4 +1,4 @@
{% load static from staticfiles %}
{% load static %}
{% load raven %}
<!DOCTYPE html>

View File

@@ -1,5 +1,5 @@
{% extends 'base_rigs.html' %}
{% load staticfiles %}
{% load static %}
{% block title %}Login Required{% endblock %}
{% block js %}

View File

@@ -1,8 +1,6 @@
{% load widget_tweaks %}
{% include 'form_errors.html' %}
<div class="col-sm-6 col-sm-offset-3 col-lg-4 col-lg-offset-4">
<form action="{% url 'login' %}" method="post" role="form" target="_self">{% csrf_token %}
<div class="form-group">
<label for="id_username">{{ form.username.label }}</label>