1 ##############################################################################
2 # Copyright (c) 2016 Max Breitenfeldt and others.
3 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
15 import oauth2 as oauth
16 from django.conf import settings
17 from django.contrib import messages
18 from django.contrib.auth import logout, authenticate, login
19 from django.contrib.auth.decorators import login_required
20 from django.contrib.auth.mixins import LoginRequiredMixin
21 from django.contrib.auth.models import User
22 from django.urls import reverse
23 from django.utils.decorators import method_decorator
24 from django.views.generic import RedirectView, TemplateView, UpdateView
25 from django.shortcuts import render
27 from rest_framework.authtoken.models import Token
29 from account.forms import AccountSettingsForm
30 from account.jira_util import SignatureMethod_RSA_SHA1
31 from account.models import UserProfile
32 from booking.models import Booking
33 from resource_inventory.models import GenericResourceBundle, ConfigBundle, Image
36 @method_decorator(login_required, name='dispatch')
37 class AccountSettingsView(UpdateView):
39 form_class = AccountSettingsForm
40 template_name_suffix = '_update_form'
42 def get_success_url(self):
43 messages.add_message(self.request, messages.INFO,
47 def get_object(self, queryset=None):
48 return self.request.user.userprofile
50 def get_context_data(self, **kwargs):
51 token, created = Token.objects.get_or_create(user=self.request.user)
52 context = super(AccountSettingsView, self).get_context_data(**kwargs)
53 context.update({'title': "Settings", 'token': token})
57 class JiraLoginView(RedirectView):
58 def get_redirect_url(self, *args, **kwargs):
59 consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
60 client = oauth.Client(consumer)
61 client.set_signature_method(SignatureMethod_RSA_SHA1())
63 # Step 1. Get a request token from Jira.
65 resp, content = client.request(settings.OAUTH_REQUEST_TOKEN_URL, "POST")
66 except Exception as e:
67 messages.add_message(self.request, messages.ERROR,
68 'Error: Connection to Jira failed. Please contact an Administrator')
70 if resp['status'] != '200':
71 messages.add_message(self.request, messages.ERROR,
72 'Error: Connection to Jira failed. Please contact an Administrator')
75 # Step 2. Store the request token in a session for later use.
76 self.request.session['request_token'] = dict(urllib.parse.parse_qsl(content.decode()))
77 # Step 3. Redirect the user to the authentication URL.
78 url = settings.OAUTH_AUTHORIZE_URL + '?oauth_token=' + \
79 self.request.session['request_token']['oauth_token'] + \
80 '&oauth_callback=' + settings.OAUTH_CALLBACK_URL
84 class JiraLogoutView(LoginRequiredMixin, RedirectView):
85 def get_redirect_url(self, *args, **kwargs):
90 class JiraAuthenticatedView(RedirectView):
91 def get_redirect_url(self, *args, **kwargs):
92 # Step 1. Use the request token in the session to build a new client.
93 consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
94 token = oauth.Token(self.request.session['request_token']['oauth_token'],
95 self.request.session['request_token']['oauth_token_secret'])
96 client = oauth.Client(consumer, token)
97 client.set_signature_method(SignatureMethod_RSA_SHA1())
99 # Step 2. Request the authorized access token from Jira.
101 resp, content = client.request(settings.OAUTH_ACCESS_TOKEN_URL, "POST")
102 except Exception as e:
103 messages.add_message(self.request, messages.ERROR,
104 'Error: Connection to Jira failed. Please contact an Administrator')
106 if resp['status'] != '200':
107 messages.add_message(self.request, messages.ERROR,
108 'Error: Connection to Jira failed. Please contact an Administrator')
111 access_token = dict(urllib.parse.parse_qsl(content.decode()))
113 module_dir = os.path.dirname(__file__) # get current directory
114 with open(module_dir + '/rsa.pem', 'r') as f:
118 'access_token': access_token['oauth_token'],
119 'access_token_secret': access_token['oauth_token_secret'],
120 'consumer_key': settings.OAUTH_CONSUMER_KEY,
124 jira = JIRA(server=settings.JIRA_URL, oauth=oauth_dict)
125 username = jira.current_user()
126 email = jira.user(username).emailAddress
128 # Step 3. Lookup the user or create them if they don't exist.
130 user = User.objects.get(username=username)
131 except User.DoesNotExist:
132 # Save our permanent token and secret for later.
133 user = User.objects.create_user(username=username,
134 password=access_token['oauth_token_secret'])
135 profile = UserProfile()
138 user.userprofile.email_addr = email
139 url = reverse('account:settings')
140 user.userprofile.oauth_token = access_token['oauth_token']
141 user.userprofile.oauth_secret = access_token['oauth_token_secret']
142 user.userprofile.save()
143 user.set_password(access_token['oauth_token_secret'])
145 user = authenticate(username=username, password=access_token['oauth_token_secret'])
146 login(self.request, user)
147 # redirect user to settings page to complete profile
151 @method_decorator(login_required, name='dispatch')
152 class UserListView(TemplateView):
153 template_name = "account/user_list.html"
155 def get_context_data(self, **kwargs):
156 users = User.objects.all()
157 context = super(UserListView, self).get_context_data(**kwargs)
158 context.update({'title': "Dashboard Users", 'users': users})
162 def account_detail_view(request):
163 template = "account/details.html"
164 return render(request, template)
166 def account_resource_view(request):
168 gathers a users genericResoureBundles and
169 turns them into displayable objects
171 if not request.user.is_authenticated:
172 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
173 template = "account/resource_list.html"
174 resources = list(GenericResourceBundle.objects.filter(owner=request.user))
175 context = {"resources": resources, "title": "My Resources"}
176 return render(request, template, context=context)
178 def account_booking_view(request):
179 if not request.user.is_authenticated:
180 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
181 template = "account/booking_list.html"
182 bookings = list(Booking.objects.filter(owner=request.user))
183 collab_bookings = list(request.user.collaborators.all())
184 context = {"title": "My Bookings", "bookings": bookings, "collab_bookings": collab_bookings}
185 return render(request, template, context=context)
187 def account_configuration_view(request):
188 if not request.user.is_authenticated:
189 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
190 template = "account/configuration_list.html"
191 configs = list(ConfigBundle.objects.filter(owner=request.user))
192 context = {"title": "Configuration List", "configurations": configs}
193 return render(request, template, context=context)
195 def account_images_view(request):
196 if not request.user.is_authenticated:
197 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
198 template = "account/image_list.html"
199 my_images = Image.objects.filter(owner=request.user)
200 public_images = Image.objects.filter(public=True)
201 context = {"title": "Images", "images": my_images, "public_images": public_images }
202 return render(request, template, context=context)