Compare commits

..

6 Commits

Author SHA1 Message Date
David Taylor
3269e92ef2 Merge pull request #277 from nottinghamtec/davidtaylorhq-patch-1
Explicitly define height in oembed JSON
2017-03-10 15:29:29 +00:00
David Taylor
0ae7bcaf7c Explicitly define height in oembed JSON 2017-03-10 15:26:00 +00:00
Tom Price
9694d407ae Merge pull request #275 from nottinghamtec/hotfix/home-links
Make forum go to actual forum
2017-02-06 15:47:12 +00:00
Sam Osborne
82aa2785ea Make forum go to actual forum
Currently goes to old forum :(
2017-02-06 15:35:29 +00:00
David Taylor
337dbd74fd Merge pull request #273 from nottinghamtec/hotfix/restore-pagination
Restore pagination to invoice waiting (requested by Emma)
2016-11-04 13:36:21 +00:00
David Taylor
caa55fe89a Restore pagination to invoice waiting (requested by Emma) 2016-11-04 13:31:06 +00:00
21 changed files with 115 additions and 528 deletions

View File

@@ -58,7 +58,6 @@ INSTALLED_APPS = (
'captcha',
'widget_tweaks',
'raven.contrib.django.raven_compat',
'social.apps.django_app.default',
)
MIDDLEWARE_CLASSES = (
@@ -74,31 +73,6 @@ MIDDLEWARE_CLASSES = (
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
AUTHENTICATION_BACKENDS = (
'RIGS.discourse.discourse.DiscourseAuth',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details', # Load remote details
'social.pipeline.social_auth.social_uid', # Load remote ID
'social.pipeline.social_auth.auth_allowed', # Check not blacklisted
'social.pipeline.social_auth.social_user', # If already associated, login
'RIGS.discourse.pipeline.new_connection', # Choose a user account, much UI
'social.pipeline.social_auth.associate_user', # Associate the social auth with the user
'social.pipeline.social_auth.load_extra_data', # Save all the social info we have on this user
'RIGS.discourse.pipeline.update_avatar', # Load the avatar URL from the API, and save to user model
'social.pipeline.user.user_details', # Save any details that changed
)
DISCOURSE_HOST = os.environ.get('DISCOURSE_HOST') if os.environ.get('DISCOURSE_HOST') else 'http://localhost:4000'
DISCOURSE_SSO_SECRET = os.environ.get('DISCOURSE_SSO_SECRET') if os.environ.get('DISCOURSE_SSO_SECRET') else 'ABCDEFGHIJKLMNOP'
DISCOURSE_API_KEY = os.environ.get('DISCOURSE_API_KEY') if os.environ.get('DISCOURSE_HOST') else None
DISCOURSE_API_USER = os.environ.get('DISCOURSE_API_USER') if os.environ.get('DISCOURSE_HOST') else 'system'
REGISTRATION_OPEN = False # Disable built-in django registration - must register using forum
ROOT_URLCONF = 'PyRIGS.urls'
WSGI_APPLICATION = 'PyRIGS.wsgi.application'
@@ -228,8 +202,6 @@ TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.tz",
"django.core.context_processors.request",
"django.contrib.messages.context_processors.messages",
'social.apps.django_app.context_processors.backends',
'social.apps.django_app.context_processors.login_redirect',
)

View File

@@ -18,7 +18,6 @@ urlpatterns = patterns('',
url('^user/', include('registration.backends.default.urls')),
url(r'^admin/', include(admin.site.urls)),
url('', include('social.apps.django_app.urls', namespace='social'))
)
if settings.DEBUG:

View File

@@ -1,91 +0,0 @@
from __future__ import unicode_literals
from social.backends.base import BaseAuth
from django.conf import settings
from .sso import DiscourseSSO
class DiscourseAssociation(object):
""" Use Association model to save the nonce by force. """
def __init__(self, handle, secret='', issued=0, lifetime=0, assoc_type=''):
self.handle = handle # as nonce
self.secret = secret.encode() # not use
self.issued = issued # not use
self.lifetime = lifetime # not use
self.assoc_type = assoc_type # as state
class DiscourseAuth(BaseAuth):
"""Discourse authentication backend"""
name = 'discourse'
secret = settings.DISCOURSE_SSO_SECRET
host = settings.DISCOURSE_HOST
EXTRA_DATA = [
('username', 'username'),
('email', 'email'),
('external_id', 'external_id')
]
sso = DiscourseSSO(secret)
def get_and_store_nonce(self, url):
# Create a nonce
nonce = self.strategy.random_string(64)
# Store the nonce
association = DiscourseAssociation(nonce)
self.strategy.storage.association.store(url, association)
return nonce
def get_nonce(self, nonce):
try:
return self.strategy.storage.association.get(
server_url=self.host,
handle=nonce
)[0]
except IndexError:
pass
def remove_nonce(self, nonce_id):
self.strategy.storage.association.remove([nonce_id])
def get_user_id(self, details, response):
"""Return current user id."""
return int(response['external_id'])
def get_user_details(self, response):
"""Return user basic information (id and email only)."""
return {'username': response['username'],
'email': response['email'],
'fullname': response['name'].replace('+', ' ') if 'name' in response else '',
'first_name': '',
'last_name': ''}
def auth_url(self):
"""Build and return complete URL."""
nonce = self.get_and_store_nonce(self.host)
return self.host + self.sso.build_login_URL(nonce, self.redirect_uri)
def auth_complete(self, *args, **kwargs):
"""Completes login process, must return user instance."""
try:
if not self.sso.validate(self.data['sso'], self.data['sig']):
raise Exception("Someone wants to hack us!")
except KeyError:
raise Exception("SSO Error, please try again")
nonce = self.sso.get_nonce(self.data['sso'])
nonce_obj = self.get_nonce(nonce)
if nonce_obj:
self.remove_nonce(nonce_obj.id)
else:
raise Exception("Nonce does not match!")
kwargs.update({'response': self.sso.get_data(
self.data['sso']), 'backend': self})
return self.strategy.authenticate(*args, **kwargs)

View File

@@ -1,88 +0,0 @@
from django.core.urlresolvers import reverse
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.shortcuts import render_to_response
from django.core.exceptions import ValidationError
from django.conf import settings
import json
import requests
from social.pipeline.partial import partial
from RIGS.models import Profile
from RIGS import forms
class SocialRegisterForm(forms.ProfileRegistrationFormUniqueEmail):
def __init__(self, *args, **kwargs):
super(SocialRegisterForm, self).__init__(*args, **kwargs)
self.fields.pop('password1')
self.fields.pop('password2')
self.fields.pop('captcha')
self.fields['email'].widget.attrs['readonly'] = True
def clean_email(self):
initial = getattr(self, 'initial', None)
if(initial['email'] != self.cleaned_data['email']):
raise ValidationError("You cannot change the email")
return initial['email']
@partial
def new_connection(backend, details, response, user=None, is_new=False, social=None, request=None, *args, **kwargs):
if social is not None:
return
data = backend.strategy.request_data()
if data.get('UseCurrentAccount') is not None:
return
alreadyLoggedIn = user is not None
context = {
'details': details,
'alreadyLoggedIn': alreadyLoggedIn,
'loggedInUser': user,
}
if not alreadyLoggedIn:
completeUrl = reverse('social:complete', kwargs={'backend': backend.name})
context['login_url'] = "{0}?{1}={2}".format(reverse('login'), REDIRECT_FIELD_NAME, completeUrl)
if data.get('username') is None:
form = SocialRegisterForm(initial=details)
else:
form = SocialRegisterForm(data, initial=details)
if form.is_valid():
new_user = Profile.objects.create_user(**form.cleaned_data)
return {'user': new_user}
context['form'] = form
return render_to_response('RIGS/social-associate.html', context)
def update_avatar(backend, details, response, user=None, social=None, *args, **kwargs):
host = settings.DISCOURSE_HOST
api_key = settings.DISCOURSE_API_KEY
api_user = settings.DISCOURSE_API_USER
if social is not None:
url = "{}/users/{}.json".format(host, details['username'])
params = {
'api_key': api_key,
'api_username': api_user
}
resp = requests.get(url=url, params=params)
extraData = json.loads(resp.text)
avatar_template = extraData['user']['avatar_template']
if avatar_template and user.avatar_template != avatar_template:
user.avatar_template = avatar_template
user.save()
return

View File

@@ -1,46 +0,0 @@
import urllib
from hashlib import sha256
import hmac
from base64 import b64decode, b64encode
class DiscourseSSO:
def __init__(self, secret_key):
self.__secret_key = secret_key
def validate(self, payload, sig):
payload = urllib.unquote(payload)
computed_sig = hmac.new(
self.__secret_key.encode(),
payload.encode(),
sha256
).hexdigest()
return hmac.compare_digest(unicode(computed_sig), sig)
def get_nonce(self, payload):
payload = b64decode(urllib.unquote(payload)).decode()
d = dict(nonce.split("=") for nonce in payload.split('&'))
if 'nonce' in d and d['nonce'] != '':
return d['nonce']
else:
raise Exception("Nonce could not be found in payload")
def get_data(self, payload):
payload = urllib.unquote(b64decode(urllib.unquote(payload)).decode())
d = dict(data.split("=") for data in payload.split('&'))
return d
def build_login_URL(self, nonce, redirect_uri):
data = {
'nonce': nonce,
'return_sso_url': redirect_uri
}
payload = urllib.urlencode(data)
payload = b64encode(payload.encode())
sig = hmac.new(self.__secret_key.encode(), payload, sha256).hexdigest()
return '/session/sso_provider?' + urllib.urlencode({'sso': payload, 'sig': sig})

View File

@@ -122,7 +122,7 @@ class InvoiceArchive(generic.ListView):
class InvoiceWaiting(generic.ListView):
model = models.Event
# paginate_by = 25
paginate_by = 25
template_name = 'RIGS/event_invoice.html'
def get_context_data(self, **kwargs):

View File

@@ -3,7 +3,6 @@ from django import forms
from django.utils import formats
from django.conf import settings
from django.core import serializers
from django.core.exceptions import ValidationError
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, AuthenticationForm, PasswordResetForm
from registration.forms import RegistrationFormUniqueEmail
from captcha.fields import ReCaptchaField
@@ -28,16 +27,6 @@ class ProfileRegistrationFormUniqueEmail(RegistrationFormUniqueEmail):
raise forms.ValidationError("These initials are already in use. Please supply different initials.")
return self.cleaned_data['initials']
def clean_first_name(self):
if self.cleaned_data["first_name"].strip() == '':
raise ValidationError("First name is required.")
return self.cleaned_data["first_name"]
def clean_last_name(self):
if self.cleaned_data["last_name"].strip() == '':
raise ValidationError("Last name is required.")
return self.cleaned_data["last_name"]
# Login form
class PasswordReset(PasswordResetForm):

View File

@@ -1,19 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0024_auto_20160229_2042'),
]
operations = [
migrations.AddField(
model_name='profile',
name='avatar_template',
field=models.CharField(max_length=255, null=True, editable=False, blank=True),
),
]

View File

@@ -22,7 +22,6 @@ 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)
api_key = models.CharField(max_length=40, blank=True, editable=False, null=True)
avatar_template = models.CharField(max_length=255, blank=True, editable=False, null=True)
@classmethod
def make_api_key(cls):
@@ -34,13 +33,8 @@ class Profile(AbstractUser):
@property
def profile_picture(self):
url = ""
if settings.DISCOURSE_API_KEY is not None:
if self.avatar_template:
return settings.DISCOURSE_HOST+self.avatar_template.format(size=500)
if settings.USE_GRAVATAR or settings.USE_GRAVATAR is None:
url = "https://www.gravatar.com/avatar/" + hashlib.md5(self.email).hexdigest() + "?d=wavatar&s=500"
return url
@property

