summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pharos-dashboard/docker-compose.yml2
-rw-r--r--pharos-dashboard/src/account/migrations/0002_auto_20161005_1201.py25
-rw-r--r--pharos-dashboard/src/account/models.py8
-rw-r--r--pharos-dashboard/src/account/tasks.py34
-rw-r--r--pharos-dashboard/src/account/views.py21
-rw-r--r--pharos-dashboard/src/api/urls.py1
-rw-r--r--pharos-dashboard/src/api/views.py18
-rw-r--r--pharos-dashboard/src/dashboard/migrations/0002_auto_20161005_1202.py21
-rw-r--r--pharos-dashboard/src/dashboard/models.py2
-rw-r--r--pharos-dashboard/src/templates/account/user_list.html20
-rw-r--r--pharos-dashboard/src/templates/account/userprofile_update_form.html10
-rw-r--r--pharos-dashboard/src/templates/dashboard/resource_detail.html1
12 files changed, 146 insertions, 17 deletions
diff --git a/pharos-dashboard/docker-compose.yml b/pharos-dashboard/docker-compose.yml
index 00a8d15..b487620 100644
--- a/pharos-dashboard/docker-compose.yml
+++ b/pharos-dashboard/docker-compose.yml
@@ -59,7 +59,7 @@ services:
worker:
restart: always
build: ./worker/
- command: bash -c "celery -A pharos_dashboard worker -l info -B"
+ command: bash -c "celery -A pharos_dashboard worker -l info -B --schedule=~/celerybeat-schedule""
env_file: config.env
links:
- postgres
diff --git a/pharos-dashboard/src/account/migrations/0002_auto_20161005_1201.py b/pharos-dashboard/src/account/migrations/0002_auto_20161005_1201.py
new file mode 100644
index 0000000..33d2cc5
--- /dev/null
+++ b/pharos-dashboard/src/account/migrations/0002_auto_20161005_1201.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-10-05 12:01
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('account', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='userprofile',
+ name='full_name',
+ field=models.CharField(default='', max_length=100),
+ ),
+ migrations.AddField(
+ model_name='userprofile',
+ name='jira_url',
+ field=models.CharField(default='', max_length=100),
+ ),
+ ]
diff --git a/pharos-dashboard/src/account/models.py b/pharos-dashboard/src/account/models.py
index 621f669..d87ee18 100644
--- a/pharos-dashboard/src/account/models.py
+++ b/pharos-dashboard/src/account/models.py
@@ -11,6 +11,7 @@
from django.db import models
from django.contrib.auth.models import User
+from rest_framework.authtoken.models import Token
from dashboard.models import Resource
@@ -23,8 +24,15 @@ class UserProfile(models.Model):
ssh_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
pgp_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
company = models.CharField(max_length=200, blank=False)
+
oauth_token = models.CharField(max_length=1024, blank=False)
oauth_secret = models.CharField(max_length=1024, blank=False)
+ jira_url = models.CharField(max_length=100, default='')
+ full_name = models.CharField(max_length=100, default='')
+
class Meta:
db_table = 'user_profile'
+
+ def __str__(self):
+ return self.user.username
diff --git a/pharos-dashboard/src/account/tasks.py b/pharos-dashboard/src/account/tasks.py
new file mode 100644
index 0000000..bfb865d
--- /dev/null
+++ b/pharos-dashboard/src/account/tasks.py
@@ -0,0 +1,34 @@
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from celery import shared_task
+from django.contrib.auth.models import User
+from jira import JIRAError
+
+from account.jira_util import get_jira
+
+
+@shared_task
+def sync_jira_accounts():
+ users = User.objects.all()
+ for user in users:
+ jira = get_jira(user)
+ try:
+ user_dict = jira.myself()
+ except JIRAError:
+ # User can be anonymous (local django admin account)
+ continue
+ user.email = user_dict['emailAddress']
+ user.userprofile.url = user_dict['self']
+ user.userprofile.full_name = user_dict['displayName']
+ print(user_dict)
+
+ user.userprofile.save()
+ user.save() \ No newline at end of file
diff --git a/pharos-dashboard/src/account/views.py b/pharos-dashboard/src/account/views.py
index 3b4269d..ac973f5 100644
--- a/pharos-dashboard/src/account/views.py
+++ b/pharos-dashboard/src/account/views.py
@@ -12,6 +12,7 @@ import os
import urllib
import oauth2 as oauth
+from django.conf import settings
from django.contrib import messages
from django.contrib.auth import logout, authenticate, login
from django.contrib.auth.decorators import login_required
@@ -19,17 +20,14 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.decorators import method_decorator
-from django.views.generic import RedirectView
-from django.views.generic import TemplateView
-from django.views.generic import UpdateView
+from django.views.generic import RedirectView, TemplateView, UpdateView
+
from jira import JIRA
+from rest_framework.authtoken.models import Token
from account.forms import AccountSettingsForm
from account.jira_util import SignatureMethod_RSA_SHA1
from account.models import UserProfile
-from django.conf import settings
-
-consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
@method_decorator(login_required, name='dispatch')
@@ -46,9 +44,16 @@ class AccountSettingsView(UpdateView):
def get_object(self, queryset=None):
return self.request.user.userprofile
+ def get_context_data(self, **kwargs):
+ token, created = Token.objects.get_or_create(user=self.request.user)
+ context = super(AccountSettingsView, self).get_context_data(**kwargs)
+ context.update({'title': "Settings", 'token': token})
+ return context
+
class JiraLoginView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
+ consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
client = oauth.Client(consumer)
client.set_signature_method(SignatureMethod_RSA_SHA1())
@@ -61,7 +66,7 @@ class JiraLoginView(RedirectView):
self.request.session['request_token'] = dict(urllib.parse.parse_qsl(content.decode()))
# Step 3. Redirect the user to the authentication URL.
url = settings.OAUTH_AUTHORIZE_URL + '?oauth_token=' + \
- self.request.session['request_token']['oauth_token'] + \
+ self.request.session['request_token']['oauth_token'] + \
'&oauth_callback=' + settings.OAUTH_CALLBACK_URL
return url
@@ -75,6 +80,7 @@ class JiraLogoutView(LoginRequiredMixin, RedirectView):
class JiraAuthenticatedView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
# Step 1. Use the request token in the session to build a new client.
+ consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
token = oauth.Token(self.request.session['request_token']['oauth_token'],
self.request.session['request_token']['oauth_token_secret'])
client = oauth.Client(consumer, token)
@@ -122,6 +128,7 @@ class JiraAuthenticatedView(RedirectView):
# redirect user to settings page to complete profile
return url
+@method_decorator(login_required, name='dispatch')
class UserListView(TemplateView):
template_name = "account/user_list.html"
diff --git a/pharos-dashboard/src/api/urls.py b/pharos-dashboard/src/api/urls.py
index 5206ac7..dfbe1ac 100644
--- a/pharos-dashboard/src/api/urls.py
+++ b/pharos-dashboard/src/api/urls.py
@@ -35,4 +35,5 @@ router.register(r'bookings', BookingViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
+ url(r'^token$', GenerateTokenView.as_view(), name='generate_token'),
] \ No newline at end of file
diff --git a/pharos-dashboard/src/api/views.py b/pharos-dashboard/src/api/views.py
index 761ce6e..55de5c6 100644
--- a/pharos-dashboard/src/api/views.py
+++ b/pharos-dashboard/src/api/views.py
@@ -10,9 +10,14 @@
from rest_framework import viewsets
+from django.contrib.auth.decorators import login_required
+from django.utils.decorators import method_decorator
from api.serializers import ResourceSerializer, ServerSerializer, BookingSerializer
from booking.models import Booking
from dashboard.models import Resource, Server
+from django.views import View
+from rest_framework.authtoken.models import Token
+from django.shortcuts import redirect
class BookingViewSet(viewsets.ModelViewSet):
@@ -30,4 +35,15 @@ class ServerViewSet(viewsets.ModelViewSet):
class ResourceViewSet(viewsets.ModelViewSet):
queryset = Resource.objects.all()
serializer_class = ResourceSerializer
- filter_fields = ('name',) \ No newline at end of file
+ filter_fields = ('name',)
+
+
+@method_decorator(login_required, name='dispatch')
+class GenerateTokenView(View):
+ def get(self, request, *args, **kwargs):
+ user = self.request.user
+ token, created = Token.objects.get_or_create(user=user)
+ if not created:
+ token.delete()
+ Token.objects.create(user=user)
+ return redirect('account:settings')
diff --git a/pharos-dashboard/src/dashboard/migrations/0002_auto_20161005_1202.py b/pharos-dashboard/src/dashboard/migrations/0002_auto_20161005_1202.py
new file mode 100644
index 0000000..e47c3b1
--- /dev/null
+++ b/pharos-dashboard/src/dashboard/migrations/0002_auto_20161005_1202.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-10-05 12:02
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('dashboard', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='resource',
+ name='vpn_users',
+ field=models.ManyToManyField(blank=True, related_name='user_vpn_users', to=settings.AUTH_USER_MODEL),
+ ),
+ ]
diff --git a/pharos-dashboard/src/dashboard/models.py b/pharos-dashboard/src/dashboard/models.py
index 050834e..e3f22e6 100644
--- a/pharos-dashboard/src/dashboard/models.py
+++ b/pharos-dashboard/src/dashboard/models.py
@@ -23,7 +23,7 @@ class Resource(models.Model):
description = models.CharField(max_length=300, blank=True, null=True)
url = models.CharField(max_length=100, blank=True, null=True)
owner = models.ForeignKey(User, related_name='user_lab_owner', null=True)
- vpn_users = models.ManyToManyField(User, related_name='user_vpn_users')
+ vpn_users = models.ManyToManyField(User, related_name='user_vpn_users', blank=True)
slave = models.ForeignKey(JenkinsSlave, on_delete=models.DO_NOTHING, null=True)
def get_booking_utilization(self, weeks):
diff --git a/pharos-dashboard/src/templates/account/user_list.html b/pharos-dashboard/src/templates/account/user_list.html
index c2b8193..f18e161 100644
--- a/pharos-dashboard/src/templates/account/user_list.html
+++ b/pharos-dashboard/src/templates/account/user_list.html
@@ -5,6 +5,8 @@
<thead>
<tr>
<th>Username</th>
+ <th>Full Name</th>
+ <th>Email</th>
<th>Company</th>
<th>SSH Key</th>
<th>GPG Key</th>
@@ -17,17 +19,23 @@
{{ user.username }}
</td>
<td>
+ {{ user.userprofile.full_name }}
+ </td>
+ <td>
+ {{ user.email }}
+ </td>
+ <td>
{{ user.userprofile.company }}
</td>
<td>
- {% if user.userprofile.ssh_public_key %}
- <a href={{ user.userprofile.ssh_public_key.url }}>SSH</a>
- {% endif %}
+ {% if user.userprofile.ssh_public_key %}
+ <a href={{ user.userprofile.ssh_public_key.url }}>SSH</a>
+ {% endif %}
</td>
<td>
- {% if user.userprofile.pgp_public_key %}
- <a href={{ user.userprofile.pgp_public_key.url }}>GPG</a>
- {% endif %}
+ {% if user.userprofile.pgp_public_key %}
+ <a href={{ user.userprofile.pgp_public_key.url }}>GPG</a>
+ {% endif %}
</td>
</tr>
{% endfor %}
diff --git a/pharos-dashboard/src/templates/account/userprofile_update_form.html b/pharos-dashboard/src/templates/account/userprofile_update_form.html
index 542ea81..f4bb7b5 100644
--- a/pharos-dashboard/src/templates/account/userprofile_update_form.html
+++ b/pharos-dashboard/src/templates/account/userprofile_update_form.html
@@ -16,9 +16,17 @@
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
{% bootstrap_form form %}
+ <p><b>API Token</b>
+ <a href="{% url 'generate_token' %}" class="btn btn-default">
+ Generate
+ </a>
+ </p>
+ <p style="word-wrap: break-word;">{{ token.key }}</p>
+
+ <p></p>
{% buttons %}
<button type="submit" class="btn btn btn-success">
- Save
+ Save Profile
</button>
{% endbuttons %}
</form>
diff --git a/pharos-dashboard/src/templates/dashboard/resource_detail.html b/pharos-dashboard/src/templates/dashboard/resource_detail.html
index 657d565..e0b29bd 100644
--- a/pharos-dashboard/src/templates/dashboard/resource_detail.html
+++ b/pharos-dashboard/src/templates/dashboard/resource_detail.html
@@ -106,6 +106,7 @@
</p>
<p>
<b>Email: </b>
+ {{ resource.owner.email }}
</p>
<p>
<a href="{% url 'booking:create' resource_id=resource.id %}" class="btn