Christian Boltz e4be47
{% set helios = salt['pillar.get']('profile:helios', {}) %}
Christian Boltz e4be47
Christian Boltz e4be47
# a massive hack to see if we're testing, in which case we use different settings
Christian Boltz e4be47
import sys
Christian Boltz 6ac95b
Christian Boltz 6ac95b
import json
Christian Boltz 6ac95b
import os
Christian Boltz 6ac95b
Christian Boltz e4be47
TESTING = 'test' in sys.argv
Christian Boltz e4be47
Christian Boltz e4be47
# go through environment variables and override them
Christian Boltz e4be47
def get_from_env(var, default):
Christian Boltz 6ac95b
    if not TESTING and var in os.environ:
Christian Boltz e4be47
        return os.environ[var]
Christian Boltz e4be47
    else:
Christian Boltz e4be47
        return default
Christian Boltz e4be47
Christian Boltz e4be47
DEBUG = (get_from_env('DEBUG', '1') == '1')
Christian Boltz e4be47
Christian Boltz e4be47
# add admins of the form: 
Christian Boltz e4be47
#    ('Ben Adida', 'ben@adida.net'),
Christian Boltz e4be47
# if you want to be emailed about errors.
Christian Boltz 6ac95b
ADMINS = (get_from_env('ADMIN_NAME', ''), get_from_env('ADMIN_EMAIL', ''))
Christian Boltz e4be47
Christian Boltz e4be47
MANAGERS = ADMINS
Christian Boltz e4be47
Christian Boltz e4be47
# is this the master Helios web site?
Christian Boltz e4be47
MASTER_HELIOS = (get_from_env('MASTER_HELIOS', '0') == '1')
Christian Boltz e4be47
Christian Boltz e4be47
# show ability to log in? (for example, if the site is mostly used by voters)
Christian Boltz e4be47
# if turned off, the admin will need to know to go to /auth/login manually
Christian Boltz e4be47
SHOW_LOGIN_OPTIONS = (get_from_env('SHOW_LOGIN_OPTIONS', '1') == '1')
Christian Boltz e4be47
Christian Boltz e4be47
# sometimes, when the site is not that social, it's not helpful
Christian Boltz e4be47
# to display who created the election
Christian Boltz e4be47
SHOW_USER_INFO = (get_from_env('SHOW_USER_INFO', '1') == '1')
Christian Boltz e4be47
Christian Boltz e4be47
DATABASES = {
Christian Boltz e4be47
    'default': {
Christian Boltz e4be47
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
Christian Boltz 6ac95b
        'CONN_MAX_AGE': 600,
Christian Boltz e4be47
        'NAME': '{{ helios.database_name }}',
Christian Boltz e4be47
        'HOST': '{{ helios.database_host }}',
Christian Boltz e4be47
        'USER': '{{ helios.database_user }}',
Christian Boltz e4be47
        'PASSWORD': '{{ salt['pillar.get']('postgres:users:helios:password') }}',
Christian Boltz 6ac95b
        {% if helios.database_sslmode %}
Christian Boltz dfcb3e
        'OPTIONS': {
Christian Boltz dfcb3e
            'sslmode': 'require',
Christian Boltz dfcb3e
        }
Christian Boltz 6ac95b
        {% endif %}
Christian Boltz e4be47
    }
Christian Boltz e4be47
}
Christian Boltz e4be47
Christian Boltz e4be47
# override if we have an env variable
Christian Boltz e4be47
if get_from_env('DATABASE_URL', None):
Christian Boltz e4be47
    import dj_database_url
Christian Boltz 6ac95b
    DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)
Christian Boltz e4be47
    DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
