diff --git a/authentic2/COPYING b/authentic2/COPYING new file mode 100644 index 0000000..718cb94 --- /dev/null +++ b/authentic2/COPYING @@ -0,0 +1,2 @@ +authentic2-plugin-template is entirely under the copyright of Entr'ouvert and +distributed under the license AGPLv3 or later. diff --git a/authentic2/MANIFEST.in b/authentic2/MANIFEST.in new file mode 100644 index 0000000..5f87890 --- /dev/null +++ b/authentic2/MANIFEST.in @@ -0,0 +1,3 @@ +include COPYING +recursive-include src/authentic2_plugin_template/templates *.html +recursive-include src/authentic2_plugin_template/static *.js *.css *.png diff --git a/authentic2/README b/authentic2/README new file mode 100644 index 0000000..3688845 --- /dev/null +++ b/authentic2/README @@ -0,0 +1,20 @@ +** THIS IS A TEMPLATE PROJECT ** + +To rename it to your taste: + + $ ./adapt.sh + +** THIS IS A TEMPLATE PROJECT ** +Authentic2 Plugin Template +========================== + +Install +------- + +You just have to install the package in your virtualenv and relaunch, it will +be automatically loaded by authentic2. + +Settings +-------- + +** DESCRIBE CUSTOM SETTINGS HERE ** diff --git a/authentic2/adapt.sh b/authentic2/adapt.sh new file mode 100755 index 0000000..d9fb451 --- /dev/null +++ b/authentic2/adapt.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +set -x + +echo "Give project name (it must match regexp ^[a-z][a-z0-9-]+$ )" +read PROJECT_NAME + +if ! echo $PROJECT_NAME | grep -q '^[a-z][a-z0-9-]\+$'; then + echo "Invalid project name:" $PROJECT_NAME + exit 1 +fi + +UPPER_UNDERSCORED=`echo $PROJECT_NAME | tr a-z A-Z | sed 's/-/_/g'` +LOWER_UNDERSCORED=`echo $PROJECT_NAME | sed 's/-/_/g'` +TITLECASE=`echo $PROJECT_NAME | sed 's/-/ /g;s/.*/\L&/; s/[a-z]*/\u&/g'` + +echo Project name: $PROJECT_NAME +echo Uppercase underscored: $UPPER_UNDERSCORED +echo Lowercase underscored: $LOWER_UNDERSCORED +echo Titlecase: $TITLECASE + +if [ -d .git ]; then + MV='git mv' +else + MV=mv +fi + +sed -i \ + -e "s/authentic2_plugin_template/$LOWER_UNDERSCORED/g" \ + -e "s/authentic2-plugin-template/$PROJECT_NAME/g" \ + -e "s/A2_TEMPLATE_/A2_$UPPER_UNDERSCORED_/g" \ + -e "s/Authentic2 Plugin Template/$TITLECASE/g" \ + setup.py src/*/*.py README COPYING MANIFEST.in +$MV src/authentic2_plugin_template/static/authentic2_plugin_template \ + src/authentic2_plugin_template/static/$LOWER_UNDERSCORED +$MV src/authentic2_plugin_template/templates/authentic2_plugin_template \ + src/authentic2_plugin_template/templates/$LOWER_UNDERSCORED +$MV src/authentic2_plugin_template src/$LOWER_UNDERSCORED diff --git a/authentic2/setup.py b/authentic2/setup.py new file mode 100755 index 0000000..0bb96e4 --- /dev/null +++ b/authentic2/setup.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +from setuptools import setup, find_packages +import os + +def get_version(): + import glob + import re + import os + + version = None + for d in glob.glob('src/*'): + if not os.path.isdir(d): + continue + module_file = os.path.join(d, '__init__.py') + if not os.path.exists(module_file): + continue + for v in re.findall("""__version__ *= *['"](.*)['"]""", + open(module_file).read()): + assert version is None + version = v + if version: + break + assert version is not None + if os.path.exists('.git'): + import subprocess + p = subprocess.Popen(['git','describe','--dirty','--match=v*'], + stdout=subprocess.PIPE) + result = p.communicate()[0] + assert p.returncode == 0, 'git returned non-zero' + new_version = result.split()[0][1:] + assert new_version.split('-')[0] == version, '__version__ must match the last git annotated tag' + version = new_version.replace('-', '.') + return version + +README = file(os.path.join( + os.path.dirname(__file__), + 'README')).read() + +setup(name='authentic2-plugin-template', + version=get_version(), + license='AGPLv3', + description='Authentic2 Plugin Template', + long_description=README, + author="Entr'ouvert", + author_email="info@entrouvert.com", + packages=find_packages('src'), + package_dir={ + '': 'src', + }, + package_data={ + 'authentic2_plugin_template': [ + 'templates/authentic2_plugin_template/*.html', + 'static/authentic2_plugin_template/js/*.js', + 'static/authentic2_plugin_template/css/*.css', + 'static/authentic2_plugin_template/img/*.png', + ], + }, + install_requires=[ + ], + entry_points={ + 'authentic2.plugin': [ + 'authentic2-plugin-template= authentic2_plugin_template:Plugin', + ], + }, +) diff --git a/authentic2/src/authentic2_plugin_template/__init__.py b/authentic2/src/authentic2_plugin_template/__init__.py new file mode 100644 index 0000000..3de27b7 --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/__init__.py @@ -0,0 +1,62 @@ +__version__ = '1.0.0' + +class Plugin(object): + def get_before_urls(self): + from . import urls + return urls.urlpatterns + + def get_after_urls(self): + return [] + + def get_apps(self): + return [__name__] + + def get_before_middleware(self): + return [] + + def get_after_middleware(self): + return [] + + def get_authentication_backends(self): + return [] + + def get_auth_frontends(self): + return [] + + def get_idp_backends(self): + return [] + + def get_admin_modules(self): + from . import dashboard + return dashboard.get_admin_modules() + + def service_list(self, request): + '''For IdP plugins this method add links to the user homepage. + + It must return a list of authentic2.utils.Service objects, each + object has a name and can have an url and some actions. + + Service(name=name[, url=url[, actions=actions]]) + + Actions are a list of tuples, whose parts are + - first the name of the action, + - the HTTP method for calling the action, + - the URL for calling the action, + - the paramters to pass to this URL as a sequence of key-value tuples. + ''' + return [] + + def logout_list(self, request): + '''For IdP or SP plugins this method add actions to logout from remote + IdP or SP. + + It must returns a list of HTML fragments, each fragment is + responsible for calling the view doing the logout. Views are usually + called using or tags and finally redirect to an + icon indicating success or failure for the logout. + + Authentic2 provide two such icons through the following URLs: + - os.path.join(settings.STATIC_URL, 'authentic2/img/ok.png') + - os.path.join(settings.STATIC_URL, 'authentic2/img/ok.png') + ''' + return [] diff --git a/authentic2/src/authentic2_plugin_template/admin.py b/authentic2/src/authentic2_plugin_template/admin.py new file mode 100644 index 0000000..08eef26 --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin + +from . import models + +# registrer your admin editable models here using admin.register diff --git a/authentic2/src/authentic2_plugin_template/app_settings.py b/authentic2/src/authentic2_plugin_template/app_settings.py new file mode 100644 index 0000000..da34e12 --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/app_settings.py @@ -0,0 +1,23 @@ +class AppSettings(object): + __DEFAULTS = { + 'ENABLE': True, + } + + def __init__(self, prefix): + self.prefix = prefix + + def _setting(self, name, dflt): + from django.conf import settings + return getattr(settings, self.prefix+name, dflt) + + def __getattr__(self, name): + if name not in self.__DEFAULTS: + raise AttributeError(name) + return self._setting(name, self.__DEFAULTS[name]) + +# Ugly? Guido recommends this himself ... +# http://mail.python.org/pipermail/python-ideas/2012-May/014969.html +import sys +app_settings = AppSettings('A2_PLUGIN_TEMPLATE_') +app_settings.__name__ = __name__ +sys.modules[__name__] = app_settings diff --git a/authentic2/src/authentic2_plugin_template/dashboard.py b/authentic2/src/authentic2_plugin_template/dashboard.py new file mode 100644 index 0000000..48882ba --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/dashboard.py @@ -0,0 +1,11 @@ +from django.utils.translation import ugettext_lazy as _ + +from admin_tools.dashboard import modules + + +def get_admin_modules(): + '''Show Client model in authentic2 admin''' + model_list = modules.ModelList(_('Authentic2 Plugin Template'), + models=('authentic2_plugin_template.models.*',)) + return (model_list,) + diff --git a/authentic2/src/authentic2_plugin_template/forms.py b/authentic2/src/authentic2_plugin_template/forms.py new file mode 100644 index 0000000..32d64dc --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/forms.py @@ -0,0 +1,3 @@ +from django import forms + + diff --git a/authentic2/src/authentic2_plugin_template/migrations/__init__.py b/authentic2/src/authentic2_plugin_template/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/authentic2/src/authentic2_plugin_template/models.py b/authentic2/src/authentic2_plugin_template/models.py new file mode 100644 index 0000000..c0f6f87 --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/models.py @@ -0,0 +1,4 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +# put your models here diff --git a/authentic2/src/authentic2_plugin_template/static/authentic2_plugin_template/.keepme b/authentic2/src/authentic2_plugin_template/static/authentic2_plugin_template/.keepme new file mode 100644 index 0000000..e69de29 diff --git a/authentic2/src/authentic2_plugin_template/templates/authentic2_plugin_template/index.html b/authentic2/src/authentic2_plugin_template/templates/authentic2_plugin_template/index.html new file mode 100644 index 0000000..5d16e06 --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/templates/authentic2_plugin_template/index.html @@ -0,0 +1 @@ +{% comment %}placeholder{% endcomment %} diff --git a/authentic2/src/authentic2_plugin_template/urls.py b/authentic2/src/authentic2_plugin_template/urls.py new file mode 100644 index 0000000..578c4c0 --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/urls.py @@ -0,0 +1,14 @@ +from django.conf.urls import patterns, url + +from authentic2.decorators import setting_enabled, required + +from . import app_settings +from .views import index + +urlpatterns = required( + setting_enabled('ENABLE', settings=app_settings), + patterns('', + url('^authentic2_plugin_template/$', index, + name='authentic2-plugin-template-index'), + ) +) diff --git a/authentic2/src/authentic2_plugin_template/views.py b/authentic2/src/authentic2_plugin_template/views.py new file mode 100644 index 0000000..ad5596b --- /dev/null +++ b/authentic2/src/authentic2_plugin_template/views.py @@ -0,0 +1,10 @@ +from django.shortcuts import render + + +from . import decorators + +__ALL_ = [ 'sso' ] + +@decorators.plugin_enabled +def index(request): + return render(request, 'authentic2_plugin_template/index.html')