add user settings for Sources
This commit is contained in:
parent
e98e5e4e3e
commit
ae3c092238
|
@ -186,6 +186,12 @@ class Source(PolicyModel):
|
|||
"""Return additional Info, such as a callback URL. Show in the administration interface."""
|
||||
return None
|
||||
|
||||
def has_user_settings(self):
|
||||
"""Entrypoint to integrate with User settings. Can either return False if no
|
||||
user settings are available, or a tuple or string, string, string where the first string
|
||||
is the name the item has, the second string is the icon and the third is the view-name."""
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<li class="dropdown">
|
||||
<button class="btn btn-link dropdown-toggle nav-item-iconic" id="dropdownMenu1" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<span title="Help" class="fa pficon-help dropdown-title"></span>
|
||||
<span title="Help" class="fa pficon-help"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
{% comment %} <li><a href="#0">Help</a></li> {% endcomment %}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
{% load i18n %}
|
||||
{% load is_active %}
|
||||
{% load static %}
|
||||
{% load passbook_user_settings %}
|
||||
|
||||
{% block content %}
|
||||
|
@ -24,6 +25,15 @@
|
|||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="nav-divider"></li>
|
||||
{% user_sources as us %}
|
||||
{% for name, icon, link in us %}
|
||||
<li class="{% if link == request.get_full_path %} active {% endif %}">
|
||||
<a href="{{ link }}">
|
||||
<img src="{% static icon %}" alt=""> {{ name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from django import template
|
||||
|
||||
from passbook.core.models import Factor
|
||||
from passbook.core.models import Factor, Source
|
||||
from passbook.core.policies import PolicyEngine
|
||||
|
||||
register = template.Library()
|
||||
|
@ -20,3 +20,17 @@ def user_factors(context):
|
|||
if policy_engine.passing and _link:
|
||||
matching_factors.append(_link)
|
||||
return matching_factors
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def user_sources(context):
|
||||
"""Return a list of all sources which are enabled for the user"""
|
||||
user = context.get('request').user
|
||||
_all_sources = Source.objects.filter(enabled=True).select_subclasses()
|
||||
matching_sources = []
|
||||
for factor in _all_sources:
|
||||
_link = factor.has_user_settings()
|
||||
policy_engine = PolicyEngine(factor.policies.all())
|
||||
policy_engine.for_user(user).with_request(context.get('request')).build()
|
||||
if policy_engine.passing and _link:
|
||||
matching_sources.append(_link)
|
||||
return matching_sources
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""OAuth Client models"""
|
||||
|
||||
from django.db import models
|
||||
from django.urls import reverse_lazy
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from passbook.core.models import Source, UserSourceConnection
|
||||
|
@ -38,6 +38,16 @@ class OAuthSource(Source):
|
|||
return "Callback URL: '%s'" % reverse_lazy('passbook_oauth_client:oauth-client-callback',
|
||||
kwargs={'source_slug': self.slug})
|
||||
|
||||
def has_user_settings(self):
|
||||
"""Entrypoint to integrate with User settings. Can either return False if no
|
||||
user settings are available, or a tuple or string, string, string where the first string
|
||||
is the name the item has, the second string is the icon and the third is the view-name."""
|
||||
icon = 'img/%s.svg' % self.get_login_button[1]
|
||||
view_name = 'passbook_oauth_client:oauth-client-user'
|
||||
return self.name, icon, reverse((view_name), kwargs={
|
||||
'source_slug': self.slug
|
||||
})
|
||||
|
||||
class Meta:
|
||||
|
||||
verbose_name = _('Generic OAuth Source')
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
|
||||
{% any_provider as enabled %}
|
||||
{% if enabled %}
|
||||
<div class="btn-group btn-primary btn-block">
|
||||
{% endif %}
|
|
@ -1,6 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
|
||||
{% provider_exists 'facebook' as facebook_enabled %}
|
||||
{% if facebook_enabled %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider='facebook' %}" class="btn" style="background-color:#4267b2;color:white;margin-top:10px;width:100%;"><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
|
||||
{% endif %}
|
|
@ -1,6 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
|
||||
{% provider_exists 'twitter' as twitter_enabled %}
|
||||
{% if twitter_enabled %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider='twitter' %}" class="btn" style="background-color:#55ACEE;color:white;margin-top:10px;width:100%;"><i class="fa fa-twitter" aria-hidden="true"></i></a>
|
||||
{% endif %}
|
|
@ -1,7 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
{% load static %}
|
||||
|
||||
{% provider_exists 'google' as google_enabled %}
|
||||
{% if google_enabled %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider='google' %}" class="btn" style="background-color:white;color:black;margin-top:10px;width:100%;"><img src="{% static 'img/google.svg' %}" style="height:12px"></a>
|
||||
{% endif %}
|
|
@ -1,6 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
|
||||
{% provider_exists 'github' as github_enabled %}
|
||||
{% if github_enabled %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider='github' %}" class="btn" style="background-color:#444444;color:white;margin-top:10px;width:100%;"><i class="fa fa-github" aria-hidden="true"></i></a>
|
||||
{% endif %}
|
|
@ -1,7 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
{% load static %}
|
||||
|
||||
{% provider_exists 'discord' as discord_enabled %}
|
||||
{% if discord_enabled %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider='discord' %}" class="btn" style="background-color:#2C2F33;color:white;margin-top:10px;width:100%;"><img src="{% static 'img/discord.svg' %}" style="height:12px"></a>
|
||||
{% endif %}
|
|
@ -1,7 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
{% load static %}
|
||||
|
||||
{% provider_exists 'reddit' as reddit_enabled %}
|
||||
{% if reddit_enabled %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider='reddit' %}" class="btn" style="background-color:#ff4500;color:white;margin-top:10px;width:100%;"><img src="{% static 'img/reddit.svg' %}" style="height:20px;margin-top:-5px;"></a>
|
||||
{% endif %}
|
|
@ -1,6 +0,0 @@
|
|||
{% load passbook_oauth_client %}
|
||||
|
||||
{% any_provider as enabled %}
|
||||
{% if enabled %}
|
||||
</div>
|
||||
{% endif %}
|
|
@ -1,54 +0,0 @@
|
|||
{% extends "user/base.html" %}
|
||||
|
||||
{% load utils %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% title "Overview" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1><clr-icon shape="connect" size="48"></clr-icon>{% trans "OAuth2" %}</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{% trans "Connected Accounts" %}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
{% if provider_state %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>
|
||||
<th>{% trans 'Provider' %}</th>
|
||||
<th>{% trans 'Status' %}</th>
|
||||
<th>{% trans 'Action' %}</th>
|
||||
<th>{% trans 'ID' %}</th>
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for data in provider_state %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans data.provider.ui_name %}</td>
|
||||
<td>{{ data.state|yesno:"Connected,Not Connected" }}</td>
|
||||
<td>
|
||||
{% if data.state == False %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-login' provider=data.provider.name %}">Connect</a>
|
||||
{% else %}
|
||||
<a href="{% url 'passbook_oauth_client:oauth-client-disconnect' provider=data.provider.name %}">Disconnect</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ data.aas.first.identifier }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{% trans "No Providers configured!" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,18 @@
|
|||
{% extends "user/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block page %}
|
||||
<h1>{{ source.name }}</h1>
|
||||
{% if connections.exists %}
|
||||
<p>{% trans 'Connected.' %}</p>
|
||||
<a class="btn btn-danger" href="{% url 'passbook_oauth_client:oauth-client-disconnect' source_slug=source.slug %}">
|
||||
{% trans 'Disconnect' %}
|
||||
</a>
|
||||
{% else %}
|
||||
<p>Not connected.</p>
|
||||
<a class="btn btn-primary" href="{% url 'passbook_oauth_client:oauth-client-login' source_slug=source.slug %}">
|
||||
{% trans 'Connect' %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -3,7 +3,7 @@
|
|||
from django.urls import path
|
||||
|
||||
from passbook.oauth_client.source_types.manager import RequestKind
|
||||
from passbook.oauth_client.views import core, dispatcher
|
||||
from passbook.oauth_client.views import core, dispatcher, user
|
||||
|
||||
urlpatterns = [
|
||||
path('login/<slug:source_slug>/', dispatcher.DispatcherView.as_view(
|
||||
|
@ -12,4 +12,6 @@ urlpatterns = [
|
|||
kind=RequestKind.callback), name='oauth-client-callback'),
|
||||
path('disconnect/<slug:source_slug>/', core.DisconnectView.as_view(),
|
||||
name='oauth-client-disconnect'),
|
||||
path('user/<slug:source_slug>/', user.UserSettingsView.as_view(),
|
||||
name='oauth-client-user'),
|
||||
]
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"""passbook oauth_client user views"""
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from passbook.oauth_client.models import OAuthSource, UserOAuthSourceConnection
|
||||
|
||||
|
||||
class UserSettingsView(LoginRequiredMixin, TemplateView):
|
||||
"""Show user current connection state"""
|
||||
|
||||
template_name = 'oauth_client/user.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
source = get_object_or_404(OAuthSource, slug=self.kwargs.get('source_slug'))
|
||||
connections = UserOAuthSourceConnection.objects.filter(user=self.request.user,
|
||||
source=source)
|
||||
kwargs['source'] = source
|
||||
kwargs['connections'] = connections
|
||||
return super().get_context_data(**kwargs)
|
Reference in New Issue