diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..2a73383
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,12 @@
+PROFILES_SERVER_NAME=localhost:8080
+
+DEBUG=true
+
+PROFILES_OIDC_CLIENT_ID=profiles-dev
+PROFILES_OIDC_CLIENT_SECRET=
+PROFILES_OIDC_LOGOUT_REDIRECT_URI=http://localhost:8080/logout
+
+LDAP_BIND_DN=uid=yourusername,cn=users,cn=accounts,dc=csh,dc=rit,dc=edu
+LDAP_BIND_PASS=
+
+DATADOG_ENV=local
diff --git a/README.md b/README.md
index 4581f59..f6d12da 100755
--- a/README.md
+++ b/README.md
@@ -61,17 +61,32 @@ to
SERVER_NAME = os.environ.get('PROFILES_SERVER_NAME', 'localhost:8080')
```
-Reach out to an RTP to get OIDC credentials that will allow you to develop locally behind OIDC auth.
+#### OIDC
+
+Reach out to an RTP to get OIDC credentials that will allow you to develop locally behind OIDC auth. You will need `PROFILES_OIDC_CLIENT_ID` and `PROFILES_OIDC_CLIENT_SECRET`
+
+#### LDAP
```LDAP_BIND_DN``` is your CSH DN. It is in the following format:
```uid={CSH User Name},cn=users,cn=accounts,dc=csh,dc=rit,dc=edu```
+```LDAP_BIND_PASS``` is your CSH password.
+
+#### DATADOG
- ```LDAP_BIND_PASS``` is your CSH password.
+```DATADOG_ENV``` is the env where you are developing, should stay local for local development
+
+```DATADOG_APP_VERSION``` is the version of your app, when unset defaults to git commit hash
If you did everything right, you should be able to run ```python app.py``` and develop locally.
+Running with Docker
+--------------------
+
+Alternatively, you can run profiles using docker or podman compose. You can configure the environment in same way as above, using a `config.py` file, or you can copy the `.env.example` file to `.env` and configure it there.
+
+The docker-compose file is also set up for automatic redeploying with watch if you run with `podman compose up --watch --build`
Code Standards
------------
diff --git a/config.env.py b/config.env.py
index 6cbe927..4505441 100644
--- a/config.env.py
+++ b/config.env.py
@@ -2,12 +2,13 @@
import random
import string
from os import environ as env
+import subprocess
# Sentry DSN
SENTRY_DSN = env.get("PROFILES_SENTRY_DSN", "")
# Flask config
-DEBUG = False
+DEBUG = os.environ.get("DEBUG", "false").lower() == "true"
IP = os.environ.get('PROFILES_IP', 'localhost')
PORT = os.environ.get('PROFILES_PORT', 8080)
SERVER_NAME = os.environ.get('PROFILES_SERVER_NAME', 'profiles.csh.rit.edu')
@@ -25,3 +26,10 @@
LDAP_BIND_DN = env.get("LDAP_BIND_DN", default="cn=profiles,ou=Apps,dc=csh,dc=rit,dc=edu")
LDAP_BIND_PASS = env.get("LDAP_BIND_PW", default=None)
+
+GIT_HASH = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('utf-8').rstrip()
+
+DATADOG_RUM_CONFIG = {
+ 'DATADOG_ENV': os.environ.get('DATADOG_ENV', 'local'),
+ 'DATADOG_APP_VERSION': os.environ.get('DATADOG_APP_VERSION', GIT_HASH),
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..33a0a31
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,17 @@
+version: "3"
+services:
+ profiles:
+ build: .
+ container_name: profiles
+ ports:
+ - "127.0.0.1:8080:8080"
+ env_file:
+ - path: .env
+ required: false
+ develop:
+ watch:
+ - action: sync+restart
+ path: ./profiles
+ target: /opt/profiles/profiles
+ ignore:
+ - __pycache__
diff --git a/profiles/__init__.py b/profiles/__init__.py
index 2289e29..4ae4181 100644
--- a/profiles/__init__.py
+++ b/profiles/__init__.py
@@ -90,12 +90,15 @@ def home(info=None):
@before_request
def user(uid=None, info=None):
try:
- return render_template("profile.html", info=info, member_info=get_member_info(uid))
+ return render_template(
+ "profile.html", info=info,
+ member_info=get_member_info(uid), **app.config['DATADOG_RUM_CONFIG']
+ )
except BadQueryError as bqe:
# ldap_get_member() returns a BadQueryError if getting the user's information fails.
# Flask already treats a stray BadQueryError as a 404, but actually handling it prevents the traceback
# from getting dumped into the log.
- return render_template("404.html", message=bqe), 404
+ return render_template("404.html", message=bqe, *app.config['DATADOG_RUM_CONFIG']), 404
@app.route("/results", methods=["POST"])
@@ -116,7 +119,8 @@ def search(searched=None, info=None):
if len(members) == 1:
return redirect("/user/" + members[0].uid, 302)
return render_template(
- "listing.html", info=info, title="Search Results: " + searched, members=members
+ "listing.html", info=info, title="Search Results: " + searched,
+ members=members, *app.config['DATADOG_RUM_CONFIG']
)
@@ -128,7 +132,8 @@ def group(_group=None, info=None):
if _group == "eboard":
return render_template(
- "listing.html", info=info, title=group_desc, members=ldap_get_eboard()
+ "listing.html", info=info, title=group_desc,
+ members=ldap_get_eboard(), *app.config['DATADOG_RUM_CONFIG']
)
return render_template(
@@ -136,6 +141,7 @@ def group(_group=None, info=None):
info=info,
title=group_desc,
members=_ldap_get_group_members(_group),
+ *app.config['DATADOG_RUM_CONFIG']
)
@@ -144,7 +150,8 @@ def group(_group=None, info=None):
@before_request
def year(_year=None, info=None):
return render_template(
- "listing.html", info=info, title="Year: " + _year, members=ldap_get_year(_year)
+ "listing.html", info=info, title="Year: " + _year,
+ members=ldap_get_year(_year), *app.config['DATADOG_RUM_CONFIG']
)
@@ -181,7 +188,7 @@ def image(uid):
try:
return get_image(uid)
except BadQueryError as bqe:
- return render_template("404.html", message=bqe), 404
+ return render_template("404.html", message=bqe, *app.config['DATADOG_RUM_CONFIG']), 404
@app.route("/clearcache")
@@ -214,9 +221,9 @@ def clear_cache(info=None):
@app.errorhandler(500)
def handle_internal_error(e):
if isinstance(e, NotFound):
- return render_template("404.html", message=str(e)), 404
+ return render_template("404.html", message=str(e), *app.config['DATADOG_RUM_CONFIG']), 404
if isinstance(e.original_exception, BadQueryError):
- return render_template("404.html", message=e.original_exception), 404
+ return render_template("404.html", message=e.original_exception, *app.config['DATADOG_RUM_CONFIG']), 404
raise e.original_exception
diff --git a/profiles/templates/include/head.html b/profiles/templates/include/head.html
index 521ba71..4de3859 100644
--- a/profiles/templates/include/head.html
+++ b/profiles/templates/include/head.html
@@ -28,4 +28,31 @@
+
+
diff --git a/profiles/utils.py b/profiles/utils.py
index 505778f..d026219 100644
--- a/profiles/utils.py
+++ b/profiles/utils.py
@@ -1,6 +1,5 @@
# Credit to Liam Middlebrook and Ram Zallan
# https://github.com/liam-middlebrook/gallery
-import subprocess
import base64
import datetime
@@ -12,6 +11,7 @@
import ldap
from profiles import _ldap
+import profiles
from profiles.ldap import (ldap_get_calendar,
ldap_get_member,
ldap_get_pronouns,
@@ -25,13 +25,11 @@
def before_request(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
- git_revision = subprocess.check_output(
- ['git', 'rev-parse', '--short', 'HEAD']).decode('utf-8').rstrip()
uuid = str(session["userinfo"].get("sub", ""))
uid = str(session["userinfo"].get("preferred_username", ""))
user_obj = _ldap.get_member(uid, uid=True)
info = {
- "git_revision": git_revision,
+ "git_revision": profiles.app.config['GIT_HASH'],
"uuid": uuid,
"uid": uid,
"user_obj": user_obj,