Christian Boltz e4be47
Christian Boltz e4be47
# Local time zone for this installation. Choices can be found here:
Christian Boltz e4be47
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
Christian Boltz e4be47
# although not all choices may be available on all operating systems.
Christian Boltz e4be47
# If running in a Windows environment this must be set to the same as your
Christian Boltz e4be47
# system time zone.
Christian Boltz e4be47
TIME_ZONE = 'UTC'
Christian Boltz e4be47
Christian Boltz e4be47
# Language code for this installation. All choices can be found here:
Christian Boltz e4be47
# http://www.i18nguy.com/unicode/language-identifiers.html
Christian Boltz e4be47
LANGUAGE_CODE = 'en-us'
Christian Boltz e4be47
Christian Boltz e4be47
SITE_ID = 1
Christian Boltz e4be47
Christian Boltz e4be47
# If you set this to False, Django will make some optimizations so as not
Christian Boltz e4be47
# to load the internationalization machinery.
Christian Boltz e4be47
USE_I18N = True
Christian Boltz e4be47
Christian Boltz e4be47
# Absolute path to the directory that holds media.
Christian Boltz e4be47
# Example: "/home/media/media.lawrence.com/"
Christian Boltz e4be47
MEDIA_ROOT = ''
Christian Boltz e4be47
Christian Boltz e4be47
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
Christian Boltz e4be47
# trailing slash if there is a path component (optional in other cases).
Christian Boltz e4be47
# Examples: "http://media.lawrence.com", "http://example.com/media/"
Christian Boltz e4be47
MEDIA_URL = ''
Christian Boltz e4be47
Christian Boltz e4be47
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
Christian Boltz e4be47
# trailing slash.
Christian Boltz e4be47
# Examples: "http://foo.com/media/", "/media/".
Christian Boltz e4be47
STATIC_URL = '/media/'
Christian Boltz e4be47
Christian Boltz e4be47
# Make this unique, and don't share it with anybody.
Christian Boltz e4be47
SECRET_KEY = get_from_env('SECRET_KEY', '{{ helios.secret_key }}')
Christian Boltz e4be47
Christian Boltz e4be47
# If debug is set to false and ALLOWED_HOSTS is not declared, django raises  "CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False."
Christian Boltz e4be47
# If in production, you got a bad request (400) error
Christian Boltz e4be47
#More info: https://docs.djangoproject.com/en/1.7/ref/settings/#allowed-hosts (same for 1.6)
Christian Boltz 860794
ALLOWED_HOSTS = [ {% for allowed_host in helios.allowed_hosts %}'{{ allowed_host }}', {% endfor %} ]
Christian Boltz e4be47
Christian Boltz e4be47
# Secure Stuff
Christian Boltz 6ac95b
if get_from_env('SSL', '0') == '1':
Christian Boltz e4be47
    SECURE_SSL_REDIRECT = True
Christian Boltz e4be47
    SESSION_COOKIE_SECURE = True
Christian Boltz e4be47
Christian Boltz e4be47
    # tuned for Heroku
Christian Boltz e4be47
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
Christian Boltz e4be47
Christian Boltz e4be47
SESSION_COOKIE_HTTPONLY = True
Christian Boltz e4be47
Christian Boltz e4be47
# let's go with one year because that's the way to do it now
Christian Boltz e4be47
STS = False
Christian Boltz 6ac95b
if get_from_env('HSTS', '0') == '1':
Christian Boltz e4be47
    STS = True
Christian Boltz e4be47
    # we're using our own custom middleware now
Christian Boltz e4be47
    # SECURE_HSTS_SECONDS = 31536000
Christian Boltz e4be47
    # not doing subdomains for now cause that is not likely to be necessary and can screw things up.
Christian Boltz e4be47
    # SECURE_HSTS_INCLUDE_SUBDOMAINS = True
