Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SRCT
go
Commits
b5c4a124
Commit
b5c4a124
authored
Feb 14, 2017
by
David Haynes
Browse files
Merge branch '2.2-dev' into 119-search-bar
parents
4b408072
cd3fbef5
Pipeline
#887
passed with stage
in 58 seconds
Changes
24
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
b5c4a124
...
...
@@ -14,3 +14,4 @@ venv
.coverage
htmlcov/
.idea
__pycache__/
.gitlab-ci.yml
View file @
b5c4a124
...
...
@@ -10,8 +10,8 @@ variables:
before_script
:
-
apt-get update -qy
-
apt-get install -y
libldap2-dev libsasl2-dev
mysql-client libmysqlclient-dev python-mysqldb
-
pip install -r requirements.txt
-
apt-get install -y mysql-client libmysqlclient-dev python-mysqldb
-
pip install -r requirements
/ci
.txt
-
cd go/
-
cp settings/settings.py.template settings/settings.py
-
cp settings/secret.py.template settings/secret.py
...
...
@@ -31,12 +31,23 @@ Go-py2.7:
image
:
library/python:2.7
type
:
test
script
:
-
python manage.py test
-
python manage.py test
Go-py3.4
:
image
:
library/python:3.4
type
:
test
script
:
-
python manage.py test
Go-py3.5
:
image
:
library/python:3.5
type
:
test
script
:
-
python manage.py test
Go-py3.6
:
image
:
library/python:3.6
type
:
test
script
:
-
pip install coverage
-
coverage run --source=go --omit=*migrations/* 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;}'
Dockerfile
View file @
b5c4a124
...
...
@@ -2,12 +2,10 @@ FROM python:3.6
ENV
PYTHONUNBUFFERED 1
RUN
apt-get update
RUN
apt-get
install
libsasl2-dev
-y
RUN
apt-get
install
libldap2-dev
-y
RUN
apt-get
install
netcat
-y
RUN
mkdir
/go
WORKDIR
/go
ADD
requirements
.txt
/go/
RUN
pip
install
-r
requirements
.txt
ADD
/
requirements
/
/go/
RUN
pip
install
-r
base
.txt
ADD
. /go/
go/go/management/commands/test_expirelinks.py
0 → 100644
View file @
b5c4a124
# Future Imports
from
__future__
import
unicode_literals
,
absolute_import
,
print_function
,
division
# Django Imports
from
django.test
import
TestCase
# App Imports
from
.expirelinks
import
*
"""
Test cases for the functions in expirelinks
"""
class
ExpireLinksTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
go/go/templates/403.html
0 → 100644
View file @
b5c4a124
<!-- include the base html template -->
{% extends 'layouts/base.html' %}
<!-- define the page title block -->
{% block title %}
403 Error
•
Forbidden
{% endblock %}
<!-- define the content block for the page -->
{% block content %}
<!-- Tell Django to load static files -->
{% load staticfiles %}
<!-- div that contains the 404 page content -->
<div
class=
"row"
>
<div
class=
"col-md-10 col-md-offset-1 text-center"
>
<h1>
403 Error - Forbidden
</h1>
<h3>
You are not permitted to access this page, or you have exceeded the maximum limit of submitted links.
</h3>
<h3>
Click
<a
href=
"{% url 'index' %}"
>
here
</a>
to return to the home page.
</h3>
<img
id=
"squirrels"
src=
"{% static "
img
/
acorn.png
"
%}"
>
<a
href=
"/"
><img
src=
"{% static "
img
/
acorn.png
"
%}"
style=
"width:10vw;"
></a>
</div>
</div>
{% endblock %}
go/go/templatetags/go_extras.py
View file @
b5c4a124
...
...
@@ -13,29 +13,39 @@ from go.models import RegisteredUser
register
=
template
.
Library
()
"""
check if a user is registered
Helper template function to check if a user is registered.
givenUser: The User object that we are checking to see if they are registered
or not.
"""
@
register
.
filter
def
is_registered
(
u
ser
):
def
is_registered
(
givenU
ser
):
# try getting the RegisteredUser of the current user
try
:
r
egistered
=
RegisteredUser
.
objects
.
get
(
user
name
=
user
.
username
)
getR
egistered
User
=
RegisteredUser
.
objects
.
get
(
user
=
givenUser
)
# if it works then the user is registered
return
True
return
getRegisteredUser
.
registered
# This should never happen
except
RegisteredUser
.
DoesNotExist
as
ex
:
print
(
ex
)
# if they don't exist then they are not registered
return
False
"""
check if a user is approved
Helper template function to check if a user is approved.
givenUser: The User object that we are checking to see if they are approved
or not.
"""
@
register
.
filter
def
is_approved
(
u
ser
):
def
is_approved
(
givenU
ser
):
# try getting the RegisteredUser of the current user
try
:
r
egistered
=
RegisteredUser
.
objects
.
get
(
user
name
=
user
.
username
)
getR
egistered
User
=
RegisteredUser
.
objects
.
get
(
user
=
givenUser
)
# if they exist, return whether or not they are approved (boolean)
return
registered
.
approved
return
getRegisteredUser
.
approved
# This should never happen
except
RegisteredUser
.
DoesNotExist
as
ex
:
print
(
ex
)
# if they don't exist then they are not approved
return
False
go/go/templatetags/test_go_extras.py
0 → 100644
View file @
b5c4a124
# Future Imports
from
__future__
import
unicode_literals
,
absolute_import
,
print_function
,
division
# Django Imports
from
django.test
import
TestCase
from
django.contrib.auth.models
import
User
# App Imports
from
.go_extras
import
is_registered
,
is_approved
from
go.models
import
RegisteredUser
"""
Test cases for the template helper functions in go_extras.py
"""
class
GoExtrasTest
(
TestCase
):
"""
Create a dummy user to be tested against.
"""
def
setUp
(
self
):
User
.
objects
.
create
(
username
=
'dhaynes'
,
password
=
'password'
)
"""
Test the is_registered function to see if it gives correct false answers
"""
def
test_is_registeredFalse
(
self
):
getUser
=
User
.
objects
.
get
(
username
=
'dhaynes'
)
getRegisteredUser
=
RegisteredUser
.
objects
.
get
(
user
=
getUser
)
getRegisteredUser
.
registered
=
False
getRegisteredUser
.
save
()
self
.
assertFalse
(
is_registered
(
getUser
))
"""
Test the is_registered function to see if it gives correct true answers
"""
def
test_is_registeredTrue
(
self
):
getUser
=
User
.
objects
.
get
(
username
=
'dhaynes'
)
getRegisteredUser
=
RegisteredUser
.
objects
.
get
(
user
=
getUser
)
getRegisteredUser
.
registered
=
True
getRegisteredUser
.
save
()
self
.
assertTrue
(
is_registered
(
getUser
))
"""
Test the is_registered function to see if it gives correct false answers
"""
def
test_is_approvedFalse
(
self
):
getUser
=
User
.
objects
.
get
(
username
=
'dhaynes'
)
getRegisteredUser
=
RegisteredUser
.
objects
.
get
(
user
=
getUser
)
getRegisteredUser
.
approved
=
False
getRegisteredUser
.
save
()
self
.
assertFalse
(
is_approved
(
getUser
))
"""
Test the is_registered function to see if it gives correct true answers
"""
def
test_is_approvedTrue
(
self
):
getUser
=
User
.
objects
.
get
(
username
=
'dhaynes'
)
getRegisteredUser
=
RegisteredUser
.
objects
.
get
(
user
=
getUser
)
getRegisteredUser
.
approved
=
False
getRegisteredUser
.
save
()
self
.
assertFalse
(
is_approved
(
getUser
))
go/go/test_cas_callbacks.py
0 → 100644
View file @
b5c4a124
# Future Imports
from
__future__
import
unicode_literals
,
absolute_import
,
print_function
,
division
# Django Imports
from
django.test
import
TestCase
# App Imports
from
go.cas_callbacks
import
pfparse
,
pfinfo
,
create_user
"""
Test cases for the functions in call_callbacks.
"""
class
CasCallbacksTest
(
TestCase
):
"""
Presently enrolled student who has been added to peoplefinder
"""
def
test_pf_peoplefinder_method
(
self
):
actual
=
pfinfo
(
'dhaynes3'
)
expected
=
[
'David'
,
'Haynes'
]
self
.
assertEqual
(
expected
,
actual
)
"""
Test the parsing method to ensure that first and last names are seperated
accordingly and correctly.
"""
def
test_pfparse_peoplefinder_method
(
self
):
actual
=
pfparse
(
"Haynes, David M"
)
expected
=
[
'David'
,
'Haynes'
]
self
.
assertEqual
(
expected
,
actual
)
"""
student no longer in peoplefinder, or who hasn't yet been added
"""
def
test_pfinfo_ldap_method
(
self
):
actual
=
pfinfo
(
'lfaraone'
)
expected
=
[
'Luke W'
,
'Faraone'
]
self
.
assertEqual
(
expected
,
actual
)
"""
student employees will have their staff info return before their student info
"""
def
test_pfinfo_employee_method
(
self
):
actual
=
pfinfo
(
'nander13'
)
expected
=
[
'Nicholas'
,
'Anderson'
]
self
.
assertEqual
(
expected
,
actual
)
"""
a name not found for either (should never happen, but gracefully handle anyway)
"""
def
test_pfinfo_dne
(
self
):
actual
=
pfinfo
(
'bobama'
)
expected
=
[
''
,
''
]
self
.
assertEqual
(
expected
,
actual
)
go/go/test_forms.py
0 → 100644
View file @
b5c4a124
# Future Imports
from
__future__
import
unicode_literals
,
absolute_import
,
print_function
,
division
# Django Imports
from
django.test
import
TestCase
# App Imports
from
go.forms
import
*
"""
Test cases for the URL form
"""
class
URLFormTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the Signup form
"""
class
SignupForm
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
go/go/test_models.py
View file @
b5c4a124
...
...
@@ -8,19 +8,17 @@ from django.contrib.auth.models import User
# App Imports
from
go.models
import
URL
,
RegisteredUser
"""
Test cases for the URL Model
"""
class
URLTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the RegisteredUser Model
- check if RegisteredUsers are actually made
- check approval and registration status flipping
- check blocking
- check printing
- add in description
- check organization field
- check full name field
- check print(RegisteredUser)
"""
class
RegisteredUserTest
(
TestCase
):
...
...
@@ -31,3 +29,23 @@ class RegisteredUserTest(TestCase):
getUser
=
User
.
objects
.
get
(
username
=
'dhaynes'
)
getRegisteredUser
=
RegisteredUser
.
objects
.
get
(
user
=
getUser
)
self
.
assertTrue
(
getRegisteredUser
)
def
test_checkPrint
(
self
):
# expected = '<Registered User: %s - Approval Status: %s>' % (self.user, self.approved)
self
.
assertTrue
(
True
)
"""
Test cases for the URL Model
- check if URL's are actually created
- modify clicks (social, qr, normal)
- check expiration date creation
- check print function
"""
class
URLTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
go/go/test_views.py
0 → 100644
View file @
b5c4a124
# Future Imports
from
__future__
import
unicode_literals
,
absolute_import
,
print_function
,
division
# Django Imports
from
django.test
import
TestCase
# App Imports
from
go.views
import
*
"""
Test cases for the index view
"""
class
IndexTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the "view" view
"""
class
ViewTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the my_links view
"""
class
MyLinksTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the delete view
"""
class
DeleteTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the signup view
"""
class
SignupTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the redirection view
"""
class
RedirectionTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
"""
Test cases for the useradmin view
"""
class
UserAdminTest
(
TestCase
):
"""
Default test case, does not actually test anything
"""
def
test_Django_Test
(
self
):
self
.
assertEqual
(
"Hello World!"
,
"Hello World!"
)
go/go/views.py
View file @
b5c4a124
...
...
@@ -12,6 +12,7 @@ from django.contrib.auth import REDIRECT_FIELD_NAME
from
django.contrib.auth.models
import
User
from
django.contrib.auth.decorators
import
user_passes_test
,
login_required
from
django.shortcuts
import
render
,
get_object_or_404
,
redirect
from
ratelimit.decorators
import
ratelimit
# App Imports
from
go.models
import
URL
,
RegisteredUser
...
...
@@ -46,61 +47,7 @@ def index(request):
# If a POST request is received, then the user has submitted a form and it's
# time to parse the form and create a new URL object
if
request
.
method
==
'POST'
:
# Now we initialize the form again but this time we have the POST
# request
url_form
=
URLForm
(
request
.
POST
,
host
=
request
.
META
.
get
(
'HTTP_HOST'
))
# Django will check the form to make sure it's valid
if
url_form
.
is_valid
():
# We don't commit the url object yet because we need to add its
# owner, and parse its date field.
url
=
url_form
.
save
(
commit
=
False
)
url
.
owner
=
request
.
user
.
registereduser
# If the user entered a short url, it's already been validated,
# so accept it. If they did not, however, then generate a
# random one and use that instead.
short
=
url_form
.
cleaned_data
.
get
(
'short'
).
strip
()
# Check if a short URL was entered
if
len
(
short
)
>
0
:
url
.
short
=
short
else
:
# If the user didn't enter a short url, generate a random
# one. However, if a random one can't be generated, return
# a 500 server error.
random_short
=
URL
.
generate_valid_short
()
if
random_short
is
None
:
return
HttpResponseServerError
(
render
(
request
,
'admin/500.html'
,
{})
)
else
:
url
.
short
=
random_short
# Grab the expiration field value. It's currently an unsable
# string value, so we need to parse it into a datetime object
# relative to right now.
expires
=
url_form
.
cleaned_data
.
get
(
'expires'
)
# Determine what the expiration date is
if
expires
==
URLForm
.
DAY
:
url
.
expires
=
timezone
.
now
()
+
timedelta
(
days
=
1
)
elif
expires
==
URLForm
.
WEEK
:
url
.
expires
=
timezone
.
now
()
+
timedelta
(
weeks
=
1
)
elif
expires
==
URLForm
.
MONTH
:
url
.
expires
=
timezone
.
now
()
+
timedelta
(
weeks
=
3
)
elif
expires
==
URLForm
.
CUSTOM
:
url
.
expires
=
url_form
.
cleaned_data
.
get
(
'expires_custom'
)
else
:
pass
# leave the field NULL
# Make sure that our new URL object is clean, then save it and
# let's redirect to view this baby.
url
.
full_clean
()
url
.
save
()
return
redirect
(
'view'
,
url
.
short
)
return
redirect
(
'view'
,
post
(
request
).
short
)
# Render index.html passing the form to the template
return
render
(
request
,
'core/index.html'
,
{
...
...
@@ -108,6 +55,65 @@ def index(request):
},
)
#rate limits are completely arbitrary
@
ratelimit
(
key
=
'user'
,
rate
=
'3/m'
,
method
=
'POST'
,
block
=
True
)
@
ratelimit
(
key
=
'user'
,
rate
=
'25/d'
,
method
=
'POST'
,
block
=
True
)
def
post
(
request
):
# Now we initialize the form again but this time we have the POST
# request
url_form
=
URLForm
(
request
.
POST
,
host
=
request
.
META
.
get
(
'HTTP_HOST'
))
# Django will check the form to make sure it's valid
if
url_form
.
is_valid
():
# We don't commit the url object yet because we need to add its
# owner, and parse its date field.
url
=
url_form
.
save
(
commit
=
False
)
url
.
owner
=
request
.
user
.
registereduser
# If the user entered a short url, it's already been validated,
# so accept it. If they did not, however, then generate a
# random one and use that instead.
short
=
url_form
.
cleaned_data
.
get
(
'short'
).
strip
()
# Check if a short URL was entered
if
len
(
short
)
>
0
:
url
.
short
=
short
else
:
# If the user didn't enter a short url, generate a random
# one. However, if a random one can't be generated, return
# a 500 server error.
random_short
=
URL
.
generate_valid_short
()
if
random_short
is
None
:
return
HttpResponseServerError
(
render
(
request
,
'admin/500.html'
,
{})
)
else
:
url
.
short
=
random_short
# Grab the expiration field value. It's currently an unsable
# string value, so we need to parse it into a datetime object
# relative to right now.
expires
=
url_form
.
cleaned_data
.
get
(
'expires'
)
# Determine what the expiration date is
if
expires
==
URLForm
.
DAY
:
url
.
expires
=
timezone
.
now
()
+
timedelta
(
days
=
1
)
elif
expires
==
URLForm
.
WEEK
:
url
.
expires
=
timezone
.
now
()
+
timedelta
(
weeks
=
1
)
elif
expires
==
URLForm
.
MONTH
:
url
.
expires
=
timezone
.
now
()
+
timedelta
(
weeks
=
3
)
elif
expires
==
URLForm
.
CUSTOM
:
url
.
expires
=
url_form
.
cleaned_data
.
get
(
'expires_custom'
)
else
:
pass
# leave the field NULL
# Make sure that our new URL object is clean, then save it and
# let's redirect to view this baby.
url
.
full_clean
()
url
.
save
()
return
url
"""
This view allows the user to view details about a URL. Note that they
do not need to be logged in to view info.
...
...
@@ -151,7 +157,6 @@ def my_links(request):
},
)
"""
This view deletes a URL if you have the permission to. User must be
logged in and registered, and must also be the owner of the URL.
...
...
go/settings/settings.docker.py.template
View file @
b5c4a124
...
...
@@ -2,8 +2,6 @@
from . import secret
import os
AUTH_MODE = "CAS"
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# DEBUG mode is used to view more details when errors occur
...
...
@@ -137,52 +135,25 @@ AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
CAS_SERVER_URL = os.environ['cas_url']
CAS_LOGOUT_COMPLETELY = True
CAS_PROVIDE_URL_TO_LOGOUT = True
if AUTH_MODE.lower() == 'ldap':
import ldap
AUTHENTICATION_BACKENDS += (
'django_auth_ldap.backend.LDAPBackend',
)
AUTH_LDAP_SERVER_URI = "ldaps://directory.gmu.edu:636" # server url
AUTH_LDAP_BIND_DN = "ou=people,o=gmu.edu" # bind DN