View File

@@ -61,6 +61,7 @@ class EventOembed(generic.View):
'html': '<iframe src="{0}" frameborder="0" width="100%" height="250"></iframe>'.format(full_url),
'version': '1.0',
'type': 'rich',
'height': '250'
}
json = simplejson.JSONEncoderForHTML().encode(data)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 KiB

View File

@@ -23,7 +23,7 @@
<div class="list-group-item default"></div>
<a class="list-group-item" href="//members.nottinghamtec.co.uk/forum" target="_blank"><span class="glyphicon glyphicon-link"></span> TEC Forum</a>
<a class="list-group-item" href="https://forum.nottinghamtec.co.uk" target="_blank"><span class="glyphicon glyphicon-link"></span> TEC Forum</a>
<a class="list-group-item" href="//members.nottinghamtec.co.uk/wiki" target="_blank"><span class="glyphicon glyphicon-link"></span> TEC Wiki</a>
<a class="list-group-item" href="http://members.nottinghamtec.co.uk/wiki/images/2/22/Event_Risk_Assesment.pdf" target="_blank"><span class="glyphicon glyphicon-link"></span> Pre-Event Risk Assessment</a>
<a class="list-group-item" href="//members.nottinghamtec.co.uk/price" target="_blank"><span class="glyphicon glyphicon-link"></span> Price List</a>

