Merge "Experimental Compass Support"
[pharos-tools.git] / dashboard / src / account / views.py
1 ##############################################################################
2 # Copyright (c) 2016 Max Breitenfeldt and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10
11 import os
12 import urllib
13
14 import oauth2 as oauth
15 from django.conf import settings
16 from django.contrib import messages
17 from django.contrib.auth import logout, authenticate, login
18 from django.contrib.auth.decorators import login_required
19 from django.contrib.auth.mixins import LoginRequiredMixin
20 from django.contrib.auth.models import User
21 from django.urls import reverse
22 from django.utils.decorators import method_decorator
23 from django.views.generic import RedirectView, TemplateView, UpdateView
24 from jira import JIRA
25 from rest_framework.authtoken.models import Token
26
27 from account.forms import AccountSettingsForm
28 from account.jira_util import SignatureMethod_RSA_SHA1
29 from account.models import UserProfile
30
31
32 @method_decorator(login_required, name='dispatch')
33 class AccountSettingsView(UpdateView):
34     model = UserProfile
35     form_class = AccountSettingsForm
36     template_name_suffix = '_update_form'
37
38     def get_success_url(self):
39         messages.add_message(self.request, messages.INFO,
40                              'Settings saved')
41         return '/'
42
43     def get_object(self, queryset=None):
44         return self.request.user.userprofile
45
46     def get_context_data(self, **kwargs):
47         token, created = Token.objects.get_or_create(user=self.request.user)
48         context = super(AccountSettingsView, self).get_context_data(**kwargs)
49         context.update({'title': "Settings", 'token': token})
50         return context
51
52
53 class JiraLoginView(RedirectView):
54     def get_redirect_url(self, *args, **kwargs):
55         consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
56         client = oauth.Client(consumer)
57         client.set_signature_method(SignatureMethod_RSA_SHA1())
58
59         # Step 1. Get a request token from Jira.
60         try:
61             resp, content = client.request(settings.OAUTH_REQUEST_TOKEN_URL, "POST")
62         except Exception as e:
63             messages.add_message(self.request, messages.ERROR,
64                                  'Error: Connection to Jira failed. Please contact an Administrator')
65             return '/'
66         if resp['status'] != '200':
67             messages.add_message(self.request, messages.ERROR,
68                                  'Error: Connection to Jira failed. Please contact an Administrator')
69             return '/'
70
71         # Step 2. Store the request token in a session for later use.
72         self.request.session['request_token'] = dict(urllib.parse.parse_qsl(content.decode()))
73         # Step 3. Redirect the user to the authentication URL.
74         url = settings.OAUTH_AUTHORIZE_URL + '?oauth_token=' + \
75               self.request.session['request_token']['oauth_token'] + \
76               '&oauth_callback=' + settings.OAUTH_CALLBACK_URL
77         return url
78
79
80 class JiraLogoutView(LoginRequiredMixin, RedirectView):
81     def get_redirect_url(self, *args, **kwargs):
82         logout(self.request)
83         return '/'
84
85
86 class JiraAuthenticatedView(RedirectView):
87     def get_redirect_url(self, *args, **kwargs):
88         # Step 1. Use the request token in the session to build a new client.
89         consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
90         token = oauth.Token(self.request.session['request_token']['oauth_token'],
91                             self.request.session['request_token']['oauth_token_secret'])
92         client = oauth.Client(consumer, token)
93         client.set_signature_method(SignatureMethod_RSA_SHA1())
94
95         # Step 2. Request the authorized access token from Jira.
96         try:
97             resp, content = client.request(settings.OAUTH_ACCESS_TOKEN_URL, "POST")
98         except Exception as e:
99             messages.add_message(self.request, messages.ERROR,
100                                  'Error: Connection to Jira failed. Please contact an Administrator')
101             return '/'
102         if resp['status'] != '200':
103             messages.add_message(self.request, messages.ERROR,
104                                  'Error: Connection to Jira failed. Please contact an Administrator')
105             return '/'
106
107         access_token = dict(urllib.parse.parse_qsl(content.decode()))
108
109         module_dir = os.path.dirname(__file__)  # get current directory
110         with open(module_dir + '/rsa.pem', 'r') as f:
111             key_cert = f.read()
112
113         oauth_dict = {
114             'access_token': access_token['oauth_token'],
115             'access_token_secret': access_token['oauth_token_secret'],
116             'consumer_key': settings.OAUTH_CONSUMER_KEY,
117             'key_cert': key_cert
118         }
119
120         jira = JIRA(server=settings.JIRA_URL, oauth=oauth_dict)
121         username = jira.current_user()
122         email = jira.user(username).emailAddress
123         url = '/'
124         # Step 3. Lookup the user or create them if they don't exist.
125         try:
126             user = User.objects.get(username=username)
127         except User.DoesNotExist:
128             # Save our permanent token and secret for later.
129             user = User.objects.create_user(username=username,
130                                             password=access_token['oauth_token_secret'])
131             profile = UserProfile()
132             profile.user = user
133             profile.save()
134             user.userprofile.email_addr = email
135             url = reverse('account:settings')
136         user.userprofile.oauth_token = access_token['oauth_token']
137         user.userprofile.oauth_secret = access_token['oauth_token_secret']
138         user.userprofile.save()
139         user.set_password(access_token['oauth_token_secret'])
140         user.save()
141         user = authenticate(username=username, password=access_token['oauth_token_secret'])
142         login(self.request, user)
143         # redirect user to settings page to complete profile
144         return url
145
146
147 @method_decorator(login_required, name='dispatch')
148 class UserListView(TemplateView):
149     template_name = "account/user_list.html"
150
151     def get_context_data(self, **kwargs):
152         users = User.objects.all()
153         context = super(UserListView, self).get_context_data(**kwargs)
154         context.update({'title': "Dashboard Users", 'users': users})
155         return context