-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from keitaroinc/initial-implementation
Initial implementation
- Loading branch information
Showing
21 changed files
with
629 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,3 +40,6 @@ coverage.xml | |
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# Saml2 config | ||
idp.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,16 @@ | ||
language: python | ||
sudo: required | ||
|
||
# use an older trusty image, because the newer images cause build errors with | ||
# psycopg2 that comes with CKAN<2.8: | ||
# "Error: could not determine PostgreSQL version from '10.1'" | ||
# see https://github.com/travis-ci/travis-ci/issues/8897 | ||
dist: trusty | ||
group: deprecated-2017Q4 | ||
|
||
# matrix | ||
python: | ||
- 2.7 | ||
env: | ||
- CKANVERSION=master | ||
- CKANVERSION=2.7 | ||
- CKANVERSION=2.8 | ||
|
||
# tests | ||
- "3.8" | ||
env: CKANVERSION=2.9 | ||
services: | ||
- postgresql | ||
- redis-server | ||
- postgresql | ||
- redis | ||
- docker | ||
install: | ||
- bash bin/travis-build.bash | ||
- pip install coveralls | ||
- bash bin/travis-build.bash | ||
- pip install coveralls | ||
- pip freeze | ||
script: sh bin/travis-run.sh | ||
after_success: | ||
- coveralls | ||
|
||
# additional jobs | ||
matrix: | ||
include: | ||
- name: "Flake8 on Python 3.7" | ||
dist: xenial # required for Python 3.7 | ||
cache: pip | ||
install: pip install flake8 | ||
script: | ||
- flake8 --version | ||
- flake8 . --count --max-complexity=10 --max-line-length=127 --statistics --exclude ckan,ckanext-saml2auth | ||
python: 3.7 | ||
# overwrite matrix | ||
env: | ||
- FLAKE8=true | ||
- CKANVERSION=master | ||
- coveralls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,31 +2,18 @@ | |
these badges work. The necessary Travis and Coverage config files have been | ||
generated for you. | ||
.. image:: https://travis-ci.org/duskobogdanovski/ckanext-saml2auth.svg?branch=master | ||
:target: https://travis-ci.org/duskobogdanovski/ckanext-saml2auth | ||
.. image:: https://travis-ci.com/keitaroinc/ckanext-saml2auth.svg?branch=initial-implementation | ||
:target: https://travis-ci.com/keitaroinc/ckanext-saml2auth | ||
|
||
.. image:: https://coveralls.io/repos/duskobogdanovski/ckanext-saml2auth/badge.svg | ||
:target: https://coveralls.io/r/duskobogdanovski/ckanext-saml2auth | ||
.. image:: https://coveralls.io/repos/github/keitaroinc/ckanext-saml2auth/badge.svg?branch=initial-implementation | ||
:target: https://coveralls.io/github/keitaroinc/ckanext-saml2auth?branch=initial-implementation | ||
|
||
.. image:: https://img.shields.io/pypi/v/ckanext-saml2auth.svg | ||
:target: https://pypi.org/project/ckanext-saml2auth/ | ||
:alt: Latest Version | ||
|
||
.. image:: https://img.shields.io/pypi/pyversions/ckanext-saml2auth.svg | ||
:target: https://pypi.org/project/ckanext-saml2auth/ | ||
:alt: Supported Python versions | ||
|
||
.. image:: https://img.shields.io/pypi/status/ckanext-saml2auth.svg | ||
:target: https://pypi.org/project/ckanext-saml2auth/ | ||
:alt: Development Status | ||
|
||
.. image:: https://img.shields.io/pypi/l/ckanext-saml2auth.svg | ||
:target: https://pypi.org/project/ckanext-saml2auth/ | ||
:alt: License | ||
|
||
============= | ||
================== | ||
ckanext-saml2auth | ||
============= | ||
================== | ||
|
||
.. Put a description of your extension here: | ||
What does it do? What features does it have? | ||
|
@@ -37,8 +24,7 @@ ckanext-saml2auth | |
Requirements | ||
------------ | ||
|
||
For example, you might want to mention here which versions of CKAN this | ||
extension works with. | ||
This extension works with CKAN 2.9+. | ||
|
||
|
||
------------ | ||
|
@@ -51,19 +37,29 @@ Installation | |
To install ckanext-saml2auth: | ||
|
||
1. Activate your CKAN virtual environment, for example:: | ||
1. Install the required packages:: | ||
|
||
sudo apt install xmlsec1 | ||
|
||
|
||
2. Activate your CKAN virtual environment, for example:: | ||
|
||
. /usr/lib/ckan/default/bin/activate | ||
|
||
2. Install the ckanext-saml2auth Python package into your virtual environment:: | ||
3. Install the ckanext-saml2auth Python package into your virtual environment:: | ||
|
||
pip install ckanext-saml2auth | ||
|
||
3. Add ``saml2auth`` to the ``ckan.plugins`` setting in your CKAN | ||
|
||
4. Install the python modules required by the extension (adjusting the path according to where ckanext-saml2auth was installed in the previous step):: | ||
|
||
pip install -r requirements.txt | ||
|
||
5. Add ``saml2auth`` to the ``ckan.plugins`` setting in your CKAN | ||
config file (by default the config file is located at | ||
``/etc/ckan/default/ckan.ini``). | ||
|
||
4. Restart CKAN. For example if you've deployed CKAN with Apache on Ubuntu:: | ||
6. Restart CKAN. For example if you've deployed CKAN with Apache on Ubuntu:: | ||
|
||
sudo service apache2 reload | ||
|
||
|
@@ -72,13 +68,51 @@ To install ckanext-saml2auth: | |
Config settings | ||
--------------- | ||
|
||
None at present | ||
Required:: | ||
|
||
# Specifies the metadata location type | ||
# Options: local or remote | ||
ckanext.saml2auth.idp_metadata.location = remote | ||
|
||
# Path to a local file accessible on the server the service runs on | ||
# Ignore this config if the idp metadata location is set to: remote | ||
ckanext.saml2auth.idp_metadata.local_path = /opt/metadata/idp.xml | ||
|
||
# A remote URL serving aggregate metadata | ||
# Ignore this config if the idp metadata location is set to: local | ||
ckanext.saml2auth.idp_metadata.remote_url = https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2 | ||
|
||
.. Document any optional config settings here. For example:: | ||
# Path to a local file accessible on the server the service runs on | ||
# Ignore this config if the idp metadata location is set to: local | ||
ckanext.saml2auth.idp_metadata.remote_cert = /opt/metadata/kalmar2.cert | ||
|
||
.. # The minimum number of hours to wait before re-checking a resource | ||
# (optional, default: 24). | ||
ckanext.saml2auth.some_setting = some_default_value | ||
# Corresponding SAML user field for firstname | ||
ckanext.saml2auth.user_firstname = firstname | ||
|
||
# Corresponding SAML user field for lastname | ||
ckanext.saml2auth.user_lastname = lastname | ||
|
||
# Corresponding SAML user field for email | ||
ckanext.saml2auth.user_email = email | ||
|
||
|
||
Optional:: | ||
|
||
# Configuration setting that enables CKAN's internal register/login functionality as well | ||
# Default: False | ||
ckanext.saml2auth.enable_ckan_internal_login = True | ||
|
||
# List of email addresses from users that should be created as sysadmins (system administrators) | ||
ckanext.saml2auth.sysadmins_list = [email protected] [email protected] [email protected] | ||
|
||
# Indicates that attributes that are not recognized (they are not configured in attribute-mapping), | ||
# will not be discarded. | ||
# Default: True | ||
ckanext.saml2auth.allow_unknown_attributes = False | ||
|
||
# A list of string values that will be used to set the <NameIDFormat> element of the metadata of an entity. | ||
# Default: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent | ||
ckanext.saml2auth.sp.name_id_format = urn:oasis:names:tc:SAML:2.0:nameid-format:persistent urn:oasis:names:tc:SAML:2.0:nameid-format:transient | ||
|
||
|
||
---------------------- | ||
|
@@ -88,6 +122,8 @@ Developer installation | |
To install ckanext-saml2auth for development, activate your CKAN virtualenv and | ||
do:: | ||
|
||
|
||
sudo apt install xmlsec1 | ||
git clone https://github.com/duskobogdanovski/ckanext-saml2auth.git | ||
cd ckanext-saml2auth | ||
python setup.py develop | ||
|
@@ -108,9 +144,9 @@ To run the tests and produce a coverage report, first make sure you have | |
pytest --ckan-ini=test.ini --cov=ckanext.saml2auth | ||
|
||
|
||
---------------------------------------- | ||
-------------------------------------------- | ||
Releasing a new version of ckanext-saml2auth | ||
---------------------------------------- | ||
-------------------------------------------- | ||
|
||
ckanext-saml2auth should be available on PyPI as https://pypi.org/project/ckanext-saml2auth. | ||
To publish a new version to PyPI follow these steps: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,5 @@ | ||
#!/bin/sh -e | ||
set -ex | ||
|
||
flake8 --version | ||
# stop the build if there are Python syntax errors or undefined names | ||
flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics --exclude ckan,ckanext-saml2auth | ||
pytest --ckan-ini=subdir/test.ini --cov=ckanext.saml2auth --disable-warnings ckanext/saml2auth/tests | ||
|
||
pytest --ckan-ini=subdir/test.ini \ | ||
--cov=ckanext.saml2auth | ||
|
||
# strict linting | ||
flake8 . --count --max-complexity=10 --max-line-length=127 --statistics --exclude ckan,ckanext-saml2auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# encoding: utf-8 | ||
import logging | ||
import string | ||
import secrets | ||
from six import text_type | ||
|
||
from saml2.client import Saml2Client | ||
from saml2.config import Config as Saml2Config | ||
|
||
import ckan.model as model | ||
import ckan.authz as authz | ||
from ckan.common import config, asbool, aslist | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
def saml_client(config): | ||
sp_config = Saml2Config() | ||
sp_config.load(config) | ||
client = Saml2Client(config=sp_config) | ||
return client | ||
|
||
|
||
def generate_password(): | ||
alphabet = string.ascii_letters + string.digits | ||
password = ''.join(secrets.choice(alphabet) for i in range(8)) | ||
return password | ||
|
||
|
||
def is_default_login_enabled(): | ||
return asbool( | ||
config.get('ckanext.saml2auth.enable_ckan_internal_login', | ||
False)) | ||
|
||
|
||
def update_user_sysadmin_status(username, email): | ||
sysadmins_list = aslist( | ||
config.get('ckanext.saml2auth.sysadmins_list')) | ||
user = model.User.by_name(text_type(username)) | ||
sysadmin = authz.is_sysadmin(username) | ||
|
||
if sysadmin and email not in sysadmins_list: | ||
user.sysadmin = False | ||
model.Session.add(user) | ||
model.Session.commit() | ||
elif not sysadmin and email in sysadmins_list: | ||
user.sysadmin = True | ||
model.Session.add(user) | ||
model.Session.commit() | ||
|
||
|
||
def activate_user_if_deleted(userobj): | ||
u'''Reactivates deleted user.''' | ||
if userobj.is_deleted(): | ||
userobj.activate() | ||
userobj.commit() | ||
log.info(u'User {} reactivated'.format(userobj.name)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,49 @@ | ||
# encoding: utf-8 | ||
import ckan.plugins as plugins | ||
import ckan.plugins.toolkit as toolkit | ||
|
||
from ckanext.saml2auth.views.saml2auth import saml2auth | ||
from ckanext.saml2auth import helpers as h | ||
|
||
|
||
class Saml2AuthPlugin(plugins.SingletonPlugin): | ||
plugins.implements(plugins.IConfigurer) | ||
plugins.implements(plugins.IBlueprint) | ||
plugins.implements(plugins.IConfigurable) | ||
plugins.implements(plugins.ITemplateHelpers) | ||
|
||
# ITemplateHelpers | ||
|
||
def get_helpers(self): | ||
return { | ||
'is_default_login_enabled': | ||
h.is_default_login_enabled | ||
} | ||
|
||
# IConfigurable | ||
|
||
def configure(self, config): | ||
# Certain config options must exists for the plugin to work. Raise an | ||
# exception if they're missing. | ||
missing_config = "{0} is not configured. Please amend your .ini file." | ||
config_options = ( | ||
'ckanext.saml2auth.idp_metadata.local_path', | ||
'ckanext.saml2auth.user_firstname', | ||
'ckanext.saml2auth.user_lastname', | ||
'ckanext.saml2auth.user_email' | ||
) | ||
for option in config_options: | ||
if not config.get(option, None): | ||
raise RuntimeError(missing_config.format(option)) | ||
|
||
# IBlueprint | ||
|
||
def get_blueprint(self): | ||
return [saml2auth] | ||
|
||
# IConfigurer | ||
|
||
def update_config(self, config_): | ||
toolkit.add_template_directory(config_, 'templates') | ||
toolkit.add_public_directory(config_, 'public') | ||
toolkit.add_resource('fanstatic', | ||
'saml2auth') | ||
toolkit.add_resource('fanstatic', 'saml2auth') |
Oops, something went wrong.