Add google login and view for public services (#533)

* add login using google login
* Add `is_public flag` to services
* Add public view for services marked as public
* Add base_public.html for unauthenticated users and use that with authenticated views
* fix first time setup issue. change setup.html and about.html to extend from base_public.html template and redirect from home to setup if necessary

Pull-request #533
This commit is contained in:
Pablo González 2017-08-15 10:28:41 -03:00 committed by Jean-Frédéric
parent 4034d98a37
commit cb2fc2e896
14 changed files with 312 additions and 166 deletions

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cabotapp', '0003_auto_20170201_1045'),
]
operations = [
migrations.AddField(
model_name='Service',
name='is_public',
field=models.BooleanField(default=False, help_text=b'The service will be shown in the public home', verbose_name=b'Is Public'),
),
]

View File

@ -305,6 +305,12 @@ class Service(CheckGroupMixin):
help_text="URL of service." help_text="URL of service."
) )
is_public = models.BooleanField(
verbose_name='Is Public',
default=False,
help_text='The service will be shown in the public home'
)
class Meta: class Meta:
ordering = ['name'] ordering = ['name']

View File

@ -318,7 +318,8 @@ class ServiceForm(forms.ModelForm):
'alerts', 'alerts',
'alerts_enabled', 'alerts_enabled',
'hackpad_id', 'hackpad_id',
'runbook_link' 'runbook_link',
'is_public'
) )
widgets = { widgets = {
'name': forms.TextInput(attrs={'style': 'width: 70%;'}), 'name': forms.TextInput(attrs={'style': 'width: 70%;'}),
@ -801,6 +802,18 @@ class ServiceListView(LoginRequiredMixin, ListView):
return Service.objects.all().order_by('name').prefetch_related('status_checks') return Service.objects.all().order_by('name').prefetch_related('status_checks')
class ServicePublicListView(TemplateView):
model = Service
context_object_name = 'services'
template_name = "cabotapp/service_public_list.html"
def get_context_data(self, **kwargs):
context = super(ServicePublicListView, self).get_context_data(**kwargs)
context[self.context_object_name] = Service.objects\
.filter(is_public=True, alerts_enabled=True)\
.order_by('name').prefetch_related('status_checks')
return context
class InstanceDetailView(LoginRequiredMixin, DetailView): class InstanceDetailView(LoginRequiredMixin, DetailView):
model = Instance model = Instance
context_object_name = 'instance' context_object_name = 'instance'

View File

@ -285,8 +285,9 @@ if AUTH_LDAP:
# Github SSO # Github SSO
AUTH_GITHUB_ENTERPRISE_ORG = force_bool(os.environ.get('AUTH_GITHUB_ENTERPRISE_ORG', False)) AUTH_GITHUB_ENTERPRISE_ORG = force_bool(os.environ.get('AUTH_GITHUB_ENTERPRISE_ORG', False))
AUTH_GITHUB_ORG = force_bool(os.environ.get('AUTH_GITHUB_ORG', False)) AUTH_GITHUB_ORG = force_bool(os.environ.get('AUTH_GITHUB_ORG', False))
AUTH_GOOGLE_OAUTH2 = force_bool(os.environ.get('AUTH_GOOGLE_OAUTH2', False))
AUTH_SOCIAL = AUTH_GITHUB_ORG or AUTH_GITHUB_ENTERPRISE_ORG AUTH_SOCIAL = AUTH_GITHUB_ORG or AUTH_GITHUB_ENTERPRISE_ORG or AUTH_GOOGLE_OAUTH2
if AUTH_SOCIAL: if AUTH_SOCIAL:
SOCIAL_AUTH_URL_NAMESPACE = 'social' SOCIAL_AUTH_URL_NAMESPACE = 'social'
@ -307,4 +308,10 @@ if AUTH_GITHUB_ENTERPRISE_ORG:
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_SECRET = os.environ.get('AUTH_GITHUB_ENTERPRISE_ORG_CLIENT_SECRET') SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_SECRET = os.environ.get('AUTH_GITHUB_ENTERPRISE_ORG_CLIENT_SECRET')
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_NAME = os.environ.get('AUTH_GITHUB_ENTERPRISE_ORG_NAME') SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_NAME = os.environ.get('AUTH_GITHUB_ENTERPRISE_ORG_NAME')
if AUTH_GOOGLE_OAUTH2:
AUTHENTICATION_BACKENDS += tuple(['social_core.backends.google.GoogleOAuth2'])
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ.get('AUTH_GOOGLE_OAUTH2_KEY')
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ.get('AUTH_GOOGLE_OAUTH2_SECRET')
SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = os.environ.get('AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS', '').split(',')
EXPOSE_USER_API = force_bool(os.environ.get('EXPOSE_USER_API', False)) EXPOSE_USER_API = force_bool(os.environ.get('EXPOSE_USER_API', False))

View File

@ -1,98 +1,55 @@
{% load static from staticfiles %} {% extends 'base_public.html' %}
<!DOCTYPE html> {% block header_navbar_menu %}
<html> <ul class="nav navbar-nav">
<head> <li>
<a href="{% url 'instances' %}"><i class="fa fa-desktop"></i> Instances</a>
<meta charset="utf-8"> </li>
<title>{% block title %}Cabot by Arachnys{% endblock title %}</title> <li>
<a href="{% url 'services' %}"><i class="fa fa-gears"></i> Services</a>
<meta name="viewport" content="width=device-width, initial-scale=1"> </li>
{% load compress %} <li>
{% compress css %} <a href="{% url 'checks' %}"><i class="fa fa-cog"></i> Checks</a>
<link href="{% static 'bootstrap/css/bootstrap.css' %}" rel="stylesheet"> </li>
<link id="chosen-css" href="{% static 'theme/css/chosen.css' %}" rel="stylesheet"> <ul class="nav navbar-nav navbar-left">
<link id="chosen-css" href="{% static 'theme/css/bootstrap-chosen.css' %}" rel="stylesheet"> <li class="dropdown">
<link href="{% static 'bootstrap/css/dashboard.css' %}" rel="stylesheet"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" id="download">New <span class="caret"></span></a>
<link href="{% static 'theme/css/jquery-ui-1.8.21.custom.css' %}" type="text/css" rel="stylesheet"> <ul class="dropdown-menu" aria-labelledby="New">
<link href="{% static 'arachnys/css/base.less' %}" type="text/less" rel="stylesheet">
<link rel="stylesheet" href="{% static 'arachnys/css/morris.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'arachnys/css/graph.css' %}" type="text/css">
{% endcompress %}
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="icon" href="{% static 'arachnys/img/icon_48x48.png'%}" type="image/png">
{% compress js %}
<script type="text/coffeescript">
if window.location.host.indexOf('localhost') != -1
window.ENVIRONMENT = 'DEVELOPMENT'
else
window.ENVIRONMENT = 'PRODUCTION'
</script>
{% endcompress %}
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="{% url "services" %}" class="navbar-brand"><img src="{% static 'arachnys/img/icon_48x48.png' %}" width='20' height='20' /> Cabot by Arachnys</a>
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-main">
<ul class="nav navbar-nav">
<li> <li>
<a href="{% url "instances" %}"><i class="fa fa-desktop"></i> Instances</a> <a href="{% url 'create-service' %}"><i class="fa fa-gears"></i> Service</a>
</li> </li>
<li> <li>
<a href="{% url "services" %}"><i class="fa fa-gears"></i> Services</a> <a href="{% url 'create-instance' %}"><i class="fa fa-desktop"></i> Instance</a>
</li>
<li class="divider"></li>
<li>
<a href="{% url 'create-graphite-check' %}?service={{ service.id }}&instance={{ instance.id }}" class=""><i class="glyphicon glyphicon-signal" title="Add new metric check"></i> Graphite check</a>
</li> </li>
<li> <li>
<a href="{% url "checks" %}"><i class="fa fa-cog"></i> Checks</a> <a href="{% url 'create-http-check' %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new Http check"><i class="glyphicon glyphicon-arrow-up"></i> Http check</a>
</li> </li>
<ul class="nav navbar-nav navbar-left"> <li>
<li class="dropdown"> <a href="{% url 'create-jenkins-check' %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new Jenkins check"><i class="glyphicon glyphicon-ok"></i> Jenkins check</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="download">New <span class="caret"></span></a> </li>
<ul class="dropdown-menu" aria-labelledby="New"> <li>
<li> <a href="{% url 'create-icmp-check' %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new ICMP check"><i class="glyphicon glyphicon-transfer"></i> ICMP check</a>
<a href="{% url "create-service" %}"><i class="fa fa-gears"></i> Service</a> </li>
</li> <!-- Custom check plugins buttons-->
<li> {% for checktype in custom_check_types %}
<a href="{% url "create-instance" %}"><i class="fa fa-desktop"></i> Instance</a> <li>
</li> <a href="{% url checktype.creation_url %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new {{checktype.check_name|capfirst}} check"><i class="glyphicon glyphicon-transfer"></i> {{checktype.check_name|capfirst}} check</a>
<li class="divider"></li>
<li>
<a href="{% url "create-graphite-check" %}?service={{ service.id }}&instance={{ instance.id }}" class=""><i class="glyphicon glyphicon-signal" title="Add new metric check"></i> Graphite check</a>
</li>
<li>
<a href="{% url "create-http-check" %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new Http check"><i class="glyphicon glyphicon-arrow-up"></i> Http check</a>
</li>
<li>
<a href="{% url "create-jenkins-check" %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new Jenkins check"><i class="glyphicon glyphicon-ok"></i> Jenkins check</a>
</li>
<li>
<a href="{% url "create-icmp-check" %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new ICMP check"><i class="glyphicon glyphicon-transfer"></i> ICMP check</a>
</li>
<!-- Custom check plugins buttons-->
{% for checktype in custom_check_types %}
<li>
<a href="{% url checktype.creation_url %}?service={{ service.id }}&instance={{ instance.id }}" class="" title="Add new {{checktype.check_name|capfirst}} check"><i class="glyphicon glyphicon-transfer"></i> {{checktype.check_name|capfirst}} check</a>
</li>
{% endfor %}
</ul>
</li> </li>
</ul> {% endfor %}
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> </li>
</ul>
</ul>
<ul class="nav navbar-nav navbar-right">
<li> <li>
<a href="{% url "subscriptions" %}"><i class="fa fa-table"></i> Alert subscriptions</a> <a href="{% url 'subscriptions' %}"><i class="fa fa-table"></i> Alert subscriptions</a>
</li> </li>
<li> <li>
<a href="{% url "shifts" %}"><i class="glyphicon glyphicon-time"></i> Duty rota</a> <a href="{% url 'shifts' %}"><i class="glyphicon glyphicon-time"></i> Duty rota</a>
</li> </li>
{% if user.is_authenticated %}
<li class="dropdown"> <li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="download">{{ user.username }} <span class="caret"></span></a> <a class="dropdown-toggle" data-toggle="dropdown" href="#" id="download">{{ user.username }} <span class="caret"></span></a>
<ul class="dropdown-menu" aria-labelledby="admin"> <ul class="dropdown-menu" aria-labelledby="admin">
@ -115,77 +72,5 @@
</li> </li>
</ul> </ul>
</li> </li>
{% endif %}
</ul> </ul>
</div> {% endblock header_navbar_menu %}
</div>
</div>
<!-- start: Header -->
<div class="container">
<noscript>
<div class="alert alert-block span10">
<h4 class="alert-heading">Warning!</h4>
<p>You need to have <a href="http://en.wikipedia.org/wiki/JavaScript" target="_blank">JavaScript</a> enabled to use this site.</p>
</div>
</noscript>
{% if messages %}
<div class="messages">
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissable">
<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
<div class="row">
{% block content %}
{% endblock content %}
</div>
<div class="clearfix"></div>
</div>
{% load compress %}
{% block js %}
{% compress js %}
<script src="{% static 'bootstrap/js/jquery-1.10.2.js' %}"></script>
<script src="{% static 'theme/js/jquery-ui.js' %}"></script>
<script src="{% static 'theme/js/jquery.ui.core.js' %}"></script>
<script src="{% static 'theme/js/jquery.ui.position.js' %}"></script>
<script src="{% static 'theme/js/jquery.ui.autocomplete.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap.js' %}"></script>
<script src="{% static 'theme/js/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'theme/js/chosen.jquery.js' %}"></script>
<script src="{% static 'theme/js/jquery.sparkline.min.js' %}"></script>
<script src="{% static 'theme/js/custom.js' %}"></script>
<script src="{% static 'arachnys/js/raphael.js' %}"></script>
<script src="{% static 'arachnys/js/morris.js' %}"></script>
<!-- end: JavaScript-->
<script type="text/coffeescript">
$ () ->
$('.sparktristate').sparkline('html', {type: 'tristate'})
$('ul.nav li a').each () ->
if $($(this))[0].href == String(window.location)
$(this).parent().addClass('active')
$('[data-rel="chosen"],[rel="chosen"]').chosen({ width: '100%' })
#$('.datatable').dataTable
# sDom: "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span12'i><'span12 center'p>>",
# sPaginationType: "bootstrap",
# iDisplayLength: 100,
# oLanguage:
# sLengthMenu: "_MENU_ records per page"
</script>
{% endcompress %}
{% endblock js %}
</body>
</html>

View File

@ -0,0 +1,124 @@
{% load static from staticfiles %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Cabot by Arachnys{% endblock title %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
{% load compress %}
{% compress css %}
<link href="{% static 'bootstrap/css/bootstrap.css' %}" rel="stylesheet">
<link id="chosen-css" href="{% static 'theme/css/chosen.css' %}" rel="stylesheet">
<link id="chosen-css" href="{% static 'theme/css/bootstrap-chosen.css' %}" rel="stylesheet">
<link href="{% static 'bootstrap/css/dashboard.css' %}" rel="stylesheet">
<link href="{% static 'theme/css/jquery-ui-1.8.21.custom.css' %}" type="text/css" rel="stylesheet">
<link href="{% static 'arachnys/css/base.less' %}" type="text/less" rel="stylesheet">
<link rel="stylesheet" href="{% static 'arachnys/css/morris.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'arachnys/css/graph.css' %}" type="text/css">
{% endcompress %}
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-social/5.1.1/bootstrap-social.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
<link rel="icon" href="{% static 'arachnys/img/icon_48x48.png'%}" type="image/png">
{% compress js %}
<script type="text/coffeescript">
if window.location.host.indexOf('localhost') != -1
window.ENVIRONMENT = 'DEVELOPMENT'
else
window.ENVIRONMENT = 'PRODUCTION'
</script>
{% endcompress %}
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="{% url 'dashboard' %}" class="navbar-brand"><img src="{% static 'arachnys/img/icon_48x48.png' %}" width='20' height='20' /> Cabot by Arachnys</a>
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-main">
{% block header_navbar_menu %}
<ul class="nav navbar-nav navbar-right">
<li>
<a href="{% url 'login' %}"><i class="glyphicon glyphicon-log-in"></i> Log In</a>
</li>
</ul>
{% endblock header_navbar_menu %}
</div>
</div>
</div>
<!-- start: Header -->
<div class="container">
<noscript>
<div class="alert alert-block span10">
<h4 class="alert-heading">Warning!</h4>
<p>You need to have <a href="http://en.wikipedia.org/wiki/JavaScript" target="_blank">JavaScript</a> enabled to use this site.</p>
</div>
</noscript>
{% if messages %}
<div class="messages">
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissable">
<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
<div class="row">
{% block content %}
{% endblock content %}
</div>
<div class="clearfix"></div>
</div>
{% load compress %}
{% block js %}
{% compress js %}
<script src="{% static 'bootstrap/js/jquery-1.10.2.js' %}"></script>
<script src="{% static 'theme/js/jquery-ui.js' %}"></script>
<script src="{% static 'theme/js/jquery.ui.core.js' %}"></script>
<script src="{% static 'theme/js/jquery.ui.position.js' %}"></script>
<script src="{% static 'theme/js/jquery.ui.autocomplete.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap.js' %}"></script>
<script src="{% static 'theme/js/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'theme/js/chosen.jquery.js' %}"></script>
<script src="{% static 'theme/js/jquery.sparkline.min.js' %}"></script>
<script src="{% static 'theme/js/custom.js' %}"></script>
<script src="{% static 'arachnys/js/raphael.js' %}"></script>
<script src="{% static 'arachnys/js/morris.js' %}"></script>
<!-- end: JavaScript-->
<script type="text/coffeescript">
$ () ->
$('.sparktristate').sparkline('html', {type: 'tristate'})
$('ul.nav li a').each () ->
if $($(this))[0].href == String(window.location)
$(this).parent().addClass('active')
$('[data-rel="chosen"],[rel="chosen"]').chosen({ width: '100%' })
#$('.datatable').dataTable
# sDom: "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span12'i><'span12 center'p>>",
# sPaginationType: "bootstrap",
# iDisplayLength: 100,
# oLanguage:
# sLengthMenu: "_MENU_ records per page"
</script>
{% endcompress %}
{% endblock js %}
</body>
</html>

View File

@ -0,0 +1,36 @@
{% if not services %}
<div class="col-xs-11 col-xs-offset-1">
<hr/>
No available services monitoring
</div>
{% else %}
<div class="row">
<div class="col-xs-8">
<h4>Name</h4>
</div>
<div class="col-xs-2">
<h4>Overall Checks</h4>
</div>
<div class="col-xs-2">
<h4>Acknowledgment</h4>
</div>
</div>
{% for service in services %}
<hr/>
<div class="row">
<div class="col-xs-8 {% if service.alerts_enabled %}enabled{% else %}warning{% endif %}">
<a href="{{service.url}}" title="{{service.url}}" target="_blank">{{service.name}}</a>
</div>
<div class="col-xs-2">
<span class="label label-{% if not service.alerts_enabled %}warning{% else %}{% if service.overall_status == service.PASSING_STATUS %}success{% else %}danger{% endif %}{% endif %}">{% if service.alerts_enabled %}{{ service.overall_status|lower|capfirst }}{% else %}Disabled{% endif %}</span>
</div>
<div class="col-xs-2">
<span class="label label-{% if not service.unexpired_acknowledgement %}danger{% else %}success{% endif %}">{% if service.overall_status != service.PASSING_STATUS %}{% if service.unexpired_acknowledgement %}Yes{% else %}No{% endif %}{% endif %}</span>
</div>
</div>
{% endfor %}
{% endif %}

View File

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_public.html' %}
{% load static from staticfiles %} {% load static from staticfiles %}
{% block title %}{{ block.super }} - About{% endblock title %} {% block title %}{{ block.super }} - About{% endblock title %}

View File

@ -0,0 +1,17 @@
{% extends 'base_public.html' %}
{% block header_navbar_menu %}
<ul class="nav navbar-nav">
<li>
<a href="{% url 'public' %}"><i class="fa fa-gears"></i> Services</a>
</li>
</ul>
{{block.super}}
{% endblock header_navbar_menu %}
{% block content %}
<div class="row">
<div class="col-xs-12">
{% include 'cabotapp/_service_public_list.html' %}
</div>
</div>
{% endblock content %}

View File

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_public.html' %}
{% block content %} {% block content %}
<h1>Welcome to Cabot!</h1> <h1>Welcome to Cabot!</h1>

View File

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_public.html' %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
@ -14,10 +14,10 @@
<div class="form-group"> <div class="form-group">
<div class="col-xs-6 col-xs-offset-2"> <div class="col-xs-6 col-xs-offset-2">
<button type="submit" class="btn btn-primary">Log in</button> <button type="submit" class="btn btn-primary">Log in</button>
<a href="{% url "password-reset" %}" class="btn">Reset password</a> <a href="{% url 'password-reset' %}" class="btn">Reset password</a>
</div> </div>
</div> </div>
</div> </div>
</form> </form>
</form> {% include "./social_auth.html" %}
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_public.html' %}
{% block content %} {% block content %}

View File

@ -0,0 +1,28 @@
{% load extra %}
{% echo_setting 'AUTH_GOOGLE_OAUTH2' as google_enable %}
{% echo_setting 'AUTH_GITHUB_ORG' as github_enable %}
{% echo_setting 'AUTH_GITHUB_ENTERPRISE_ORG' as github_enterprise_enable %}
<div class="col-xs-3 col-xs-offset-2">
<hr/>
{% if github_enable %}
<a class="btn btn-block btn-social btn-github" href="{% url 'social:begin' 'github-org' %}">
<i class="fa fa-github" aria-hidden="true"></i>
Sig in with Github
</a>
{% endif %}
{% if github_enterprise_enable %}
<a class="btn btn-block btn-social btn-github" href="{% url 'social:begin' 'github-enterprise-org' %}">
<i class="fa fa-github" aria-hidden="true"></i>
Sig in with GitHub Enterprise
</a>
{% endif %}
{% if google_enable %}
<a class="btn btn-block btn-social btn-google" href="{% url 'social:begin' 'google-oauth2' %}">
<i class="fa fa-google" aria-hidden="true"></i>
Sign in with Google
</a>
{% endif %}
</div>

View File

@ -14,7 +14,7 @@ from cabot.cabotapp.views import (
from cabot.cabotapp.views import (InstanceListView, InstanceDetailView, from cabot.cabotapp.views import (InstanceListView, InstanceDetailView,
InstanceUpdateView, InstanceCreateView, InstanceDeleteView, InstanceUpdateView, InstanceCreateView, InstanceDeleteView,
ServiceListView, ServiceDetailView, ServiceListView, ServicePublicListView, ServiceDetailView,
ServiceUpdateView, ServiceCreateView, ServiceDeleteView, ServiceUpdateView, ServiceCreateView, ServiceDeleteView,
UserProfileUpdateView, ShiftListView, subscriptions) UserProfileUpdateView, ShiftListView, subscriptions)
@ -43,11 +43,20 @@ def first_time_setup_wrapper(func):
return func(*args, **kwargs) return func(*args, **kwargs)
return wrapper return wrapper
def home_authentication_switcher(request, *args, **kwargs):
if cabot_needs_setup():
return redirect('first_time_setup')
if not request.user.is_authenticated():
return ServicePublicListView.as_view()(request, *args, **kwargs)
else:
return ServiceListView.as_view()(request, *args, **kwargs)
urlpatterns = [ urlpatterns = [
# for the password reset views # for the password reset views
url('^', include('django.contrib.auth.urls')), url('^', include('django.contrib.auth.urls')),
url(r'^$', view=RedirectView.as_view(url='services/', permanent=False), url(r'^$', view=home_authentication_switcher,
name='dashboard'), name='dashboard'),
url(r'^subscriptions/', view=subscriptions, url(r'^subscriptions/', view=subscriptions,
name='subscriptions'), name='subscriptions'),
@ -67,6 +76,8 @@ urlpatterns = [
url(r'^services/', view=ServiceListView.as_view(), url(r'^services/', view=ServiceListView.as_view(),
name='services'), name='services'),
url(r'^public/', view=ServicePublicListView.as_view(),
name='public'),
url(r'^service/create/', view=ServiceCreateView.as_view(), url(r'^service/create/', view=ServiceCreateView.as_view(),
name='create-service'), name='create-service'),
url(r'^service/update/(?P<pk>\d+)/', url(r'^service/update/(?P<pk>\d+)/',