View File

@@ -133,20 +133,6 @@
{% endif %}
</dd>
</dl>
<h4>Linked to {{object.social_auth.count}} Forum Account(s)</h4>
{% if object.social_auth.count > 0 %}
<a href="{% url 'unlink_forum' %}" class="btn btn-danger">
Unlink Forum Account(s) <span class="glyphicon glyphicon-pencil"></span>
</a>
{% else %}
<a href="{% url "social:begin" "discourse" %}" class="btn btn-success">
Link Forum Account <span class="glyphicon glyphicon-pencil"></span>
</a>
{% endif %}
{% endif %}
{% endif %}
</div>

View File

@@ -1,55 +0,0 @@
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block title %}Associate{% endblock %}
{% block content %}
<div class="col-sm-10 col-sm-offset-1">
<div class="text-center">
<h1>R<small>ig</small> I<small>nformation</small> G<small>athering</small> S<small>ystem</small></h1>
</div>
<h2 class="text-center">Welcome <strong>{{details.username}}</strong></h2>
<h4 class="text-center">This is the first time you've visited RIGS with your forum account, so we need a few details to get you set up</h4>
<hr/>
{% if alreadyLoggedIn %}
<h2 class="text-center">You are logged in to RIGS as <strong>{{loggedInUser.username}}</strong></h2>
<div class="col-sm-8 col-sm-offset-2">
<form action="", method="post">{% csrf_token %}
<input type="hidden" name="UseCurrentAccount" value="1"/>
<button type="submit" class="btn btn-lg btn-primary center btn-block">Link Forum account to RIGS Account</button>
</form>
<a class="btn btn-lg btn-warning center btn-block" href="{% url 'logout' %}" role="button">Logout</a>
</div>
{% else %}
<h4 class="text-center"><a class="btn btn-info" href="{{login_url}}" role="button">I already have a RIGS account</a></h4>
{% if form.errors or supplement_form.errors %}
<div class="alert alert-danger">
{{form.errors}}
{{supplement_form.errors}}
</div>
{% endif %}
<div class="col-sm-8 col-sm-offset-2">
<form action="" method="post" class="form-horizontal" role="form">{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}" class="control-label col-sm-4">{{ field.label }}</label>
<div class="controls col-sm-8">
{% render_field field class+="form-control" placeholder=field.label %}
</div>
</div>
{% endfor %}
<p><input type="submit" value="Register" class="btn btn-primary pull-right"></p>
</form>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -16,136 +16,136 @@ from selenium.webdriver.support.ui import WebDriverWait
from RIGS import models
# class UserRegistrationTest(LiveServerTestCase):
class UserRegistrationTest(LiveServerTestCase):
# def setUp(self):
# self.browser = webdriver.Firefox()
# self.browser.implicitly_wait(3) # Set implicit wait session wide
# os.environ['RECAPTCHA_TESTING'] = 'True'
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3) # Set implicit wait session wide
os.environ['RECAPTCHA_TESTING'] = 'True'
# def tearDown(self):
# self.browser.quit()
# os.environ['RECAPTCHA_TESTING'] = 'False'
def tearDown(self):
self.browser.quit()
os.environ['RECAPTCHA_TESTING'] = 'False'
# def test_registration(self):
# # Navigate to the registration page
# self.browser.get(self.live_server_url + '/user/register/')
# title_text = self.browser.find_element_by_tag_name('h3').text
# self.assertIn("User Registration", title_text)
def test_registration(self):
# Navigate to the registration page
self.browser.get(self.live_server_url + '/user/register/')
title_text = self.browser.find_element_by_tag_name('h3').text
self.assertIn("User Registration", title_text)
# # Check the form invites correctly
# username = self.browser.find_element_by_id('id_username')
# self.assertEqual(username.get_attribute('placeholder'), 'Username')
# email = self.browser.find_element_by_id('id_email')
# self.assertEqual(email.get_attribute('placeholder'), 'E-mail')
# # If this is correct we don't need to test it later
# self.assertEqual(email.get_attribute('type'), 'email')
# password1 = self.browser.find_element_by_id('id_password1')
# self.assertEqual(password1.get_attribute('placeholder'), 'Password')
# self.assertEqual(password1.get_attribute('type'), 'password')
# password2 = self.browser.find_element_by_id('id_password2')
# self.assertEqual(
# password2.get_attribute('placeholder'), 'Password confirmation')
# self.assertEqual(password2.get_attribute('type'), 'password')
# first_name = self.browser.find_element_by_id('id_first_name')
# self.assertEqual(first_name.get_attribute('placeholder'), 'First name')
# last_name = self.browser.find_element_by_id('id_last_name')
# self.assertEqual(last_name.get_attribute('placeholder'), 'Last name')
# initials = self.browser.find_element_by_id('id_initials')
# self.assertEqual(initials.get_attribute('placeholder'), 'Initials')
# phone = self.browser.find_element_by_id('id_phone')
# self.assertEqual(phone.get_attribute('placeholder'), 'Phone')
# Check the form invites correctly
username = self.browser.find_element_by_id('id_username')
self.assertEqual(username.get_attribute('placeholder'), 'Username')
email = self.browser.find_element_by_id('id_email')
self.assertEqual(email.get_attribute('placeholder'), 'E-mail')
# If this is correct we don't need to test it later
self.assertEqual(email.get_attribute('type'), 'email')
password1 = self.browser.find_element_by_id('id_password1')
self.assertEqual(password1.get_attribute('placeholder'), 'Password')
self.assertEqual(password1.get_attribute('type'), 'password')
password2 = self.browser.find_element_by_id('id_password2')
self.assertEqual(
password2.get_attribute('placeholder'), 'Password confirmation')
self.assertEqual(password2.get_attribute('type'), 'password')
first_name = self.browser.find_element_by_id('id_first_name')
self.assertEqual(first_name.get_attribute('placeholder'), 'First name')
last_name = self.browser.find_element_by_id('id_last_name')
self.assertEqual(last_name.get_attribute('placeholder'), 'Last name')
initials = self.browser.find_element_by_id('id_initials')
self.assertEqual(initials.get_attribute('placeholder'), 'Initials')
phone = self.browser.find_element_by_id('id_phone')
self.assertEqual(phone.get_attribute('placeholder'), 'Phone')
# # Fill the form out incorrectly
# username.send_keys('TestUsername')
# email.send_keys('test@example.com')
# password1.send_keys('correcthorsebatterystaple')
# # deliberate mistake
# password2.send_keys('correcthorsebatterystapleerror')
# first_name.send_keys('John')
# last_name.send_keys('Smith')
# initials.send_keys('JS')
# phone.send_keys('0123456789')
# self.browser.execute_script(
# "return jQuery('#g-recaptcha-response').val('PASSED')")
# Fill the form out incorrectly
username.send_keys('TestUsername')
email.send_keys('test@example.com')
password1.send_keys('correcthorsebatterystaple')
# deliberate mistake
password2.send_keys('correcthorsebatterystapleerror')
first_name.send_keys('John')
last_name.send_keys('Smith')
initials.send_keys('JS')
phone.send_keys('0123456789')
self.browser.execute_script(
"return jQuery('#g-recaptcha-response').val('PASSED')")
# # Submit incorrect form
# submit = self.browser.find_element_by_xpath("//input[@type='submit']")
# submit.click()
# Submit incorrect form
submit = self.browser.find_element_by_xpath("//input[@type='submit']")
submit.click()
# # Restablish error fields
# password1 = self.browser.find_element_by_id('id_password1')
# password2 = self.browser.find_element_by_id('id_password2')
# Restablish error fields
password1 = self.browser.find_element_by_id('id_password1')
password2 = self.browser.find_element_by_id('id_password2')
# # 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)
# 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)
# # Passwords should be empty
# self.assertEqual(password1.get_attribute('value'), '')
# self.assertEqual(password2.get_attribute('value'), '')
# Passwords should be empty
self.assertEqual(password1.get_attribute('value'), '')
self.assertEqual(password2.get_attribute('value'), '')
# # Correct error
# password1.send_keys('correcthorsebatterystaple')
# password2.send_keys('correcthorsebatterystaple')
# self.browser.execute_script(
# "return jQuery('#g-recaptcha-response').val('PASSED')")
# Correct error
password1.send_keys('correcthorsebatterystaple')
password2.send_keys('correcthorsebatterystaple')
self.browser.execute_script(
"return jQuery('#g-recaptcha-response').val('PASSED')")
# # Submit again
# password2.send_keys(Keys.ENTER)
# Submit again
password2.send_keys(Keys.ENTER)
# # Check we have a success message
# alert = self.browser.find_element_by_css_selector(
# 'div.alert-success').text
# self.assertIn('register', alert)
# self.assertIn('email', alert)
# Check we have a success message
alert = self.browser.find_element_by_css_selector(
'div.alert-success').text
self.assertIn('register', alert)
self.assertIn('email', alert)
# # Check Email
# self.assertEqual(len(mail.outbox), 1)
# 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)
# self.assertEqual(len(urls), 1)
# Check Email
self.assertEqual(len(mail.outbox), 1)
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)
self.assertEqual(len(urls), 1)
# mail.outbox = [] # empty this for later
mail.outbox = [] # empty this for later
# # Follow link
# self.browser.get(urls[0]) # go to the first link
# Follow link
self.browser.get(urls[0]) # go to the first link
# # Complete registration
# title_text = self.browser.find_element_by_tag_name('h2').text
# self.assertIn('Complete', title_text)
# Complete registration
title_text = self.browser.find_element_by_tag_name('h2').text
self.assertIn('Complete', title_text)
# # Test login
# self.browser.get(self.live_server_url + '/user/login')
# username = self.browser.find_element_by_id('id_username')
# self.assertEqual(username.get_attribute('placeholder'), 'Username')
# password = self.browser.find_element_by_id('id_password')
# self.assertEqual(password.get_attribute('placeholder'), 'Password')
# self.assertEqual(password.get_attribute('type'), 'password')
# Test login
self.browser.get(self.live_server_url + '/user/login')
username = self.browser.find_element_by_id('id_username')
self.assertEqual(username.get_attribute('placeholder'), 'Username')
password = self.browser.find_element_by_id('id_password')
self.assertEqual(password.get_attribute('placeholder'), 'Password')
self.assertEqual(password.get_attribute('type'), 'password')
# username.send_keys('TestUsername')
# password.send_keys('correcthorsebatterystaple')
# self.browser.execute_script(
# "return jQuery('#g-recaptcha-response').val('PASSED')")
# password.send_keys(Keys.ENTER)
username.send_keys('TestUsername')
password.send_keys('correcthorsebatterystaple')
self.browser.execute_script(
"return jQuery('#g-recaptcha-response').val('PASSED')")
password.send_keys(Keys.ENTER)
# # Check we are logged in
# udd = self.browser.find_element_by_class_name('navbar').text
# self.assertIn('Hi John', udd)
# Check we are logged in
udd = self.browser.find_element_by_class_name('navbar').text
self.assertIn('Hi John', udd)
# # Check all the data actually got saved
# profileObject = models.Profile.objects.all()[0]
# self.assertEqual(profileObject.username, 'TestUsername')
# self.assertEqual(profileObject.first_name, 'John')
# self.assertEqual(profileObject.last_name, 'Smith')
# self.assertEqual(profileObject.initials, 'JS')
# self.assertEqual(profileObject.phone, '0123456789')
# self.assertEqual(profileObject.email, 'test@example.com')
# Check all the data actually got saved
profileObject = models.Profile.objects.all()[0]
self.assertEqual(profileObject.username, 'TestUsername')
self.assertEqual(profileObject.first_name, 'John')
self.assertEqual(profileObject.last_name, 'Smith')
self.assertEqual(profileObject.initials, 'JS')
self.assertEqual(profileObject.phone, '0123456789')
self.assertEqual(profileObject.email, 'test@example.com')
# # All is well
# All is well
class EventTest(LiveServerTestCase):

