aboutsummaryrefslogtreecommitdiffstats
path: root/src/account
diff options
context:
space:
mode:
authorSawyer Bergeron <sbergeron@iol.unh.edu>2021-10-15 14:14:46 -0400
committerSawyer Bergeron <sbergeron@iol.unh.edu>2021-10-15 14:20:02 -0400
commit35b9f39178cc502a5283a1b37a65f7dd0838ae05 (patch)
tree676ede483e2aa6a0ad8ebaef0c0300a155a22023 /src/account
parentb3ed8ebcf536c021330e7ccbc0376f6b89189348 (diff)
Merge User Booking API Rev 1 (Try 3)
Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu> Change-Id: Ie1eee0a59929f8da39f16bb6bc17ae3de4f1cba9 Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu>
Diffstat (limited to 'src/account')
-rw-r--r--src/account/jira_util.py65
-rw-r--r--src/account/models.py1
-rw-r--r--src/account/tasks.py37
-rw-r--r--src/account/urls.py36
-rw-r--r--src/account/views.py148
5 files changed, 27 insertions, 260 deletions
diff --git a/src/account/jira_util.py b/src/account/jira_util.py
deleted file mode 100644
index a522594..0000000
--- a/src/account/jira_util.py
+++ /dev/null
@@ -1,65 +0,0 @@
-##############################################################################
-# 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
-##############################################################################
-
-
-import base64
-import os
-
-import oauth2 as oauth
-from django.conf import settings
-from jira import JIRA
-from tlslite.utils import keyfactory
-
-
-class SignatureMethod_RSA_SHA1(oauth.SignatureMethod):
- name = 'RSA-SHA1'
-
- def signing_base(self, request, consumer, token):
- if not hasattr(request, 'normalized_url') or request.normalized_url is None:
- raise ValueError("Base URL for request is not set.")
-
- sig = (
- oauth.escape(request.method),
- oauth.escape(request.normalized_url),
- oauth.escape(request.get_normalized_parameters()),
- )
-
- key = '%s&' % oauth.escape(consumer.secret)
- if token:
- key += oauth.escape(token.secret)
- raw = '&'.join(sig)
- return key, raw
-
- def sign(self, request, consumer, token):
- """Build the base signature string."""
- key, raw = self.signing_base(request, consumer, token)
-
- module_dir = os.path.dirname(__file__) # get current directory
- with open(module_dir + '/rsa.pem', 'r') as f:
- data = f.read()
- privateKeyString = data.strip()
- privatekey = keyfactory.parsePrivateKey(privateKeyString)
- raw = str.encode(raw)
- signature = privatekey.hashAndSign(raw)
- return base64.b64encode(signature)
-
-
-def get_jira(user):
- module_dir = os.path.dirname(__file__) # get current directory
- with open(module_dir + '/rsa.pem', 'r') as f:
- key_cert = f.read()
-
- oauth_dict = {
- 'access_token': user.userprofile.oauth_token,
- 'access_token_secret': user.userprofile.oauth_secret,
- 'consumer_key': settings.OAUTH_CONSUMER_KEY,
- 'key_cert': key_cert
- }
-
- return JIRA(server=settings.JIRA_URL, oauth=oauth_dict)
diff --git a/src/account/models.py b/src/account/models.py
index b71f0ac..210025e 100644
--- a/src/account/models.py
+++ b/src/account/models.py
@@ -51,6 +51,7 @@ class UserProfile(models.Model):
oauth_secret = models.CharField(max_length=1024, blank=False)
jira_url = models.CharField(max_length=100, null=True, blank=True, default='')
+
full_name = models.CharField(max_length=100, null=True, blank=True, default='')
booking_privledge = models.BooleanField(default=False)
diff --git a/src/account/tasks.py b/src/account/tasks.py
deleted file mode 100644
index df98c73..0000000
--- a/src/account/tasks.py
+++ /dev/null
@@ -1,37 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, 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
- try:
- user.email = user_dict['emailAddress']
- except KeyError:
- pass
- user.userprofile.url = user_dict['self']
- user.userprofile.full_name = user_dict['displayName']
-
- user.userprofile.save()
- user.save()
diff --git a/src/account/urls.py b/src/account/urls.py
index 97d8c77..6d4ef2f 100644
--- a/src/account/urls.py
+++ b/src/account/urls.py
@@ -30,46 +30,30 @@ from django.urls import path
from account.views import (
AccountSettingsView,
- JiraAuthenticatedView,
- JiraLoginView,
OIDCLoginView,
- JiraLogoutView,
+ LogoutView,
UserListView,
account_resource_view,
account_booking_view,
account_images_view,
- account_configuration_view,
account_detail_view,
- resource_delete_view,
+ template_delete_view,
booking_cancel_view,
image_delete_view,
- configuration_delete_view
)
-from laas_dashboard import settings
+app_name = 'account'
-
-def get_login_view():
- if (settings.AUTH_SETTING == 'LFID'):
- return OIDCLoginView.as_view()
- else:
- return JiraLoginView.as_view()
-
-
-app_name = "account"
urlpatterns = [
url(r'^settings/', AccountSettingsView.as_view(), name='settings'),
- url(r'^authenticated/$', JiraAuthenticatedView.as_view(), name='authenticated'),
- url(r'^login/$', get_login_view(), name='login'),
- url(r'^logout/$', JiraLogoutView.as_view(), name='logout'),
+ url(r'^login/$', OIDCLoginView.as_view(), name='login'),
+ url(r'^logout/$', LogoutView.as_view(), name='logout'),
url(r'^users/$', UserListView.as_view(), name='users'),
- url(r'^my/resources/$', account_resource_view, name="my-resources"),
- path('my/resources/delete/<int:resource_id>', resource_delete_view),
- url(r'^my/bookings/$', account_booking_view, name="my-bookings"),
+ url(r'^my/resources/$', account_resource_view, name='my-resources'),
+ path('my/resources/delete/<int:resource_id>', template_delete_view),
+ url(r'^my/bookings/$', account_booking_view, name='my-bookings'),
path('my/bookings/cancel/<int:booking_id>', booking_cancel_view),
- url(r'^my/images/$', account_images_view, name="my-images"),
+ url(r'^my/images/$', account_images_view, name='my-images'),
path('my/images/delete/<int:image_id>', image_delete_view),
- url(r'^my/configurations/$', account_configuration_view, name="my-configurations"),
- path('my/configurations/delete/<int:config_id>', configuration_delete_view),
- url(r'^my/$', account_detail_view, name="my-account"),
+ url(r'^my/$', account_detail_view, name='my-account'),
]
diff --git a/src/account/views.py b/src/account/views.py
index b74126e..8976ff9 100644
--- a/src/account/views.py
+++ b/src/account/views.py
@@ -10,13 +10,10 @@
import os
-import urllib
-import oauth2 as oauth
-from django.conf import settings
from django.utils import timezone
from django.contrib import messages
-from django.contrib.auth import logout, authenticate, login
+from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
@@ -26,13 +23,11 @@ from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.views.generic import RedirectView, TemplateView, UpdateView
from django.shortcuts import render
-from jira import JIRA
from rest_framework.authtoken.models import Token
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
from account.forms import AccountSettingsForm
-from account.jira_util import SignatureMethod_RSA_SHA1
from account.models import UserProfile
from booking.models import Booking
from resource_inventory.models import ResourceTemplate, Image
@@ -69,7 +64,7 @@ class MyOIDCAB(OIDCAuthenticationBackend):
If this changes we will need to match users based on some
other criterea.
"""
- username = claims.get(os.environ['CLAIMS_ENDPOINT'] + 'username')
+ username = claims.get(os.environ.get('CLAIMS_ENDPOINT') + 'username')
if not username:
return HttpResponse('No username provided, contact support.')
@@ -101,109 +96,17 @@ class MyOIDCAB(OIDCAuthenticationBackend):
return user
-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())
-
- # Step 1. Get a request token from Jira.
- try:
- resp, content = client.request(settings.OAUTH_REQUEST_TOKEN_URL, "POST")
- except Exception:
- messages.add_message(self.request, messages.ERROR,
- 'Error: Connection to Jira failed. Please contact an Administrator')
- return '/'
- if resp['status'] != '200':
- messages.add_message(self.request, messages.ERROR,
- 'Error: Connection to Jira failed. Please contact an Administrator')
- return '/'
-
- # Step 2. Store the request token in a session for later use.
- 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'] + \
- '&oauth_callback=' + settings.OAUTH_CALLBACK_URL
- return url
-
-
class OIDCLoginView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
return reverse('oidc_authentication_init')
-class JiraLogoutView(LoginRequiredMixin, RedirectView):
+class LogoutView(LoginRequiredMixin, RedirectView):
def get_redirect_url(self, *args, **kwargs):
logout(self.request)
return '/'
-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)
- client.set_signature_method(SignatureMethod_RSA_SHA1())
-
- # Step 2. Request the authorized access token from Jira.
- try:
- resp, content = client.request(settings.OAUTH_ACCESS_TOKEN_URL, "POST")
- except Exception:
- messages.add_message(self.request, messages.ERROR,
- 'Error: Connection to Jira failed. Please contact an Administrator')
- return '/'
- if resp['status'] != '200':
- messages.add_message(self.request, messages.ERROR,
- 'Error: Connection to Jira failed. Please contact an Administrator')
- return '/'
-
- access_token = dict(urllib.parse.parse_qsl(content.decode()))
-
- module_dir = os.path.dirname(__file__) # get current directory
- with open(module_dir + '/rsa.pem', 'r') as f:
- key_cert = f.read()
-
- oauth_dict = {
- 'access_token': access_token['oauth_token'],
- 'access_token_secret': access_token['oauth_token_secret'],
- 'consumer_key': settings.OAUTH_CONSUMER_KEY,
- 'key_cert': key_cert
- }
-
- jira = JIRA(server=settings.JIRA_URL, oauth=oauth_dict)
- username = jira.current_user()
- email = ""
- try:
- email = jira.user(username).emailAddress
- except AttributeError:
- email = ""
- url = '/'
- # Step 3. Lookup the user or create them if they don't exist.
- try:
- user = User.objects.get(username=username)
- except User.DoesNotExist:
- # Save our permanent token and secret for later.
- user = User.objects.create_user(username=username,
- password=access_token['oauth_token_secret'])
- profile = UserProfile()
- profile.user = user
- profile.save()
- user.userprofile.email_addr = email
- url = reverse('account:settings')
- user.userprofile.oauth_token = access_token['oauth_token']
- user.userprofile.oauth_secret = access_token['oauth_token_secret']
- user.userprofile.save()
- user.set_password(access_token['oauth_token_secret'])
- user.save()
- user = authenticate(username=username, password=access_token['oauth_token_secret'])
- login(self.request, user)
- # 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"
@@ -232,9 +135,9 @@ def account_resource_view(request):
template = "account/resource_list.html"
active_bundles = [book.resource for book in Booking.objects.filter(
- owner=request.user, end__gte=timezone.now())]
+ owner=request.user, end__gte=timezone.now(), resource__template__temporary=False)]
active_resources = [bundle.template.id for bundle in active_bundles]
- resource_list = list(ResourceTemplate.objects.filter(owner=request.user))
+ resource_list = list(ResourceTemplate.objects.filter(owner=request.user, temporary=False))
context = {
"resources": resource_list,
@@ -262,15 +165,6 @@ def account_booking_view(request):
return render(request, template, context=context)
-def account_configuration_view(request):
- if not request.user.is_authenticated:
- return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
- template = "account/configuration_list.html"
- configs = list(ResourceTemplate.objects.filter(owner=request.user))
- context = {"title": "Configuration List", "configurations": configs}
- return render(request, template, context=context)
-
-
def account_images_view(request):
if not request.user.is_authenticated:
return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
@@ -290,28 +184,18 @@ def account_images_view(request):
return render(request, template, context=context)
-def resource_delete_view(request, resource_id=None):
- if not request.user.is_authenticated:
- return HttpResponse('no') # 403?
- grb = get_object_or_404(ResourceTemplate, pk=resource_id)
- if not request.user.id == grb.owner.id:
- return HttpResponse('no') # 403?
- if Booking.objects.filter(resource__template=grb, end__gt=timezone.now()).exists():
- return HttpResponse('no') # 403?
- grb.delete()
- return HttpResponse('')
-
-
-def configuration_delete_view(request, config_id=None):
+def template_delete_view(request, resource_id=None):
if not request.user.is_authenticated:
- return HttpResponse('no') # 403?
- config = get_object_or_404(ResourceTemplate, pk=config_id)
- if not request.user.id == config.owner.id:
- return HttpResponse('no') # 403?
- if Booking.objects.filter(resource__template=config, end__gt=timezone.now()).exists():
- return HttpResponse('no')
- config.delete()
- return HttpResponse('')
+ return HttpResponse(status=403)
+ template = get_object_or_404(ResourceTemplate, pk=resource_id)
+ if not request.user.id == template.owner.id:
+ return HttpResponse(status=403)
+ if Booking.objects.filter(resource__template=template, end__gt=timezone.now()).exists():
+ return HttpResponse(status=403)
+ template.public = False
+ template.temporary = True
+ template.save()
+ return HttpResponse(status=200)
def booking_cancel_view(request, booking_id=None):