Commit 55fc78e8 authored by David Haynes's avatar David Haynes

Merge branch 'master' into issue69

parents cd2972ad 0a726ec4
Pipeline #579 passed with stage
in 7 minutes and 17 seconds
go/settings/settings.py
go/settings/secret.py
docker-compose.yml
**/*.pyc
Dockerfile
Vagrantfile
.dockerignore
\ No newline at end of file
FROM python:2.7
ENV PYTHONUNBUFFERED 1
# HEALTHCHECK CMD curl --fail http://localhost:8000/ || exit 1
RUN mkdir /go
WORKDIR /go
ADD requirements.txt /go/
RUN apt-get update
RUN apt-get install git-all -y
RUN apt-get install python2.7-dev -y
RUN apt-get install libsasl2-dev -y
RUN apt-get install libldap2-dev -y
RUN apt-get install netcat -y
RUN apt-get install
RUN pip install -r requirements.txt
ADD . /go/
......@@ -12,6 +12,7 @@ I encourage you to join the #go channel in SRCT's [Slack Group](http://srct.slac
## Package Installation
<legend></legend>
### Prerequisities
First, install python and git on your system.
* Python is the programming language used for Django, the web framework used by Go.
......@@ -50,8 +51,27 @@ Now, on your computer, navigate to the directory in which you want to download t
`$ git clone git@git.gmu.edu:srct/go.git`
### If Using Docker
First, install Docker on your system.
* For macOS go here: https://docs.docker.com/docker-for-mac/
* For windows go here: https://docs.docker.com/docker-for-windows/
* For you specific linux disro go here: https://docs.docker.com/engine/installation/
Additionally if you are not on Mac or Windows you will need to install docker-compose: https://docs.docker.com/compose/install/
Next go to the directory with the docker-compose file in it and run:
`$ docker-compose up`
### Required Packages
If that doesn't work, try:
`$ sudo docker-compose up`
SOMETIMES if this branch is updated you might have to
You should see that the server is running by going to http://localhost:8000 in your browser.
Any changes you make to your local file system will be mirrored in the server.
### If Using Vagrant
Finally, install these packages from the standard repositories:
- VirtualBox
......@@ -60,7 +80,7 @@ Finally, install these packages from the standard repositories:
You should be installing the latest VirtualBox version which as of time of writing is `5.0.24_Ubuntur108355`. You can verify the version number by running `vboxmanage --version`.
- Vagrant
`$ sudo apt-get install vagrant`
......
version: '2'
services:
web:
build: .
restart: always
ports:
- '8000:8000'
command: /bin/bash ./startup.sh -python go/manage.py runserver 0.0.0.0:8000
volumes:
- .:/go
depends_on:
- db
environment:
- debug=True
- host=*
- email_domain=@masonlive.gmu.edu
- cas_url=https://nanderson.me/cas/
- superuser=dhaynes3
# - SECRET_KEY=much-secret
- DB_NAME=go
- DB_USER=go
- DB_PASSWORD=go
- DB_HOST=db
- PIWIK_SITE_ID=
- PIWIK_URL=
- EMAIL_HOST=
- EMAIL_PORT=
- EMAIL_HOST_USER=
- EMAIL_HOST_PASSWORD=
db:
image: mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_DATABASE: go
MYSQL_USER: go
MYSQL_PASSWORD: go
\ No newline at end of file
#!/bin/sh
#!/bin/bash
# Cron job to automatically expire outdated links, put this in cron.hourly
ACTIVATE_PATH=/path/to/virtualenv/activate
MANAGE_PATH=/path/to/go/manage.py
......
......@@ -7,7 +7,7 @@
<!-- Start the HTML page for Go -->
<html>
<!-- -->
<!-- load in our header content for every page -->
<head>
<!-- load in the title block defined on each html page -->
<title>
......@@ -22,6 +22,7 @@
<meta name="author" content="Mason SRCT">
<meta name="robots" content="all">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#006633">
<!-- Load in our icon -->
<link rel="icon" type="image/ico" href="{% static "img/favicon.ico"%}" />
......
......@@ -4,6 +4,56 @@
<!-- load in qr code lib -->
{% load qr_tags %}
<!-- CSS for page -->
<style>
a.share:link {color:#000000;}
a.share:visited {color:#000000;}
a.share:hover {color:#000000;}
a.share {text-decoration:none;}
a.button:link {color:#FFF;}
a.button:visited {color:#FFF;}
a.button:hover {color:#FFF;}
legend {
font-size: inherit;
}
#button-container {
padding-bottom: 4px;
padding-left: 6px;
padding-right: 6px;
padding-top: 4px;
}
#copy-button-{{url.short}} {
border: none;
background-color: #eeeeee;
padding-bottom: 3px;
}
#copy-button-{{url.short}}:focus {
outline: none;
}
#clipboard-icon-{{url.short}} {
font-size: 14px;
}
#link-{{url.short}}:visited {
color: #006633;
}
#link-container-{{url.short}} {
width: 400px;
}
.tooltip-inner {
white-space: nowrap;
max-width: none;
}
</style>
<!-- each link_box is a container of a bunch of elements -->
<div class="container">
......@@ -12,13 +62,13 @@
<!-- what is the address? -->
<h3>Go Address:</h3>
<div id="link-container" class="input-group">
<a id="link" class="form-control" href="{{domain}}{{url.short}}">
<a id="link-{{url.short}}" class="form-control" href="{{domain}}{{url.short}}">
{{domain}}{{url.short}}
</a>
<div id="button-container" class="input-group-addon">
<button id="copy-button" type="button" class="button btn btn-default btn-xs fa" role="button"
data-clipboard-target="#link" title="Copy to Clipboard">
<i id="clipboard-icon" class="fa fa-clipboard fa-1g" aria-hidden="true"></i>
<button id="copy-button-{{url.short}}" type="button" class="button btn btn-default btn-xs fa" role="button"
data-clipboard-target="#link-{{url.short}}" title="Copy to Clipboard">
<i id="clipboard-icon-{{url.short}}" class="fa fa-clipboard fa-1g" aria-hidden="true"></i>
</button>
</div>
</div>
......@@ -45,9 +95,8 @@
<strong>Expires:</strong> {{url.expires|default_if_none:"Never"}}
<br></br>
<!-- delete button -->
<a class="button btn btn-danger btn-sm fa" data-target="#deletionModal" data-toggle="modal">
<!-- Delete Button -->
<a class="button btn btn-danger btn-sm fa" data-target="#deletionModal-{{url.short}}" data-toggle="modal">
<i class="fa fa-trash-o fa-lg"></i> Delete
</a>
......@@ -57,9 +106,8 @@
contribute code, head to git.gmu.edu/srct/go">
<i class="fa fa-cog"></i> Edit
</a>
<!-- define delete modal -->
<div id="deletionModal" class="modal fade" role="dialog" tabindex="-1">
<!--Define Delete Modal-->
<div id="deletionModal-{{url.short}}" class="modal fade" role="dialog" tabindex="-1">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" style="background-color:#f5f5f5; border-radius: 7px">
......@@ -68,7 +116,7 @@
style="font-weight:bold; font-size: 21px !important;">
Are you sure you would like to delete this link?</h4>
<h6 style="font-weight:500; margin-top: 0px; margin-bottom: 0px;">
Deleting a link is permenant and can not be undone!</h6>
Deleting a link is permanent and can not be undone!</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>
......@@ -132,3 +180,22 @@
$('[data-toggle="popover"]').popover(option)
})
</script>
<!-- script for copying text an displaying a tooltip -->
<script>
var clipboard = new Clipboard('#copy-button-{{url.short}}');
$('#copy-button-{{url.short}}').tooltip({
trigger: 'hover',
placement: 'bottom'
});
$('#copy-button-{{url.short}}').on('hidden.bs.tooltip', function () {
$('#copy-button-{{url.short}}').attr('data-original-title', 'Copy to Clipboard');
});
clipboard.on('success', function(e) {
e.clearSelection();
$('#copy-button-{{url.short}}').attr('data-original-title', 'Copied!').tooltip('show');
});
</script>
......@@ -81,7 +81,7 @@ SRCT Go &bull; Welcome
<h3><i class="fa">How do I access Go?</i></h3>
<legend></legend>
<p>
In order to prevent abuse of the URL shortner, access to Go
In order to prevent abuse of the URL shortener, access to Go
is moderated by SRCT administrators. New users will need to fill out
a registration form in order to become an approved user.
<br></br>
......
import os
# Create a new file 'secret.py' and copy these contents into that file
# Please be sure to keep these variables secret in production
# You can generate a secret key from the following link: http://www.miniwebtool.com/django-secret-key-generator/
SECRET_KEY = os.environ['SECRET_KEY']
# Use the values from the database configuration
DB_NAME = os.environ['DB_NAME']
DB_USER = os.environ['DB_USER']
# Remember to use a strong password in production
DB_PASSWORD = os.environ['DB_PASSWORD']
# Often left blank
DB_HOST = os.environ['DB_HOST']
# Set piwik server site id (piwik can track multiple websites)
#PIWIK_SITE_ID = os.environ['PIWIK_SITE_ID']
# Point to the piwik url
#PIWIK_URL = os.environ['PIWIK_URL']
# Email configuration, if necessary
EMAIL_HOST = os.environ['EMAIL_HOST']
EMAIL_PORT = os.environ['EMAIL_PORT']
EMAIL_HOST_USER = os.environ['EMAIL_HOST_USER']
EMAIL_HOST_PASSWORD = os.environ['EMAIL_HOST_PASSWORD']
#Create a new file 'settings.py' and copy these contents into that file
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
# Do not have set True in production
DEBUG = os.environ['debug']
ADMINS = ()
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': secret.DB_NAME,
'USER': secret.DB_USER,
'PASSWORD': secret.DB_PASSWORD,
'HOST': secret.DB_HOST,
'PORT': '3306',
}
}
# The domains this application will be deployed on
# e.g. Which domains this app should listen to requests from.
ALLOWED_HOSTS = [os.environ['host']]
# Peoplefinder API
PF_URL = "http://api.srct.gmu.edu/pf/v1/"
TIME_ZONE = 'America/New_York'
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
USE_I18N = True
USE_L10N = True
USE_TZ = True
MEDIA_URL = '/media/'
MEDIA_ROOT = ''
MEDIAFILES_DIRS = (
os.path.join(BASE_DIR, 'media/'),
)
STATIC_URL = '/static/'
STATIC_ROOT = ''
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
SECRET_KEY = secret.SECRET_KEY
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates')
],
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.request'
],
'loaders': [
'django.template.loaders.app_directories.Loader'
],
'debug': DEBUG
}
}
]
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'settings.urls'
WSGI_APPLICATION = 'settings.wsgi.application'
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'go',
'django.contrib.admin',
'qrcode',
'crispy_forms',
'bootstrap3_datetime',
)
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
LOGIN_URL = '/login'
LOGOUT_URL = '/logout'
LOGIN_REDIRECT_URL = '/'
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
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
AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True # use the user
AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=people,o=gmu.edu"
AUTH_LDAP_GLOBAL_OPTIONS = { # ignore UAC cert.
ldap.OPT_X_TLS: ldap.OPT_X_TLS_DEMAND,
ldap.OPT_X_TLS_REQUIRE_CERT: ldap.OPT_X_TLS_NEVER,
}
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
AUTH_LDAP_ALWAYS_UPDATE_USER = True
elif AUTH_MODE.lower() == 'cas':
CAS_SERVER_URL = os.environ['cas_url']
CAS_LOGOUT_COMPLETELY = True
CAS_PROVIDE_URL_TO_LOGOUT = True
AUTHENTICATION_BACKENDS += (
'cas.backends.CASBackend',
)
CAS_RESPONSE_CALLBACKS = (
'go.cas_callbacks.create_user',
)
INSTALLED_APPS += (
'cas',
)
MIDDLEWARE_CLASSES += (
'cas.middleware.CASMiddleware',
)
# PIWIK_SITE_ID = secret.PIWIK_SITE_ID
# PIWIK_URL = secret.PIWIK_URL
CRISPY_TEMPLATE_PACK = 'bootstrap3'
# Mail settings
EMAIL_HOST = secret.EMAIL_HOST
EMAIL_PORT = secret.EMAIL_PORT
EMAIL_HOST_USER = secret.EMAIL_HOST_USER
EMAIL_HOST_PASSWORD = secret.EMAIL_HOST_PASSWORD
EMAIL_FROM = "example@example.com"
EMAIL_TO = "to@example.com"
# Domain used to email to users. See line 231 in views.py
# ie. in Mason's case '@masonlive.gmu.edu'
EMAIL_DOMAIN = os.environ['email_domain']
# export SECRET_KEY=$(dd if=/dev/urandom count=100 | tr -dc "A-Za-z0-9" | fold -w 60 | head -n1 2>/dev/null)
until nc -z db 3306; do
echo "waiting for database to start..."
sleep 1
done
cp go/settings/settings.docker.py.template go/settings/settings.py
cp go/settings/secret.docker.py.template go/settings/secret.py
export SECRET_KEY=$(dd if=/dev/urandom count=100 | tr -dc "A-Za-z0-9" | fold -w 60 | head -n1 2>/dev/null)
python go/manage.py flush --no-input
python go/manage.py makemigrations
python go/manage.py makemigrations go
python go/manage.py migrate
python go/manage.py createsuperuser --noinput --username=$superuser --email=$superuser$email_domain
python go/manage.py runserver 0.0.0.0:8000
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment