Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -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
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------
Expand Down
10 changes: 9 additions & 1 deletion config.env.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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),
}
17 changes: 17 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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__
23 changes: 15 additions & 8 deletions profiles/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand All @@ -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']
)


Expand All @@ -128,14 +132,16 @@ 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(
"listing.html",
info=info,
title=group_desc,
members=_ldap_get_group_members(_group),
*app.config['DATADOG_RUM_CONFIG']
)


Expand All @@ -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']
)


Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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


Expand Down
27 changes: 27 additions & 0 deletions profiles/templates/include/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,31 @@

<script defer src="https://use.fontawesome.com/releases/v5.0.9/js/all.js"></script>

<script>
(function(h,o,u,n,d) {
h = h[d] = h[d] || { q: [], onReady: function (c) { h.q.push(c) } }
d = o.createElement(u); d.async = 1; d.src = n; d.crossOrigin=''
n = o.getElementsByTagName(u)[0]; n.parentNode.insertBefore(d, n)
})(window, document, 'script', 'https://www.datadoghq-browser-agent.com/us1/v6/datadog-rum.js', 'DD_RUM')

window.DD_RUM.onReady(function () {
window.DD_RUM.init({
applicationId: '65be0cac-59ab-4ad7-8c23-5a3e577893fe',
clientToken: 'pub2f0696fe063adeb0dc204547f4584f55',
site: 'datadoghq.com',
service: 'profiles',
env: '{{ DATADOG_ENV }}',
version: '{{ DATADOG_APP_VERSION }}',
sessionSampleRate: 100, // capture 100% of sessions
sessionReplaySampleRate: 100, // capture 100% of sessions with replay
trackResources: true, // Enable Resource tracking
trackUserInteractions: true, // Enable Action tracking
trackLongTasks: true, // Enable Long Tasks tracking

allowedTracingUrls: [ 'http://localhost:8080', 'https://profiles.csh.rit.edu', 'https://profiles-dev.csh.rit.edu'],
defaultPrivacyLevel: 'mask-user-input',
});
});
</script>

</head>
6 changes: 2 additions & 4 deletions profiles/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Credit to Liam Middlebrook and Ram Zallan
# https://github.com/liam-middlebrook/gallery
import subprocess
import base64
import datetime

Expand All @@ -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,
Expand All @@ -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,
Expand Down
Loading