Christian Boltz e4be47
Christian Boltz e4be47
SECURE_BROWSER_XSS_FILTER = True
Christian Boltz e4be47
SECURE_CONTENT_TYPE_NOSNIFF = True
Christian Boltz e4be47
Christian Boltz 6ac95b
SILENCED_SYSTEM_CHECKS = ['urls.W002']
Christian Boltz e4be47
Christian Boltz 6ac95b
MIDDLEWARE = [
Christian Boltz e4be47
    # secure a bunch of things
Christian Boltz 6ac95b
    'django.middleware.security.SecurityMiddleware',
Christian Boltz e4be47
    'helios.security.HSTSMiddleware',
Christian Boltz e4be47
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
Christian Boltz 6ac95b
    # 'django.middleware.csrf.CsrfViewMiddleware',
Christian Boltz e4be47
Christian Boltz e4be47
    'django.middleware.common.CommonMiddleware',
Christian Boltz e4be47
    'django.contrib.sessions.middleware.SessionMiddleware',
Christian Boltz 6ac95b
    'django.contrib.auth.middleware.AuthenticationMiddleware',
Christian Boltz 6ac95b
]
Christian Boltz e4be47
Christian Boltz e4be47
ROOT_URLCONF = 'urls'
Christian Boltz e4be47
Christian Boltz e4be47
ROOT_PATH = os.path.dirname(__file__)
Christian Boltz 6ac95b
Christian Boltz 6ac95b
TEMPLATES = [
Christian Boltz 6ac95b
    {
Christian Boltz 6ac95b
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
Christian Boltz 6ac95b
        'APP_DIRS': True,
Christian Boltz 6ac95b
        'DIRS': [
Christian Boltz 6ac95b
            ROOT_PATH,
Christian Boltz 6ac95b
            os.path.join(ROOT_PATH, 'templates'),
Christian Boltz 6ac95b
            # os.path.join(ROOT_PATH, 'helios/templates'),  # covered by APP_DIRS:True
Christian Boltz 6ac95b
            # os.path.join(ROOT_PATH, 'helios_auth/templates'),  # covered by APP_DIRS:True
Christian Boltz 6ac95b
            # os.path.join(ROOT_PATH, 'server_ui/templates'),  # covered by APP_DIRS:True
Christian Boltz 6ac95b
        ],
Christian Boltz 6ac95b
        'OPTIONS': {
Christian Boltz 6ac95b
            'debug': DEBUG
Christian Boltz 6ac95b
        }
Christian Boltz 6ac95b
    },
Christian Boltz 6ac95b
]
Christian Boltz e4be47
Christian Boltz e4be47
INSTALLED_APPS = (
Christian Boltz 6ac95b
    'django.contrib.auth',
Christian Boltz 6ac95b
    'django.contrib.contenttypes',
Christian Boltz e4be47
    'django.contrib.sessions',
Christian Boltz 6ac95b
    'django.contrib.sites',
Christian Boltz 6ac95b
#   'anymail',
Christian Boltz e4be47
    ## HELIOS stuff
Christian Boltz e4be47
    'helios_auth',
Christian Boltz e4be47
    'helios',
Christian Boltz e4be47
    'server_ui',
Christian Boltz e4be47
)
Christian Boltz e4be47
Christian Boltz 6ac95b
ANYMAIL = {
Christian Boltz 6ac95b
    "MAILGUN_API_KEY": get_from_env('MAILGUN_API_KEY', None),
Christian Boltz 6ac95b
}
Christian Boltz 6ac95b
Christian Boltz 6ac95b
if ANYMAIL["MAILGUN_API_KEY"]:
Christian Boltz 6ac95b
    EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend"
Christian Boltz 6ac95b
Christian Boltz e4be47
##
Christian Boltz e4be47
## HELIOS
Christian Boltz e4be47
##
Christian Boltz e4be47
Christian Boltz e4be47
Christian Boltz e4be47
MEDIA_ROOT = ROOT_PATH + "media/"
Christian Boltz e4be47
Christian Boltz e4be47
# a relative path where voter upload files are stored
Christian Boltz e4be47
VOTER_UPLOAD_REL_PATH = "voters/%Y/%m/%d"
Christian Boltz e4be47
Christian Boltz e4be47
Christian Boltz e4be47
# Change your email settings
Christian Boltz e4be47
DEFAULT_FROM_EMAIL = get_from_env('DEFAULT_FROM_EMAIL', '{{ helios.default_from_email }}')
Christian Boltz e4be47
DEFAULT_FROM_NAME = get_from_env('DEFAULT_FROM_NAME', '{{ helios.default_from_name }}')
Christian Boltz e4be47
SERVER_EMAIL = '%s <%s>' % (DEFAULT_FROM_NAME, DEFAULT_FROM_EMAIL)
Christian Boltz e4be47
Christian Boltz e4be47
LOGIN_URL = '/auth/'
Christian Boltz e4be47
LOGOUT_ON_CONFIRMATION = True
Christian Boltz e4be47
Christian Boltz e4be47
# The two hosts are here so the main site can be over plain HTTP
Christian Boltz e4be47
# while the voting URLs are served over SSL.
Christian Boltz e4be47
URL_HOST = get_from_env("URL_HOST", "{{ helios.url_host }}").rstrip("/")
Christian Boltz e4be47
Christian Boltz e4be47
# IMPORTANT: you should not change this setting once you've created
Christian Boltz e4be47
# elections, as your elections' cast_url will then be incorrect.
Christian Boltz e4be47
# SECURE_URL_HOST = "https://localhost:8443"
Christian Boltz e4be47
SECURE_URL_HOST = get_from_env("SECURE_URL_HOST", URL_HOST).rstrip("/")
Christian Boltz e4be47
Christian Boltz e4be47
# election stuff
Christian Boltz e4be47
SITE_TITLE = get_from_env('SITE_TITLE', 'openSUSE Voting')
Christian Boltz e4be47
MAIN_LOGO_URL = get_from_env('MAIN_LOGO_URL', '/static/logo.png')
Christian Boltz e4be47
ALLOW_ELECTION_INFO_URL = (get_from_env('ALLOW_ELECTION_INFO_URL', '0') == '1')
Christian Boltz e4be47
Christian Boltz e4be47
# FOOTER links
Christian Boltz e4be47
FOOTER_LINKS = json.loads(get_from_env('FOOTER_LINKS', '[]'))
Christian Boltz e4be47
FOOTER_LOGO_URL = get_from_env('FOOTER_LOGO_URL', None)
Christian Boltz e4be47
Christian Boltz e4be47
WELCOME_MESSAGE = get_from_env('WELCOME_MESSAGE', "Welcome to the openSUSE election platform!")
Christian Boltz e4be47
Christian Boltz e4be47
HELP_EMAIL_ADDRESS = get_from_env('HELP_EMAIL_ADDRESS', '{{ helios.help_email_address }}')
Christian Boltz e4be47
Christian Boltz e4be47
AUTH_TEMPLATE_BASE = "server_ui/templates/base.html"
Christian Boltz e4be47
HELIOS_TEMPLATE_BASE = "server_ui/templates/base.html"
Christian Boltz e4be47
HELIOS_ADMIN_ONLY = False
Christian Boltz e4be47
HELIOS_VOTERS_UPLOAD = True
Christian Boltz e4be47
HELIOS_VOTERS_EMAIL = True
Christian Boltz e4be47
Christian Boltz e4be47
# are elections private by default?
Christian Boltz e4be47
HELIOS_PRIVATE_DEFAULT = False
Christian Boltz e4be47
Christian Boltz e4be47
# authentication systems enabled
Christian Boltz 6ac95b
# AUTH_ENABLED_SYSTEMS = ['password','facebook','twitter', 'google', 'yahoo']
Christian Boltz 6ac95b
AUTH_ENABLED_SYSTEMS = 'opensuse'
Christian Boltz 6ac95b
AUTH_DEFAULT_SYSTEM = 'opensuse'
Christian Boltz e4be47
Christian Boltz e4be47
# who can create an election?
Christian Boltz e4be47
# (parameter specific to openSUSE auth)
Christian Boltz e4be47
ELECTION_CREATORS = [ {% for election_creator in helios.election_creators %}'{{ election_creator }}', {% endfor %} ]
Christian Boltz e4be47
Christian Boltz e4be47
# google
Christian Boltz e4be47
GOOGLE_CLIENT_ID = get_from_env('GOOGLE_CLIENT_ID', '')
Christian Boltz e4be47
GOOGLE_CLIENT_SECRET = get_from_env('GOOGLE_CLIENT_SECRET', '')
Christian Boltz e4be47
Christian Boltz e4be47
# facebook
Christian Boltz e4be47
FACEBOOK_APP_ID = get_from_env('FACEBOOK_APP_ID','')
Christian Boltz e4be47
FACEBOOK_API_KEY = get_from_env('FACEBOOK_API_KEY','')
Christian Boltz e4be47
FACEBOOK_API_SECRET = get_from_env('FACEBOOK_API_SECRET','')
Christian Boltz e4be47
Christian Boltz e4be47
# twitter
Christian Boltz e4be47
TWITTER_API_KEY = ''
Christian Boltz e4be47
TWITTER_API_SECRET = ''
Christian Boltz e4be47
TWITTER_USER_TO_FOLLOW = 'heliosvoting'
Christian Boltz e4be47
TWITTER_REASON_TO_FOLLOW = "we can direct-message you when the result has been computed in an election in which you participated"
Christian Boltz e4be47
Christian Boltz e4be47
# the token for Helios to do direct messaging
Christian Boltz e4be47
TWITTER_DM_TOKEN = {"oauth_token": "", "oauth_token_secret": "", "user_id": "", "screen_name": ""}
Christian Boltz e4be47
Christian Boltz e4be47
# LinkedIn
Christian Boltz e4be47
LINKEDIN_API_KEY = ''
Christian Boltz e4be47
LINKEDIN_API_SECRET = ''
Christian Boltz e4be47
Christian Boltz e4be47
# CAS (for universities)
Christian Boltz e4be47
CAS_USERNAME = get_from_env('CAS_USERNAME', "")
Christian Boltz e4be47
CAS_PASSWORD = get_from_env('CAS_PASSWORD', "")
Christian Boltz e4be47
CAS_ELIGIBILITY_URL = get_from_env('CAS_ELIGIBILITY_URL', "")
Christian Boltz e4be47
CAS_ELIGIBILITY_REALM = get_from_env('CAS_ELIGIBILITY_REALM', "")
Christian Boltz e4be47
Christian Boltz e4be47
# Clever
Christian Boltz e4be47
CLEVER_CLIENT_ID = get_from_env('CLEVER_CLIENT_ID', "")
Christian Boltz e4be47
CLEVER_CLIENT_SECRET = get_from_env('CLEVER_CLIENT_SECRET', "")
Christian Boltz e4be47
Christian Boltz 6ac95b
# GitHub
Christian Boltz 6ac95b
GH_CLIENT_ID = get_from_env('GH_CLIENT_ID', '')
Christian Boltz 6ac95b
GH_CLIENT_SECRET = get_from_env('GH_CLIENT_SECRET', '')
Christian Boltz 6ac95b
Christian Boltz e4be47
# email server
Christian Boltz 6ac95b
EMAIL_HOST = get_from_env('EMAIL_HOST', 'localhost')
Christian Boltz e4be47
EMAIL_PORT = int(get_from_env('EMAIL_PORT', "25"))
Christian Boltz e4be47
EMAIL_HOST_USER = get_from_env('EMAIL_HOST_USER', '')
Christian Boltz e4be47
EMAIL_HOST_PASSWORD = get_from_env('EMAIL_HOST_PASSWORD', '')
Christian Boltz e4be47
EMAIL_USE_TLS = (get_from_env('EMAIL_USE_TLS', '0') == '1')
Christian Boltz e4be47
Christian Boltz e4be47
# to use AWS Simple Email Service
Christian Boltz e4be47
# in which case environment should contain
Christian Boltz e4be47
# AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
Christian Boltz e4be47
if get_from_env('EMAIL_USE_AWS', '0') == '1':
Christian Boltz e4be47
    EMAIL_BACKEND = 'django_ses.SESBackend'
Christian Boltz e4be47
Christian Boltz e4be47
# set up logging
Christian Boltz e4be47
import logging
Christian Boltz 6ac95b
Christian Boltz e4be47
logging.basicConfig(
Christian Boltz 6ac95b
    level=logging.DEBUG if TESTING else logging.INFO,
Christian Boltz 6ac95b
    format='%(asctime)s %(levelname)s %(message)s'
Christian Boltz e4be47
)
Christian Boltz e4be47
Christian Boltz 6ac95b
# set up celery
Christian Boltz 6ac95b
CELERY_BROKER_URL = get_from_env('CELERY_BROKER_URL', 'amqp://localhost')
Christian Boltz 6ac95b
if TESTING:
Christian Boltz 6ac95b
    CELERY_TASK_ALWAYS_EAGER = True
Christian Boltz 6ac95b
#database_url = DATABASES['default']
Christian Boltz e4be47
Christian Boltz e4be47
# Rollbar Error Logging
Christian Boltz e4be47
ROLLBAR_ACCESS_TOKEN = get_from_env('ROLLBAR_ACCESS_TOKEN', None)
Christian Boltz e4be47
if ROLLBAR_ACCESS_TOKEN:
Christian Boltz 6ac95b
  print("setting up rollbar")
Christian Boltz 6ac95b
  MIDDLEWARE += ['rollbar.contrib.django.middleware.RollbarNotifierMiddleware',]
Christian Boltz e4be47
  ROLLBAR = {
Christian Boltz e4be47
    'access_token': ROLLBAR_ACCESS_TOKEN,
Christian Boltz e4be47
    'environment': 'development' if DEBUG else 'production',  
Christian Boltz e4be47
  }