Many broken things

This commit is contained in:
Jens Langhammer
2018-11-16 09:10:35 +01:00
parent 79490984d1
commit fbaab4efaf
104 changed files with 3056 additions and 63 deletions

View File

@ -1,11 +1,13 @@
# Generated by Django 2.1.3 on 2018-11-11 08:22
# Generated by Django 2.1.3 on 2018-11-11 14:06
import uuid
from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
@ -45,9 +47,9 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Application',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.TextField()),
('launch_url', models.URLField(blank=True, null=True)),
('icon_url', models.TextField(blank=True, null=True)),
@ -59,9 +61,9 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Rule',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.TextField(blank=True, null=True)),
('action', models.CharField(choices=[('allow', 'allow'), ('deny', 'deny')], max_length=20)),
('negate', models.BooleanField(default=False)),
@ -73,9 +75,9 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Source',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.TextField()),
('slug', models.SlugField()),
('enabled', models.BooleanField(default=True)),

View File

@ -5,8 +5,9 @@ from logging import getLogger
import reversion
from django.contrib.auth.models import AbstractUser
from django.db import models
from model_utils.managers import InheritanceManager
from passbook.lib.models import CastableModel, CreatedUpdatedModel
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
LOGGER = getLogger(__name__)
@ -17,7 +18,7 @@ class User(AbstractUser):
sources = models.ManyToManyField('Source', through='UserSourceConnection')
@reversion.register()
class Application(CastableModel, CreatedUpdatedModel):
class Application(UUIDModel, CreatedUpdatedModel):
"""Every Application which uses passbook for authentication/identification/authorization
needs an Application record. Other authentication types can subclass this Model to
add custom fields and other properties"""
@ -26,6 +27,8 @@ class Application(CastableModel, CreatedUpdatedModel):
launch_url = models.URLField(null=True, blank=True)
icon_url = models.TextField(null=True, blank=True)
objects = InheritanceManager()
def user_is_authorized(self, user: User) -> bool:
"""Check if user is authorized to use this application"""
raise NotImplementedError()
@ -34,14 +37,16 @@ class Application(CastableModel, CreatedUpdatedModel):
return self.name
@reversion.register()
class Source(CastableModel, CreatedUpdatedModel):
class Source(UUIDModel, CreatedUpdatedModel):
"""Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server"""
name = models.TextField()
slug = models.SlugField()
form = None # ModelForm-based class ued to create/edit instance
form = '' # ModelForm-based class ued to create/edit instance
enabled = models.BooleanField(default=True)
objects = InheritanceManager()
def __str__(self):
return self.name
@ -57,7 +62,7 @@ class UserSourceConnection(CreatedUpdatedModel):
unique_together = (('user', 'source'),)
@reversion.register()
class Rule(CastableModel, CreatedUpdatedModel):
class Rule(UUIDModel, CreatedUpdatedModel):
"""Rules which specify if a user is authorized to use an Application. Can be overridden by
other types to add other fields, more logic, etc."""
@ -73,6 +78,8 @@ class Rule(CastableModel, CreatedUpdatedModel):
action = models.CharField(max_length=20, choices=ACTIONS)
negate = models.BooleanField(default=False)
objects = InheritanceManager()
def __str__(self):
if self.name:
return self.name

View File

@ -2,3 +2,6 @@ django>=2.0
django-reversion
PyYAML
raven
djangorestframework
markdown
django-model-utils

View File

