improve OAuth Source Setup process, fix login template, closes #3
This commit is contained in:
parent
b40ac6dc5d
commit
33431ae013
|
@ -27,6 +27,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans 'Name' %}</th>
|
<th>{% trans 'Name' %}</th>
|
||||||
<th>{% trans 'Class' %}</th>
|
<th>{% trans 'Class' %}</th>
|
||||||
|
<th>{% trans 'Additional Info' %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ source.name }}</td>
|
<td>{{ source.name }}</td>
|
||||||
<td>{{ source|fieldtype }}</td>
|
<td>{{ source|fieldtype }}</td>
|
||||||
|
<td>{{ source.additional_info }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-default btn-sm"
|
<a class="btn btn-default btn-sm"
|
||||||
href="{% url 'passbook_admin:source-update' pk=source.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
href="{% url 'passbook_admin:source-update' pk=source.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
||||||
|
|
|
@ -155,10 +155,15 @@ class Source(PolicyModel):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_url(self):
|
def get_login_button(self):
|
||||||
"""Return URL used for logging in"""
|
"""Return a tuple of URL, Icon name and Name"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_info(self):
|
||||||
|
"""Return additional Info, such as a callback URL. Show in the administration interface."""
|
||||||
|
return None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,16 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
<div class="toast-notifications-list-pf">
|
||||||
|
{% include 'partials/messages.html' with toast=True %}
|
||||||
|
</div>
|
||||||
<div class="login-pf-page">
|
<div class="login-pf-page">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 col-md-offset-3">
|
|
||||||
{% include 'partials/messages.html' %}
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
|
<div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
|
||||||
<header class="login-pf-page-header">
|
<header class="login-pf-page-header">
|
||||||
<img class="login-pf-brand" style="max-height: 10rem;" src="{% static 'img/logo.svg' %}"
|
<img class="login-pf-brand" style="max-height: 10rem;" src="{% static 'img/logo.svg' %}"
|
||||||
alt="PatternFly logo" />
|
alt="passbook logo" />
|
||||||
{% if config.login.subtext %}
|
{% if config.login.subtext %}
|
||||||
<p>{{ config.login.subtext }}</p>
|
<p>{{ config.login.subtext }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
<h1>{% trans title %}</h1>
|
<h1>{% trans title %}</h1>
|
||||||
</header>
|
</header>
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
|
||||||
{% block above_form %}
|
{% block above_form %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% include 'partials/form_login.html' %}
|
{% include 'partials/form_login.html' %}
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
{% load static %}
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<!--[if IE 9]><html lang="en-us" class="ie9 login-pf"><![endif]-->
|
|
||||||
<!--[if gt IE 9]><!-->
|
|
||||||
<html lang="en-us" class="login-pf">
|
|
||||||
<!--<![endif]-->
|
|
||||||
<head>
|
|
||||||
<title>Login Social Account (two column) - Red Hat® Common User Experience</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}">
|
|
||||||
<!-- iPad retina icon -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="{% static 'img/apple-touch-icon-precomposed-152.png' %}">
|
|
||||||
<!-- iPad retina icon (iOS < 7) -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{% static 'img/apple-touch-icon-precomposed-144.png' %}">
|
|
||||||
<!-- iPad non-retina icon -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="{% static 'img/apple-touch-icon-precomposed-76.png' %}">
|
|
||||||
<!-- iPad non-retina icon (iOS < 7) -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="{% static 'img/apple-touch-icon-precomposed-72.png' %}">
|
|
||||||
<!-- iPhone 6 Plus icon -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="{% static 'img/apple-touch-icon-precomposed-180.png' %}">
|
|
||||||
<!-- iPhone retina icon (iOS < 7) -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="{% static 'img/apple-touch-icon-precomposed-114.png' %}">
|
|
||||||
<!-- iPhone non-retina icon (iOS < 7) -->
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="{% static 'img/apple-touch-icon-precomposed-57.png' %}">
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly.min.css' %}">
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly-additions.min.css' %}">
|
|
||||||
|
|
||||||
<script src="{% static 'js/jquery.min.js' %}"></script>
|
|
||||||
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js"></script>
|
|
||||||
<script src="{% static 'js/patternfly.min.js' %}"></script>
|
|
||||||
</head>
|
|
||||||
<div class="toast-notifications-list-pf">
|
|
||||||
<div class="toast-pf alert alert-warning alert-dismissable">
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">
|
|
||||||
<span class="pficon pficon-close"></span>
|
|
||||||
</button>
|
|
||||||
<span class="pficon pficon-warning-triangle-o"></span>
|
|
||||||
These examples are included for development testing purposes. For official documentation, see <a href="https://www.patternfly.org" class="alert-link">https://www.patternfly.org</a> and <a href="http://getbootstrap.com" class="alert-link">http://getbootstrap.com</a>.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="login-pf-page login-pf-page-accounts">
|
|
||||||
<header class="login-pf-page-header">
|
|
||||||
<img class="login-pf-brand" src="/" alt="Red Hat® logo" />
|
|
||||||
</header>
|
|
||||||
<div class="card-pf login-pf-accounts">
|
|
||||||
<header class="login-pf-header">
|
|
||||||
<select class="selectpicker">
|
|
||||||
<option>English</option>
|
|
||||||
<option>French</option>
|
|
||||||
<option>Italian</option>
|
|
||||||
</select>
|
|
||||||
<h1>Log In to Your Account</h1>
|
|
||||||
</header>
|
|
||||||
<section class="login-pf-social-section" role="contentinfo" aria-label="Log in to your patternfly account">
|
|
||||||
<form>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="sr-only" for="exampleInputEmail1">Email address</label>
|
|
||||||
<input type="email" class="form-control input-lg" id="exampleInputEmail1" placeholder="Email address">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="sr-only" for="exampleInputPassword1">Password
|
|
||||||
</label>
|
|
||||||
<input type="password" class="form-control input-lg" id="exampleInputPassword1" placeholder="Password">
|
|
||||||
</div>
|
|
||||||
<div class="login-pf-settings">
|
|
||||||
<label class="checkbox-label">
|
|
||||||
<input type="checkbox"> Keep me logged in for 30 days
|
|
||||||
</label>
|
|
||||||
<a href="#">Forgot password?</a>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary btn-block btn-lg">Log In</button>
|
|
||||||
</form>
|
|
||||||
</section><!--login-pf-section-->
|
|
||||||
<section class="login-pf-social-section" role="contentinfo" aria-label="Log in with third party account">
|
|
||||||
<ul class="login-pf-social login-pf-social-double-col list-unstyled">
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/google-logo.svg' %}" alt="Google account login">Google</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/github-logo.svg' %}" alt="github account login">Github</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/facebook-logo.svg' %}" alt="Facebook account login">Facebook</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/twitter-logo.svg' %}" alt="Twitter account login">Twitter</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/linkedin-logo.svg' %}" alt="LinkIn account login">LinkIn</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/stack-exchange-logo.svg' %}" alt="Stack Exchange logo">Stack Exchange</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/open-id-logo.svg' %}" alt="Open ID account login">Open ID</a></li>
|
|
||||||
<li class="login-pf-social-link"><a href="#"><img src="{% static 'img/instagram-logo.png' %}" alt="Instagram account login">Instagram</a></li>
|
|
||||||
<li class="login-pf-social-link login-pf-social-link-more"><a href="#"><img src="{% static 'img/git-logo.svg' %}" alt="Git account login">Git</a></li>
|
|
||||||
<li class="login-pf-social-link login-pf-social-link-more"><a href="#"><img src="{% static 'img/dropbox-logo.svg' %}" alt="dropbox account login">Dropbox</a></li>
|
|
||||||
<li class="login-pf-social-link login-pf-social-link-more"><a href="#"><img src="{% static 'img/fedora-logo.png' %}" alt="fedora account login">Fedora</a></li>
|
|
||||||
<li class="login-pf-social-link login-pf-social-link-more"><a href="#"><img src="{% static 'img/skype-logo.svg' %}" alt="skype account logingit ">Skype</a></li>
|
|
||||||
</ul>
|
|
||||||
<button type="button" id="socialAccountsToggle" class="btn btn-link login-pf-social-toggle">More<span class="caret"></span></button>
|
|
||||||
</section><!--login-pf-section-->
|
|
||||||
<p class="login-pf-signup">Need an account?<a href="#">Sign up</a></p>
|
|
||||||
</div><!-- card -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 col-md-offset-3">
|
|
||||||
<footer class="login-pf-page-footer">
|
|
||||||
<ul class="login-pf-page-footer-links list-unstyled">
|
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Terms of Use</a></li>
|
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Help</a></li>
|
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Privacy Policy</a></li>
|
|
||||||
</ul>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div><!-- login-pf-page -->
|
|
||||||
<script>
|
|
||||||
$("#socialAccountsToggle").on("click", function(e) {
|
|
||||||
var $toggle = $(e.target);
|
|
||||||
var text = $toggle.contents().first()[0];
|
|
||||||
var socialContainer = $('.login-pf-social-section > .login-pf-social');
|
|
||||||
|
|
||||||
if ($toggle.hasClass('login-pf-social-toggle-active')) {
|
|
||||||
$toggle.removeClass('login-pf-social-toggle-active');
|
|
||||||
text.textContent = 'More';
|
|
||||||
socialContainer.removeClass('login-pf-social-all');
|
|
||||||
} else {
|
|
||||||
$toggle.addClass('login-pf-social-toggle-active');
|
|
||||||
text.textContent = 'Less';
|
|
||||||
socialContainer.addClass('login-pf-social-all');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,45 +1,71 @@
|
||||||
{% extends 'login/base.html' %}
|
{% extends 'base/skeleton.html' %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block row %}
|
{% block head %}
|
||||||
{% include 'partials/messages.html' %}
|
<style>
|
||||||
<div class="col-md-6">
|
.login-pf-page .login-pf-page-footer-links {
|
||||||
<div class="card-pf">
|
padding: 15px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-top: 2px solid transparent;
|
||||||
|
box-shadow: 0 1px 1px rgba(3, 3, 3, .175);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-pf-page .login-pf-page-footer-link {
|
||||||
|
color: #72767b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-pf-page .login-pf-page-footer-links li:not(:last-of-type):after {
|
||||||
|
color: #72767b;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="toast-notifications-list-pf">
|
||||||
|
{% include 'partials/messages.html' with toast=True %}
|
||||||
|
</div>
|
||||||
|
<div class="login-pf-page login-pf-page-accounts">
|
||||||
|
<header class="login-pf-page-header">
|
||||||
|
<img class="login-pf-brand" style="max-height: 10rem;" src="{% static 'img/logo.svg' %}" alt="passbook logo" />
|
||||||
|
{% if config.login.subtext %}
|
||||||
|
<p>{{ config.login.subtext }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</header>
|
||||||
|
<div class="card-pf login-pf-accounts">
|
||||||
<header class="login-pf-header">
|
<header class="login-pf-header">
|
||||||
<h1>{% trans title %}</h1>
|
<h1>{% trans title %}</h1>
|
||||||
</header>
|
</header>
|
||||||
|
<section class="login-pf-social-section" role="contentinfo" aria-label="Log in to your patternfly account">
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
|
||||||
{% block above_form %}
|
{% block above_form %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% include 'partials/form_login.html' %}
|
{% include 'partials/form_login.html' %}
|
||||||
<button type="submit" class="btn btn-primary btn-block btn-lg">{% trans primary_action %}</button>
|
<button type="submit" class="btn btn-primary btn-block btn-lg">{% trans primary_action %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
</section>
|
||||||
|
<!--login-pf-section-->
|
||||||
|
<section class="login-pf-social-section" role="contentinfo" aria-label="Log in with third party account">
|
||||||
|
<ul class="login-pf-social login-pf-social-double-col list-unstyled">
|
||||||
|
{% for url, icon, name in sources %}
|
||||||
|
<li class="login-pf-social-link">
|
||||||
|
<a href="{{ url }}">
|
||||||
|
<img src="{% static 'img/' %}{{ icon }}.svg" alt="{{ name }}"> {{ name }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
{% if show_sign_up_notice %}
|
{% if show_sign_up_notice %}
|
||||||
<p class="login-pf-signup">
|
<p class="login-pf-signup">
|
||||||
{% trans 'Need an account?' %}
|
{% trans 'Need an account?' %}
|
||||||
<a href="{% url 'passbook_core:auth-sign-up' %}">{% trans 'Sign up' %}</a>
|
<a href="{% url 'passbook_core:auth-sign-up' %}">{% trans 'Sign up' %}</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div><!-- card -->
|
||||||
</div>
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6 col-md-offset-3">
|
||||||
<div class="card-pf">
|
|
||||||
<header class="login-pf-header">
|
|
||||||
<h1>{% trans title %}</h1>
|
|
||||||
<ul>
|
|
||||||
{% for source in sources %}
|
|
||||||
<li>
|
|
||||||
<a class="btn btn-block btn-primary" href="{{ source.get_url }}">{{ source }}</a>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2">
|
|
||||||
<footer class="login-pf-page-footer">
|
<footer class="login-pf-page-footer">
|
||||||
<ul class="login-pf-page-footer-links list-unstyled">
|
<ul class="login-pf-page-footer-links list-unstyled">
|
||||||
<li><a class="login-pf-page-footer-link" href="#">Terms of Use</a></li>
|
<li><a class="login-pf-page-footer-link" href="#">Terms of Use</a></li>
|
||||||
|
@ -48,4 +74,6 @@
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -42,9 +42,12 @@ class LoginView(UserPassesTestMixin, FormView):
|
||||||
kwargs['primary_action'] = _('Log in')
|
kwargs['primary_action'] = _('Log in')
|
||||||
kwargs['show_sign_up_notice'] = CONFIG.y('passbook.sign_up.enabled')
|
kwargs['show_sign_up_notice'] = CONFIG.y('passbook.sign_up.enabled')
|
||||||
kwargs['show_password_forget_notice'] = CONFIG.y('passbook.password_reset.enabled')
|
kwargs['show_password_forget_notice'] = CONFIG.y('passbook.password_reset.enabled')
|
||||||
kwargs['sources'] = Source.objects.filter(enabled=True).select_subclasses()
|
kwargs['sources'] = []
|
||||||
if any(source.is_link for source in kwargs['sources']):
|
sources = Source.objects.filter(enabled=True).select_subclasses()
|
||||||
self.template_name = 'login/test.html'
|
if any(source.is_link for source in sources):
|
||||||
|
for source in sources:
|
||||||
|
kwargs['sources'].append(source.get_login_button)
|
||||||
|
self.template_name = 'login/with_sources.html'
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
def get_user(self, uid_value) -> User:
|
def get_user(self, uid_value) -> User:
|
||||||
|
|
|
@ -26,8 +26,16 @@ class OAuthSource(Source):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_url(self):
|
def get_login_button(self):
|
||||||
return reverse_lazy('passbook_oauth_client:oauth-client-login',
|
url = reverse_lazy('passbook_oauth_client:oauth-client-login',
|
||||||
|
kwargs={'source_slug': self.slug})
|
||||||
|
if self.provider_type == 'github':
|
||||||
|
return url, 'github-logo', _('GitHub')
|
||||||
|
return url, 'generic', _('Generic')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_info(self):
|
||||||
|
return "Callback URL: '%s'" % reverse_lazy('passbook_oauth_client:oauth-client-callback',
|
||||||
kwargs={'source_slug': self.slug})
|
kwargs={'source_slug': self.slug})
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
Reference in New Issue