Skip to content

Commit

Permalink
Merge pull request #79 from wri/odp-159
Browse files Browse the repository at this point in the history
[ODP-159] Authentication
  • Loading branch information
demenech authored Nov 9, 2023
2 parents b05a613 + a712d41 commit fed5dd1
Show file tree
Hide file tree
Showing 26 changed files with 1,842 additions and 1,160 deletions.
4 changes: 4 additions & 0 deletions ckan-backend-dev/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,7 @@ CKAN___SCHEMING__PRESETS=ckanext.wri.schema:presets.json

# auth
CKANEXT__AUTH__INCLUDE_FRONTEND_LOGIN_TOKEN=True

# custom auth
CKANEXT__WRI__ODP_URL=http://localhost:3000

2 changes: 2 additions & 0 deletions ckan-backend-dev/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ services:
- S3_SECRET_KEY_ID=${MINIO_ROOT_PASSWORD}
- S3_BUCKET_NAME=ckan
- S3_BUCKET_REGION=us-east-1
- SYS_ADMIN_API_KEY=${CKAN__DATAPUSHER__API_TOKEN}
environment:
- NEXTAUTH_SECRET=secret
- NEXTAUTH_URL=http://localhost:3000
Expand All @@ -54,6 +55,7 @@ services:
- S3_SECRET_KEY_ID=${MINIO_ROOT_PASSWORD}
- S3_BUCKET_NAME=ckan
- S3_BUCKET_REGION=us-east-1
- SYS_ADMIN_API_KEY=${CKAN__DATAPUSHER__API_TOKEN}
ports:
- "0.0.0.0:3000:3000"
healthcheck:
Expand Down
1 change: 1 addition & 0 deletions ckan-backend-dev/docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ services:
- S3_SECRET_KEY_ID=${MINIO_ROOT_PASSWORD}
- S3_BUCKET_NAME=ckan
- S3_BUCKET_REGION=us-east-1
- SYS_ADMIN_API_KEY=${CKAN__DATAPUSHER__API_TOKEN}
ports:
- "0.0.0.0:3000:3000"
healthcheck:
Expand Down
31 changes: 31 additions & 0 deletions ckan-backend-dev/src/ckanext-wri/ckanext/wri/lib/mailer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from ckan.lib.mailer import create_reset_key, mail_user, MailerException
from ckan.lib.base import render
from ckan.common import config
import ckan.model as model

def get_reset_link(user: model.User) -> str:
odp_url = config.get('ckanext.wri.odp_url')
return "{}/auth/password-reset?token={}&user_id={}".format(odp_url, user.reset_key, user.id)

def get_reset_link_body(user: model.User) -> str:
extra_vars = {
'reset_link': get_reset_link(user),
'site_title': "WRI Open Data Portal",
'site_url': config.get('ckanext.wri.odp_url'),
'user_name': user.name,
}
# NOTE: This template is translated
return render('emails/reset_password.txt', extra_vars)

def send_reset_link(user: model.User) -> None:
create_reset_key(user)
body = get_reset_link_body(user)
extra_vars = {
'site_title': config.get('ckan.site_title')
}
subject = render('emails/reset_password_subject.txt', extra_vars)

# Make sure we only use the first line
subject = subject.split('\n')[0]

mail_user(user, subject, body, body)
35 changes: 35 additions & 0 deletions ckan-backend-dev/src/ckanext-wri/ckanext/wri/logic/action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import ckan.plugins.toolkit as tk
import ckan.logic as logic
import ckanext.wri.lib.mailer as mailer
from ckan.types import Context
from ckan.common import _


ValidationError = logic.ValidationError

import logging

log = logging.getLogger(__name__)

def password_reset(context: Context, data_dict: [str, any]):
email = data_dict.get("email", False)

if not email:
raise ValidationError({"email": [_("Please provide an email address")]})
model = context['model']
session = context['session']

user = session.query(model.User).filter_by(email=email).all()

if not user:
# Do not leak whether the email is registered or not
return "Password reset link sent to email address"

try:
mailer.send_reset_link(user[0])
return "Password reset link sent to email address"
except mailer.MailerException as e:
log.exception(e)
return "Password reset link sent to email address"


11 changes: 11 additions & 0 deletions ckan-backend-dev/src/ckanext-wri/ckanext/wri/plugin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import ckan.plugins as plugins
import ckan.plugins.toolkit as toolkit

import ckanext.wri.logic.action as action
from ckanext.wri.logic.validators import iso_language_code


class WriPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IConfigurer)
plugins.implements(plugins.IValidators)
plugins.implements(plugins.IActions)

# IConfigurer

Expand All @@ -21,3 +23,12 @@ def get_validators(self):
return {
"iso_language_code": iso_language_code
}

# IActions

def get_actions(self):
return {
"password_reset": action.password_reset

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% trans %}
<p>
Dear {{ user_name }},
<br />
<br />
You have requested your password on {{ site_title }} to be reset.
<br />
<br />
Please click the following link to confirm this request:
<br />
<br />
<a target="_blank" href="{{ reset_link }}">Reset password</a>
<br />
<br />
Have a nice day.
<br />
<br />
--
Message sent by {{ site_title }} ({{ site_url }})
</p>
{% endtrans %}


1 change: 1 addition & 0 deletions deployment/frontend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ S3_ACCESS_KEY_ID="minioadmin"
S3_SECRET_KEY_ID="minioadmin"
S3_BUCKET_NAME="ckan"
S3_BUCKET_REGION="us-east-1"
SYS_ADMIN_API_KEY="1111"
Loading

0 comments on commit fed5dd1

Please sign in to comment.