@ -10,10 +10,12 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import importlib
import os
from passbook.lib.config import CONFIG
from passbook import __version__
from passbook.lib.config import CONFIG
VERSION = __version__
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
@ -30,7 +32,7 @@ DEBUG = True
INTERNAL_IPS = ['127.0.0.1']
ALLOWED_HOSTS = []
LOGIN_URL = 'auth-login'
LOGIN_URL = 'passbook_core:auth-login'
# Custom user model
AUTH_USER_MODEL = 'passbook_core.User'
@ -41,7 +43,6 @@ AUTHENTICATION_BACKENDS = [
'passbook.oauth_client.backends.AuthorizedServiceBackend'
]
# Application definition
INSTALLED_APPS = [
@ -54,11 +55,21 @@ INSTALLED_APPS = [
'reversion',
'passbook.core',
'passbook.admin',
'rest_framework',
'passbook.lib',
'passbook.ldap',
'passbook.oauth_client',
'passbook.oauth_provider',
]
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@ -133,6 +144,8 @@ USE_L10N = True
USE_TZ = True
OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
@ -230,3 +243,18 @@ with CONFIG.cd('log'):
if DEBUG:
INSTALLED_APPS.append('debug_toolbar')
MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware')
# Load subapps's INSTALLED_APPS
for _app in INSTALLED_APPS:
if _app.startswith('passbook') and \
not _app.startswith('passbook.core'):
if 'apps' in _app:
_app = '.'.join(_app.split('.')[:-2])
try:
app_settings = importlib.import_module("%s.settings" % _app)
INSTALLED_APPS.extend(getattr(app_settings, 'INSTALLED_APPS', []))
MIDDLEWARE.extend(getattr(app_settings, 'MIDDLEWARE', []))
AUTHENTICATION_BACKENDS.extend(getattr(app_settings, 'AUTHENTICATION_BACKENDS', []))
except ImportError:
pass

View File

@ -2,11 +2,9 @@
{% load static %}
{% load i18n %}
{% load is_active %}
{% block body %}
{% load static %}
{% load i18n %}
<nav class="navbar navbar-default navbar-pf" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse-1">
@ -55,20 +53,21 @@
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-primary persistent-secondary">
<ul class="nav navbar-nav navbar-primary">
{# FIXME: Detect active application #}
<li class="active">
<a href="#0">{% trans 'Overview' %}</a>
<li class="{% is_active_app 'passbook_core' %}">
<a href="{% url 'passbook_core:overview' %}">{% trans 'Overview' %}</a>
</li>
<li class="{% is_active_app 'passbook_admin' %}">
<a href="{% url 'passbook_admin:overview' %}">{% trans 'Administration' %}</a>
{% block nav_secondary %}
{% endblock %}
</li>
<li>
<a href="#0">{% trans 'Administration' %}</a>
</li>
</ul>
</div>
</nav>
<div class="container-fluid container-cards-pf">
{% include 'partials/messages.html' %}
{% block content %}
{% endblock %}
</div>

View File

@ -0,0 +1,11 @@
{% if messages %}
{% for msg in messages %}
<div class="alert alert-{{ msg.level_tag }}">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="pficon pficon-close"></span>
</button>
<span class="pficon pficon-{{ msg.level_tag }}"></span>
<strong>{{ msg.message|safe }}</strong>
</div>
{% endfor %}
{% endif %}

View File

@ -8,15 +8,25 @@ from django.views.generic import RedirectView
from passbook.core.views import authentication, overview
admin.autodiscover()
admin.site.login = RedirectView.as_view(pattern_name='auth-login')
admin.site.login = RedirectView.as_view(pattern_name='passbook_core:auth-login')
urlpatterns = [
core_urls = [
path('auth/login/', authentication.LoginView.as_view(), name='auth-login'),
path('', overview.OverviewView.as_view(), name='overview'),
]
urlpatterns = [
# Core
path('', include((core_urls, 'passbook_core'), namespace='passbook_core')),
# Administration
path('administration/django/', admin.site.urls),
path('administration/', include('passbook.admin.urls')),
path('', include('passbook.oauth_client.urls')),
path('administration/',
include(('passbook.admin.urls', 'passbook_admin'), namespace='passbook_admin')),
path('source/oauth/', include(('passbook.oauth_client.urls',
'passbook_oauth_client'), namespace='passbook_oauth_client')),
path('application/oauth', include(('passbook.oauth_provider.urls',
'passbook_oauth_provider'),
namespace='passbook_oauth_provider')),
]
if settings.DEBUG:

View File

@ -84,7 +84,7 @@ class LoginView(UserPassesTestMixin, FormView):
if 'next' in request.GET:
return redirect(request.GET.get('next'))
# Otherwise just index
return redirect(reverse('overview'))
return redirect(reverse('passbook_core:overview'))
@staticmethod
def invalid_login(request: HttpRequest, disabled_user: User = None) -> HttpResponse: