Commit 28a9349e authored by Zac Wood's avatar Zac Wood

Use mysql:5.7 to prevent crash

"Authentication plugin 'caching_sha2_password' cannot be loaded:
/usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared
object file: No such file or directory" error when running mysql:latest
parent 32b99e08
...@@ -11,7 +11,7 @@ variables: ...@@ -11,7 +11,7 @@ variables:
before_script: before_script:
- apt-get update -qy - apt-get update -qy
- apt-get install -y mysql-client libmysqlclient-dev python-mysqldb redis-server - apt-get install -y default-libmysqlclient-dev python-mysqldb redis-server
- pip install -r requirements/ci.txt - pip install -r requirements/ci.txt
- nohup redis-server & - nohup redis-server &
- cd go/ - cd go/
...@@ -35,20 +35,20 @@ before_script: ...@@ -35,20 +35,20 @@ before_script:
- python manage.py migrate - python manage.py migrate
- echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('root', 'root@srct.gmu.edu', 'root') " | python manage.py shell - echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('root', 'root@srct.gmu.edu', 'root') " | python manage.py shell
Go-py2.7: # Go-py2.7:
image: library/python:2.7 # image: library/python:2.7
stage: test # stage: test
script: # script:
- python manage.py test # - python manage.py test
Go-py3.4: # Go-py3.4:
image: library/python:3.4 # image: library/python:3.4
stage: test # stage: test
script: # script:
- python manage.py test # - python manage.py test
Go-py3.5: Go-py3.7:
image: library/python:3.5 image: library/python:3.7
stage: test stage: test
script: script:
- python manage.py test - python manage.py test
...@@ -61,9 +61,10 @@ Go-py3.5: ...@@ -61,9 +61,10 @@ Go-py3.5:
# - coverage run --source=go --omit=*migrations/*,*admin.py,*manage.py,*wsgi.py,*settings.py,*secret.py,*__init__.py,*.pyc,*templates/*,*static/* manage.py test # - coverage run --source=go --omit=*migrations/*,*admin.py,*manage.py,*wsgi.py,*settings.py,*secret.py,*__init__.py,*.pyc,*templates/*,*static/* manage.py test
# - coverage html -i && grep pc_cov htmlcov/index.html | egrep -o "[0-9]+\%" | awk '{ print "covered " $1;}' # - coverage html -i && grep pc_cov htmlcov/index.html | egrep -o "[0-9]+\%" | awk '{ print "covered " $1;}'
Go-flake8: Go-flake8:
image: library/python:3.5 image: library/python:3.7
stage: lint stage: lint
script: script:
- pip install flake8 - pip install flake8
- flake8 go/ --statistics --exit-zero - flake8 go/ --statistics --exit-zero
\ No newline at end of file
version: '2' version: '3.7'
services: services:
web: web:
build: . build: .
...@@ -13,7 +13,7 @@ services: ...@@ -13,7 +13,7 @@ services:
environment: environment:
- GO_ALLOWED_HOSTS=* - GO_ALLOWED_HOSTS=*
- GO_EMAIL_DOMAIN=@masonlive.gmu.edu - GO_EMAIL_DOMAIN=@masonlive.gmu.edu
- GO_CAS_URL=https://cas.srct.gmu.edu/ - GO_CAS_URL=https://login.gmu.edu/
- GO_DB_NAME=go - GO_DB_NAME=go
- GO_DB_USER=go - GO_DB_USER=go
- GO_DB_PASSWORD=go - GO_DB_PASSWORD=go
...@@ -25,10 +25,11 @@ services: ...@@ -25,10 +25,11 @@ services:
- GO_EMAIL_HOST_PASSWORD= - GO_EMAIL_HOST_PASSWORD=
- GO_EMAIL_FROM= - GO_EMAIL_FROM=
- GO_EMAIL_TO= - GO_EMAIL_TO=
- superuser=dhaynes3 - GO_SECRET_KEY=spookyspecret
- superuser=zwood2
db: db:
image: mysql image: mysql:5.7
environment: environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_DATABASE: go MYSQL_DATABASE: go
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
go/admin.py go/admin.py
""" """
# Future Imports
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Django Imports # Django Imports
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.admin import UserAdmin from django.contrib.auth.admin import UserAdmin
......
...@@ -2,85 +2,13 @@ ...@@ -2,85 +2,13 @@
go/cas_callbacks.py go/cas_callbacks.py
""" """
# Future Imports
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Django Imports # Django Imports
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
# Other Imports
import requests
def pfparse(pf_name_result):
"""
Parse what peoplefinder sends back to us and make a list out of it
"""
# name comes in format of Anderson, Nicholas J
name_list = pf_name_result.split(',')
# there's random whitespace with the first name
first_name_section = name_list[1].strip()
# check if there's a middle initial
mi_q = first_name_section.split(' ')
# make sure that the additional elements aren't multiple names
if len(mi_q[-1]) == 1:
first_name = ' '.join(mi_q[:-1])
else:
first_name = first_name_section
# our list containing the name of the person in a usable list
new_name_list = [first_name, name_list[0]]
return new_name_list
def pfinfo(uname):
"""
Get information from peoplefinder
"""
base_url = settings.PF_URL
url = base_url + "basic/all/" + str(uname)
try:
metadata = requests.get(url, timeout=5)
print("Retrieving information from the peoplefinder api.")
metadata.raise_for_status()
except requests.exceptions.RequestException as ex:
print("Cannot resolve to peoplefinder api:", ex)
print("Returning empty user info tuple.")
return ['', '']
else:
pfjson = metadata.json()
try:
if len(pfjson['results']) == 1:
if pfjson['method'] == 'peoplefinder':
name_str = pfjson['results'][0]['name']
name = pfparse(name_str)
elif pfjson['method'] == 'ldap':
name = [pfjson['results'][0]['givenname'], pfjson['results'][0]['surname']]
else:
name = pfjson['results'][0]['name']
return name
else:
if pfjson['method'] == 'peoplefinder':
name_str = pfjson['results'][1]['name']
name = pfparse(name_str)
elif pfjson['method'] == 'ldap':
name = [pfjson['results'][1]['givenname'], pfjson['results'][1]['surname']]
else:
name = pfjson['results'][0]['name']
return name
# if the name is not in peoplefinder, return empty first and last name
except IndexError as ex:
print("Name not found in peoplefinder.")
return ['', '']
except Exception as ex:
print("Unknown peoplefinder error:", ex)
print("Returning empty user info tuple.")
return ['', '']
def create_user(tree): def create_user(tree):
""" """
Create a django user based off of the peoplefinder info we parsed earlier Create a django user based off of the CAS info
""" """
print("Parsing CAS information.") print("Parsing CAS information.")
...@@ -90,9 +18,6 @@ def create_user(tree): ...@@ -90,9 +18,6 @@ def create_user(tree):
except Exception as ex: except Exception as ex:
print("CAS callback unsuccessful:", ex) print("CAS callback unsuccessful:", ex)
# error handling in pfinfo function
info_name = pfinfo(username)
try: try:
if user_created: if user_created:
print("Created user object %s." % username) print("Created user object %s." % username)
...@@ -106,11 +31,7 @@ def create_user(tree): ...@@ -106,11 +31,7 @@ def create_user(tree):
user.save() user.save()
print("Added user's email, %s." % email_str) print("Added user's email, %s." % email_str)
user.first_name = info_name[0]
user.last_name = info_name[1]
user.save() user.save()
print("Added user's name, %s %s." % (info_name[0], info_name[1]))
print("User object creation process completed.") print("User object creation process completed.")
else: else:
......
""" """
go/forms.py go/forms.py
""" """
# Future Imports
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Python stdlib Imports # Python stdlib Imports
from datetime import datetime, timedelta from datetime import datetime, timedelta
...@@ -20,7 +17,7 @@ from django.utils.safestring import mark_safe ...@@ -20,7 +17,7 @@ from django.utils.safestring import mark_safe
from .models import URL, RegisteredUser from .models import URL, RegisteredUser
# Other Imports # Other Imports
from bootstrap3_datetime.widgets import DateTimePicker # from bootstrap3_datetime.widgets import DateTimePicker
from crispy_forms.bootstrap import (Accordion, AccordionGroup, PrependedText, from crispy_forms.bootstrap import (Accordion, AccordionGroup, PrependedText,
StrictButton) StrictButton)
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
...@@ -94,7 +91,7 @@ class URLForm(ModelForm): ...@@ -94,7 +91,7 @@ class URLForm(ModelForm):
DAY = '1 Day' DAY = '1 Day'
WEEK = '1 Week' WEEK = '1 Week'
MONTH = '1 Month' MONTH = '1 Month'
CUSTOM = 'Custom Date' # CUSTOM = 'Custom Date'
NEVER = 'Never' NEVER = 'Never'
# Define a tuple of string date standards to be used as our date choices # Define a tuple of string date standards to be used as our date choices
...@@ -103,7 +100,7 @@ class URLForm(ModelForm): ...@@ -103,7 +100,7 @@ class URLForm(ModelForm):
(WEEK, WEEK), (WEEK, WEEK),
(MONTH, MONTH), (MONTH, MONTH),
(NEVER, NEVER), (NEVER, NEVER),
(CUSTOM, CUSTOM), # (CUSTOM, CUSTOM),
) )
# Add preset expiration choices. # Add preset expiration choices.
...@@ -129,22 +126,22 @@ class URLForm(ModelForm): ...@@ -129,22 +126,22 @@ class URLForm(ModelForm):
# Add a custom expiration choice. # Add a custom expiration choice.
expires_custom = DateTimeField( # expires_custom = DateTimeField(
required=False, # required=False,
label='Custom Date', # label='Custom Date',
input_formats=['%m-%d-%Y'], # input_formats=['%m-%d-%Y'],
validators=[valid_date], # validators=[valid_date],
initial=lambda: datetime.now() + timedelta(days=1), # initial=lambda: datetime.now() + timedelta(days=1),
widget=DateTimePicker( # widget=DateTimePicker(
options={ # options={
"format": "MM-DD-YYYY", # "format": "MM-DD-YYYY",
"pickTime": False, # "pickTime": False,
}, # },
icon_attrs={ # icon_attrs={
"class": "fa fa-calendar", # "class": "fa fa-calendar",
}, # },
) # )
) # )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
go/commands/expirelinks.py go/commands/expirelinks.py
""" """
# Future Imports
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Django Imports # Django Imports
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.utils import timezone from django.utils import timezone
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
go/commands/test_expirelinks.py go/commands/test_expirelinks.py
""" """
# Future Imports
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Python stdlib Imports # Python stdlib Imports
from datetime import timedelta from datetime import timedelta
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
go/models.py go/models.py
""" """
# Future Imports
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Python stdlib Imports # Python stdlib Imports
import string import string
...@@ -16,7 +12,8 @@ from django.db import models ...@@ -16,7 +12,8 @@ from django.db import models
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible from django.conf import settings
from django.core.mail import EmailMessage, send_mail
# Other Imports # Other Imports
from hashids import Hashids # http://hashids.org/python/ from hashids import Hashids # http://hashids.org/python/
...@@ -26,7 +23,6 @@ HASHIDS = Hashids( ...@@ -26,7 +23,6 @@ HASHIDS = Hashids(
salt="srct.gmu.edu", alphabet=(string.ascii_lowercase + string.digits) salt="srct.gmu.edu", alphabet=(string.ascii_lowercase + string.digits)
) )
@python_2_unicode_compatible
class RegisteredUser(models.Model): class RegisteredUser(models.Model):
""" """
This is simply a wrapper model for the user object which, if an object This is simply a wrapper model for the user object which, if an object
...@@ -34,7 +30,7 @@ class RegisteredUser(models.Model): ...@@ -34,7 +30,7 @@ class RegisteredUser(models.Model):
""" """
# Let's associate a User to this RegisteredUser # Let's associate a User to this RegisteredUser
user = models.OneToOneField(User) user = models.OneToOneField(User, on_delete=models.CASCADE)
# What is your name? # What is your name?
full_name = models.CharField( full_name = models.CharField(
...@@ -52,10 +48,10 @@ class RegisteredUser(models.Model): ...@@ -52,10 +48,10 @@ class RegisteredUser(models.Model):
description = models.TextField(blank=True) description = models.TextField(blank=True)
# Have you filled out the registration form? # Have you filled out the registration form?
registered = models.BooleanField(default=False) registered = models.BooleanField(default=True)
# Are you approved to use Go? # Are you approved to use Go?
approved = models.BooleanField(default=False) approved = models.BooleanField(default=True)
# Is this User Blocked? # Is this User Blocked?
blocked = models.BooleanField(default=False) blocked = models.BooleanField(default=False)
...@@ -79,9 +75,25 @@ def handle_regUser_creation(sender, instance, created, **kwargs): ...@@ -79,9 +75,25 @@ def handle_regUser_creation(sender, instance, created, **kwargs):
if created: if created:
RegisteredUser.objects.create(user=instance) RegisteredUser.objects.create(user=instance)
# Don't send mail for now
#
# user_mail = instance.username + settings.EMAIL_DOMAIN
# send_mail(
# 'We have received your Go application!',
# ######################
# 'Hey there %s,\n\n'
# 'The Go admins have received your application and are '
# 'currently in the process of reviewing it.\n\n'
# 'You will receive another email when you have been '
# 'approved.\n\n'
# '- Go Admins'
# % (str(instance.username)),
# ######################
# settings.EMAIL_FROM,
# [user_mail]
# )
@python_2_unicode_compatible
class URL(models.Model): class URL(models.Model):
""" """
This model represents a stored URL redirection rule. Each URL has an This model represents a stored URL redirection rule. Each URL has an
...@@ -90,7 +102,7 @@ class URL(models.Model): ...@@ -90,7 +102,7 @@ class URL(models.Model):
""" """
# Who is the owner of this Go link # Who is the owner of this Go link
owner = models.ForeignKey(RegisteredUser) owner = models.ForeignKey(RegisteredUser, on_delete=models.CASCADE)
# When was this link created? # When was this link created?
date_created = models.DateTimeField(default=timezone.now) date_created = models.DateTimeField(default=timezone.now)
...@@ -133,11 +145,17 @@ class URL(models.Model): ...@@ -133,11 +145,17 @@ class URL(models.Model):
should be updated to be simpler should be updated to be simpler
""" """
if cache.get("hashids_counter") is None: if cache.get("hashids_counter") is None:
print(URL.objects.count())
cache.set("hashids_counter", URL.objects.count()) cache.set("hashids_counter", URL.objects.count())
print(cache.get("hashids_counter"))
tries = 1 tries = 1
while tries < 100: while tries < 100:
try: try:
short = HASHIDS.encrypt(cache.get("hashids_counter")) counter = cache.get("hashids_counter")
if counter is None:
short = HASHIDS.encrypt(0)
else:
short = HASHIDS.encrypt(counter)
tries += 1 tries += 1
cache.incr("hashids_counter") cache.incr("hashids_counter")
URL.objects.get(short__iexact=short) URL.objects.get(short__iexact=short)
......
...@@ -25,126 +25,7 @@ ...@@ -25,126 +25,7 @@
</div> </div>
</div> </div>
<!-- Table 1 --> <!-- Table 1 -->
<!-- define the div where we can select users from a table to judge them -->
<div class="row">
<div class="col-md-12">
<input class="inputfilter" type="text" id="appliedInput"
placeholder="Search Usernames or Full Names">
<h3>Users awaiting moderation</h3>
<form method="post" action="useradmin">
<!-- csrf protection -->
{% csrf_token %}
<!-- define out table of users that need approval -->
<table class="table table-striped table-hover" id="appliedTable">
<!-- define the header row -->
<thead>
<tr>
<th>Selected</th>
<th>Username</th>
<th>Full Name</th>
<th>Description</th>
</tr>
</thead>
<!-- define the body rows -->
<tbody>
<!-- loop through all users in the need_approval list -->
{% for unapproved in need_approval %}
<!-- ..and make a new row for each user -->
<tr>
<td><input type="checkbox" name="username" value={{ unapproved.user }}></td>
<td>{{ unapproved.user }}</td>
<td>{{ unapproved.full_name }}</td>
<td>{{ unapproved.description|default:"No description provided" }}</td>
</tr>
<!-- unless it's empty in which case we show nothing -->
{% empty %}
<tr>
<td>none</td>
<td>none</td>
<td>none</td>
<td>none</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- a div containing our form submission buttons -->
<div class="form-group">
<!-- the modal for approve doesn't work-->
<a class="btn btn-primary btn-sm" data-target="#approveModal" data-toggle="modal"> Approve </a>
<!-- input type="submit" name="_approve" value="Approve" class="btn btn-primary btn-sm"-->
<a class="btn btn-danger btn-sm" data-target="#denyModal" data-toggle="modal"> Deny </a>
<a class="btn btn-default btn-sm btn-blockUsr" data-target="#blockModal" data-toggle="modal"
style="background-color: black; color: white;"> Block </a>
<!--Define Approve Modal-->
<div id="approveModal" class="modal fade" role="dialog" tabindex="-1">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" style="background-color:#f5f5f5; border-radius: 7px">
<div class="modal-header" style="text-align:center;">
<h4 class="modal-title text-center" style="font-weight:bold; font-size: 21px !important;">
Are you sure you would like to approve a user?</h4>
</div>
<div class="modal-body" style="padding-bottom: 80px">
<a type="button" class="btn btn-success btn-lg" style="border-width: 0px;float:left; width:49%; background-color: #A9B0AD; color: #ffffff; border-radius: 4px;"
data-dismiss="modal">Cancel</a>
<input type="submit" name="_approve" value="Approve" class="btn btn-primary btn-lg"
style="border-width: 0px;float:right; width:49%; background-color: #00331a; color: #ffffff; border-radius: 4px;">
</div>
</div>
</div>
</div>
<!--Define Deny Modal-->
<div id="denyModal" class="modal fade" role="dialog" tabindex="-1">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" style="background-color:#f5f5f5; border-radius: 7px">
<div class="modal-header" style="text-align:center;">
<h4 class="modal-title text-center" style="font-weight:bold; font-size: 21px !important;">
Are you sure you would like to deny a user?</h4>
<h6 style="font-weight:500; margin-top: 0px; margin-bottom: 0px;">
Please remember the user's feelings</h6>
</div>
<div class="modal-body" style="padding-bottom: 80px">
<a type="button" class="btn btn-success btn-lg" style="border-width: 0px;float:left; width:49%; background-color: #A9B0AD; color: #ffffff; border-radius: 4px;"
data-dismiss="modal">Cancel</a>
<input type="submit" name="_deny" value="Deny" class="btn btn-danger btn-lg" style="border-width: 0px;float:right; width:49%; background-color: #ac1d37; color: #ffffff; border-radius: 4px;">
</div>
</div>
</div>
</div>
<!--Define Block Modal-->
<!-- Note there is another block modal for the other block button below -->
<div id="blockModal" class="modal fade" role="dialog" tabindex="-1">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" style="background-color:#f5f5f5; border-radius: 7px">
<div class="modal-header" style="text-align:center;">
<h4 class="modal-title text-center" style="font-weight:bold; font-size: 21px !important;">
Are you sure you would like to block a user?</h4>
<h6 style="font-weight:500; margin-top: 0px; margin-bottom: 0px;">
Please remember the user's feelings</h6>
</div>
<div class="modal-body" style="padding-bottom: 80px">
<a type="button" class="btn btn-success btn-lg" style="border-width: 0px;float:left; width:49%; background-color: #A9B0AD; color: #ffffff; border-radius: 4px;"
data-dismiss="modal">Cancel</a>
<input type="submit" name="_block" value="Block" class="btn btn-danger btn-lg" style="border-width: 0px; float:right; width:49%;background-color: #000000; color: #ffffff; border-radius: 4px;">
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>