Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/configuration/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ The lifetime (in seconds) of the authentication cookie issued to a NetBox user u

---

## LOGIN_FORM_HIDDEN

Default: False

Option to hide the login form when only SSO authentication is in use. Appending `skipsso` as GET parameter shows the login form in case there is a problem with the SSO provider.

---

## LOGOUT_REDIRECT_URL

Default: `'home'`
Expand Down
2 changes: 2 additions & 0 deletions netbox/account/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@ def get(self, request):
if request.user.is_authenticated:
logger = logging.getLogger('netbox.auth.login')
return self.redirect_to_next(request, logger)
login_form_hidden = settings.LOGIN_FORM_HIDDEN and "skipsso" not in request.GET

return render(request, self.template_name, {
'form': form,
'auth_backends': self.get_auth_backends(request),
'login_form_hidden': login_form_hidden,
})

def post(self, request):
Expand Down
3 changes: 3 additions & 0 deletions netbox/netbox/configuration_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@
# re-authenticate. (Default: 1209600 [14 days])
LOGIN_TIMEOUT = None

# Hide the login form. Useful when only allowing SSO authentication.
LOGIN_FORM_HIDDEN = False

# The view name or URL to which users are redirected after logging out.
LOGOUT_REDIRECT_URL = 'home'

Expand Down
1 change: 1 addition & 0 deletions netbox/netbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
LOGIN_PERSISTENCE = getattr(configuration, 'LOGIN_PERSISTENCE', False)
LOGIN_REQUIRED = getattr(configuration, 'LOGIN_REQUIRED', True)
LOGIN_TIMEOUT = getattr(configuration, 'LOGIN_TIMEOUT', None)
LOGIN_FORM_HIDDEN = getattr(configuration, 'LOGIN_FORM_HIDDEN', False)
LOGOUT_REDIRECT_URL = getattr(configuration, 'LOGOUT_REDIRECT_URL', 'home')
MEDIA_ROOT = getattr(configuration, 'MEDIA_ROOT', os.path.join(BASE_DIR, 'media')).rstrip('/')
METRICS_ENABLED = getattr(configuration, 'METRICS_ENABLED', False)
Expand Down
73 changes: 40 additions & 33 deletions netbox/templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,48 +34,55 @@ <h4 class="alert-heading">{% trans "Errors" %}</h4>
{% endif %}

<div class="card card-md">
<div class="card-body">
<h2 class="text-center mb-4">{% trans "Log In" %}</h2>
{% if not login_form_hidden %}
<div class="card-body">
<h2 class="text-center mb-4">{% trans "Log In" %}</h2>

{# Login form #}
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
{# Login form #}
<form action="{% url 'login' %}" method="post">
{% csrf_token %}

{# Set post-login URL #}
{% if 'next' in request.GET %}
<input type="hidden" name="next" value="{{ request.GET.next }}" />
{% elif 'next' in request.POST %}
<input type="hidden" name="next" value="{{ request.POST.next }}" />
{% endif %}
{# Set post-login URL #}
{% if 'next' in request.GET %}
<input type="hidden" name="next" value="{{ request.GET.next }}" />
{% elif 'next' in request.POST %}
<input type="hidden" name="next" value="{{ request.POST.next }}" />
{% endif %}

<div class="form-group mb-3">
<label for="id_username" class="form-label">{{ form.username.label }}</label>
{{ form.username }}
{% for error in form.username.errors %}
<div class="alert alert-danger">{{ error }}</div>
{% endfor %}
</div>
<div class="form-group mb-3">
<label for="id_username" class="form-label">{{ form.username.label }}</label>
{{ form.username }}
{% for error in form.username.errors %}
<div class="alert alert-danger">{{ error }}</div>
{% endfor %}
</div>

<div class="form-group">
<label for="id_password" class="form-label">{{ form.password.label }}</label>
{{ form.password }}
{% for error in form.password.errors %}
<div class="alert alert-danger">{{ error }}</div>
{% endfor %}
</div>
<div class="form-group">
<label for="id_password" class="form-label">{{ form.password.label }}</label>
{{ form.password }}
{% for error in form.password.errors %}
<div class="alert alert-danger">{{ error }}</div>
{% endfor %}
</div>

<div class="form-footer">
<button type="submit" class="btn btn-primary w-100">
{% trans "Sign In" %}
</button>
</div>
</form>
</div>
<div class="form-footer">
<button type="submit" class="btn btn-primary w-100">
{% trans "Sign In" %}
</button>
</div>
</form>
</div>
{% endif %}

{# SSO login #}
{% if auth_backends %}
<div class="hr-text">{% trans "Or" context "Denotes an alternative option" %}</div>
{% if not login_form_hidden %}
<div class="hr-text">{% trans "Or" context "Denotes an alternative option" %}</div>
{% endif %}
<div class="card-body">
{% if login_form_hidden %}
<h2 class="text-center mb-4">{% trans "Log In" %}</h2>
{% endif %}
<div class="row">
{% for backend in auth_backends %}
<div class="col">
Expand Down
Loading