Add authentication from upstream providers (#107)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Let BasicOIDC delegate authentication to upstream providers (Google, GitHub, GitLab, Keycloak...) Reviewed-on: #107
This commit is contained in:
@ -5,27 +5,27 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">User ID</th>
|
||||
<td>{{ u.uid.0 }}</td>
|
||||
<td>{{ _p.user.uid.0 }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">First name</th>
|
||||
<td>{{ u.first_name }}</td>
|
||||
<td>{{ _p.user.first_name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Last name</th>
|
||||
<td>{{ u.last_name }}</td>
|
||||
<td>{{ _p.user.last_name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Username</th>
|
||||
<td>{{ u.username }}</td>
|
||||
<td>{{ _p.user.username }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Email</th>
|
||||
<td>{{ u.email }}</td>
|
||||
<td>{{ _p.user.email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Account type</th>
|
||||
<td>{% if u.admin %}Admin{% else %}Regular user{% endif %}</td>
|
||||
<td>{% if _p.user.admin %}Admin{% else %}Regular user{% endif %}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -14,8 +14,8 @@
|
||||
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-dark text-decoration-none">
|
||||
<span class="fs-4">{{ _p.app_name }}</span>
|
||||
</a>
|
||||
{% if _p.is_admin %}
|
||||
<span>Version {{ _p.version }}</span>
|
||||
{% if _p.user.admin %}
|
||||
<span>Version {{ _p.version }}</span>
|
||||
{% endif %}
|
||||
<hr>
|
||||
<ul class="nav nav-pills flex-column mb-auto">
|
||||
@ -24,24 +24,31 @@
|
||||
Account details
|
||||
</a>
|
||||
</li>
|
||||
{% if _p.user.allow_local_login %}
|
||||
<li>
|
||||
<a href="/settings/change_password" class="nav-link link-dark">
|
||||
Change password
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="/settings/two_factors" class="nav-link link-dark">
|
||||
Two-factor authentication
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if _p.is_admin %}
|
||||
{% if _p.user.admin %}
|
||||
<hr/>
|
||||
<li>
|
||||
<a href="/admin/clients" class="nav-link link-dark">
|
||||
Clients
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/providers" class="nav-link link-dark">
|
||||
Providers
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/users" class="nav-link link-dark">
|
||||
Users
|
||||
@ -54,7 +61,7 @@
|
||||
<a href="#" class="d-flex align-items-center link-dark text-decoration-none dropdown-toggle" id="dropdownUser"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<img src="/assets/img/account.png" alt="" width="32" height="32" class="rounded-circle me-2">
|
||||
<strong>{{ _p.user_name }}</strong>
|
||||
<strong>{{ _p.user.username }}</strong>
|
||||
</a>
|
||||
<ul class="dropdown-menu text-small shadow" aria-labelledby="dropdownUser">
|
||||
<li><a class="dropdown-item" href="/logout">Sign out</a></li>
|
||||
@ -83,6 +90,7 @@
|
||||
if(el.href === location.href) el.classList.add("active");
|
||||
else el.classList.remove("active")
|
||||
})
|
||||
|
||||
</script>
|
||||
{% if _p.ip_location_api.is_some() %}
|
||||
<script>const IP_LOCATION_API = "{{ _p.ip_location_api.unwrap() }}"</script>
|
||||
|
@ -112,28 +112,61 @@
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
{% for e in u.get_formatted_2fa_successful_logins() %}
|
||||
{% if e.can_bypass_2fa %}<li style="font-weight: bold;">{{ e.ip }} - {{ e.fmt_time() }} - BYPASS 2FA</li>
|
||||
{% else %}<li>{{ e.ip }} - {{ e.fmt_time() }}</li>{% endif %}
|
||||
{% endfor %}
|
||||
{% for e in u.get_formatted_2fa_successful_logins() %}
|
||||
{% if e.can_bypass_2fa %}
|
||||
<li style="font-weight: bold;">{{ e.ip }} - {{ e.fmt_time() }} - BYPASS 2FA</li>
|
||||
{% else %}
|
||||
<li>{{ e.ip }} - {{ e.fmt_time() }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
|
||||
<!-- Authorized authentication sources -->
|
||||
<fieldset class="form-group">
|
||||
<legend class="mt-4">Authorized authentication sources</legend>
|
||||
|
||||
<!-- Local login -->
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="allow_local_login" id="allow_local_login"
|
||||
{% if u.allow_local_login %} checked="" {% endif %}>
|
||||
<label class="form-check-label" for="allow_local_login">
|
||||
Allow local login
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Upstream providers -->
|
||||
<input type="hidden" name="authorized_sources" id="authorized_sources"/>
|
||||
{% for prov in providers %}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input authorized_provider" type="checkbox" name="prov-{{ prov.id.0 }}"
|
||||
id="prov-{{ prov.id.0 }}"
|
||||
data-id="{{ prov.id.0 }}"
|
||||
{% if u.can_login_from_provider(prov) %} checked="" {% endif %}>
|
||||
<label class="form-check-label" for="prov-{{ prov.id.0 }}">
|
||||
Allow login from {{ prov.name }}
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
|
||||
<!-- Granted clients -->
|
||||
<fieldset class="form-group">
|
||||
<legend class="mt-4">Granted clients</legend>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input type="radio" class="form-check-input" name="grant_type"
|
||||
value="all_clients" {% if u.granted_clients() == GrantedClients::AllClients %} checked="" {% endif %}>
|
||||
value="all_clients" {% if u.granted_clients()== GrantedClients::AllClients %} checked="" {% endif
|
||||
%}>
|
||||
Grant all clients
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input type="radio" class="form-check-input" name="grant_type"
|
||||
value="custom_clients" {% if matches!(self.u.granted_clients(), GrantedClients::SomeClients(_)) %} checked="checked" {% endif %}>
|
||||
value="custom_clients" {% if matches!(self.u.granted_clients(), GrantedClients::SomeClients(_))
|
||||
%} checked="checked" {% endif %}>
|
||||
Manually specify allowed clients
|
||||
</label>
|
||||
</div>
|
||||
@ -155,7 +188,8 @@
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input type="radio" class="form-check-input" name="grant_type"
|
||||
value="no_client" {% if u.granted_clients() == GrantedClients::NoClient %} checked="checked" {% endif %}>
|
||||
value="no_client" {% if u.granted_clients()== GrantedClients::NoClient %} checked="checked" {%
|
||||
endif %}>
|
||||
Do not grant any client
|
||||
</label>
|
||||
</div>
|
||||
@ -215,6 +249,13 @@
|
||||
form.addEventListener("submit", (ev) => {
|
||||
ev.preventDefault();
|
||||
|
||||
const authorized_sources = [...document.querySelectorAll(".authorized_provider")]
|
||||
.filter(e => e.checked)
|
||||
.map(e => e.getAttribute("data-id")).join(",")
|
||||
|
||||
document.querySelector("input[name=authorized_sources]").value = authorized_sources;
|
||||
|
||||
|
||||
const authorized_clients = [...document.querySelectorAll(".authorize_client_checkbox")]
|
||||
.filter(e => e.checked)
|
||||
.map(e => e.getAttribute("data-id")).join(",")
|
||||
@ -231,6 +272,9 @@
|
||||
form.submit();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock content %}
|
39
templates/settings/providers_list.html
Normal file
39
templates/settings/providers_list.html
Normal file
@ -0,0 +1,39 @@
|
||||
{% extends "base_settings_page.html" %}
|
||||
{% block content %}
|
||||
|
||||
<style>
|
||||
#providers td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<table id="providers" class="table table-hover" style="max-width: 800px;" aria-describedby="OpenID providers list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Configuration URL</th>
|
||||
<th scope="col">Client ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in providers %}
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ c.logo_url() }}" alt="{{ c.name }} logo" width="30px"/>
|
||||
</td>
|
||||
<td>{{ c.id.0 }}</td>
|
||||
<td>{{ c.name }}</td>
|
||||
<td><a href="{{ c.configuration_url }}" target="_blank" rel="noreferrer">
|
||||
{{ c.configuration_url }}
|
||||
</a></td>
|
||||
<td>{{ c.client_id }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Redirect URL for new clients: {{ redirect_url }}</p>
|
||||
|
||||
{% endblock content %}
|
Reference in New Issue
Block a user