View File

@@ -153,7 +153,6 @@ urlpatterns = patterns('',
url(r'^user/edit/$', login_required(views.ProfileUpdateSelf.as_view()),
name='profile_update_self'),
url(r'^user/reset_api_key$', login_required(views.ResetApiKey.as_view(permanent=False)), name='reset_api_key'),
url(r'^user/unlink_forum$', login_required(views.UnlinkForum.as_view(permanent=False)), name='unlink_forum'),
# ICS Calendar - API key authentication
url(r'^ical/(?P<api_pk>\d+)/(?P<api_key>\w+)/rigs.ics$', api_key_required(ical.CalendarICS()), name="ics_calendar"),

View File

@@ -382,12 +382,3 @@ class ResetApiKey(generic.RedirectView):
self.request.user.save()
return reverse_lazy('profile_detail')
class UnlinkForum(generic.RedirectView):
def get_redirect_url(self, *args, **kwargs):
for link in self.request.user.social_auth.all():
link.delete()
self.request.user.save()
return reverse_lazy('profile_detail')

View File

@@ -12,23 +12,17 @@ django-widget-tweaks==1.3
gunicorn==19.3.0
icalendar==3.9.0
lxml==3.4.4
oauthlib==2.0.0
Pillow==2.8.1
psycopg2==2.6
Pygments==2.0.2
PyJWT==1.4.2
PyPDF2==1.24
python-dateutil==2.4.2
python-openid==2.2.5
python-social-auth==0.2.21
pytz==2015.4
raven==5.8.1
reportlab==3.1.44
requests==2.11.1
requests-oauthlib==0.7.0
selenium==2.53.6
simplejson==3.7.2
six==1.10.0
six==1.9.0
sqlparse==0.1.15
static3==0.6.1
svg2rlg==0.3

View File

@@ -1,5 +1,4 @@
{% extends 'base.html' %}
{% load static from staticfiles %}
{% block title %}Login{% endblock %}
@@ -7,43 +6,5 @@
<div class="text-center">
<h1>R<small>ig</small> I<small>nformation</small> G<small>athering</small> S<small>ystem</small></h1>
</div>
<div class="panel-group">
{% url "social:complete" "discourse" as completeUrl %}
{% if not request.GET.next == completeUrl %}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
Login with TEC Forum
</h4>
</div>
<div id="forumLogin">
<div class="panel-body" style="text-align:center;">
<a class="btn btn-default" href="{% url "social:begin" "discourse" %}?next={{request.GET.next}}">
<h4>Login using</h4>
<img src="{% static "imgs/forum-logo.gif" %}" width=200></img>
</a>
</div>
</div>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
Login with RIGS Credentials
</h4>
</div>
<div class="panel-body">
<div class="panel-body">
{% include 'registration/loginform.html' %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -13,7 +13,7 @@
{% render_field form.password class+="form-control" placeholder=form.password.label %}
</div>
<div class="text-right">
{# <a href="{% url 'registration_register' %}" class="btn">Register</a> #}
<a href="{% url 'registration_register' %}" class="btn">Register</a>
<a href="{% url 'password_reset' %}" class="btn">Forgotten Password</a>
<input type="submit" value="Login" class="btn btn-primary"/>
<input type="hidden" name="next" value="{{ next }}"/>