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
--- /dev/null
+# -*- 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),
+ ),
+ ]
from django.db import models
from django.contrib.auth.models import User
+from rest_framework.authtoken.models import Token
from dashboard.models import Resource
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
--- /dev/null
+##############################################################################
+# 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
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
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')
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())
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
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)
# 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"
urlpatterns = [
url(r'^', include(router.urls)),
+ url(r'^token$', GenerateTokenView.as_view(), name='generate_token'),
]
\ No newline at end of file
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):
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')
--- /dev/null
+# -*- 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),
+ ),
+ ]
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):
<thead>
<tr>
<th>Username</th>
+ <th>Full Name</th>
+ <th>Email</th>
<th>Company</th>
<th>SSH Key</th>
<th>GPG Key</th>
<td>
{{ 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 %}
<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>
</p>
<p>
<b>Email: </b>
+ {{ resource.owner.email }}
</p>
<p>
<a href="{% url 'booking:create' resource_id=resource.id %}" class="btn