Private
Public Access
1
0

auth working, getting user data a problem

This commit is contained in:
Sander Roosendaal
2018-06-04 16:11:03 +02:00
parent aa948660a6
commit 30506818a5
10 changed files with 252 additions and 11 deletions

View File

@@ -655,6 +655,12 @@ class Rower(models.Model):
tprefreshtoken = models.CharField(default='',max_length=1000,
blank=True,null=True)
polartoken = models.CharField(default='',max_length=1000,blank=True,null=True)
polartokenexpirydate = models.DateTimeField(blank=True,null=True)
polarrefreshtoken = models.CharField(default='',max_length=1000,
blank=True,null=True)
polaruserid = models.IntegerField(default=0)
stravatoken = models.CharField(default='',max_length=200,blank=True,null=True)
stravaexportas = models.CharField(default="Rowing",
max_length=30,

168
rowers/polarstuff.py Normal file
View File

@@ -0,0 +1,168 @@
# All the functionality needed to connect to Strava
# Python
import oauth2 as oauth
import cgi
import requests
import requests.auth
import json
from django.utils import timezone
from datetime import datetime
import numpy as np
from dateutil import parser
import time
import math
from math import sin,cos,atan2,sqrt
import os,sys
import gzip
import base64
# Django
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse,JsonResponse
from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
# Project
# from .models import Profile
from rowingdata import rowingdata
import pandas as pd
from rowers.models import Rower,Workout
from rowers.models import checkworkoutuser
import dataprep
from dataprep import columndict
import stravalib
from stravalib.exc import ActivityUploadFailed,TimeoutExceeded
from rowsandall_app.settings import (
POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET,
)
# Custom exception handler, returns a 401 HTTP message
# with exception details in the json data
def custom_exception_handler(exc,message):
response = {
"errors": [
{
"code": str(exc),
"detail": message,
}
]
}
res = HttpResponse(message)
res.status_code = 401
res.json = json.dumps(response)
return res
# Custom error class - to raise a NoTokenError
class PolarNoTokenError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
return repr(self.value)
# Exchange access code for long-lived access token
def get_token(code):
post_data = {"grant_type": "authorization_code",
"code": code,
"redirect_uri": POLAR_REDIRECT_URI,
}
auth_string = '{id}:{secret}'.format(
id= POLAR_CLIENT_ID,
secret=POLAR_CLIENT_SECRET
)
headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) }
response = requests.post("https://polarremote.com/v2/oauth2/token",
data=post_data,
headers=headers)
try:
token_json = response.json()
thetoken = token_json['access_token']
expires_in = token_json['expires_in']
user_id = token_json['x_user_id']
except KeyError:
thetoken = 0
expires_in = 0
return [thetoken,expires_in,user_id]
# Make authorization URL including random string
def make_authorization_url(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
params = {"client_id": POLAR_CLIENT_ID,
"response_type": "code",
"redirect_uri": POLAR_REDIRECT_URI,
"scope":"write"}
import urllib
url = "https://flow.polar.com/oauth2/authorization" +urllib.urlencode(params)
return HttpResponseRedirect(url)
def get_polar_workout_list(user):
r = Rower.objects.get(user=user)
if (r.polartoken == '') or (r.polartoken is None):
s = "Token doesn't exist. Need to authorize"
return custom_exception_handler(401,s)
elif (timezone.now()>r.polartokenexpirydate):
s = "Token expired. Needs to refresh"
return custom_exception_handler(401,s)
else:
authorizationstring = str('Bearer ' + r.polartoken)
headers = {'Authorization':authorizationstring,
'Accept': 'application/json'}
url = 'https://polaraccesslink.com/v3/users/{userid}/exercise-transactions'.format(
userid = r.polaruserid
)
response = requests.post(url, headers=headers)
return response
def get_polar_user_info(user):
r = Rower.objects.get(user=user)
if (r.polartoken == '') or (r.polartoken is None):
s = "Token doesn't exist. Need to authorize"
return custom_exception_handler(401,s)
elif (timezone.now()>r.polartokenexpirydate):
s = "Token expired. Needs to refresh"
return custom_exception_handler(401,s)
else:
authorizationstring = str('Bearer ' + r.polartoken)
headers = {
'Authorization':authorizationstring,
'Accept': 'application/json'
}
params = {
'user-id': r.polaruserid
}
url = 'https://polaraccesslink.com/v3/users/{userid}'.format(
userid = r.polaruserid
)
print url
response = requests.get(url, headers=headers)
return response

View File

@@ -92,7 +92,7 @@ When the site is down, this is the appropriate channel to look for apologies, up
602 00 Brno<br />
Czech Republic<br />
IČ: 070 48 572<br />
DIČ: CZ 070 48 572<br />
DIČ: CZ 070 48 572 (Nejsme plátce DPH)<br />
Datová schránka: 7897syr<br />
Email: <a href="mailto:info@rowsandall.com">info@rowsandall.com</a><br />
The company is registered in the business register at the

View File

@@ -1,9 +1,9 @@
{% extends "base.html" %}
{% block title %}Contact Us{% endblock title %}
{% block title %}Import Workouts{% endblock title %}
{% block content %}
<div class="grid_6 alpha">
<h3>Import Workouts</h3>
<h2>Import Workouts</h2>
<div class="grid_6">
<div class="grid_3 alpha">
@@ -56,7 +56,7 @@
</div>
<div class="grid_6 omega">
<h3>Connect</h3>
<h2>Connect</h2>
<div class="grid_6 alpha">
<p>Click one of the below logos to connect to the service of your choice.
@@ -81,9 +81,13 @@
<div class="grid_2 alpha">
<p><a href="/rowers/me/runkeeperauthorize/"><img src="/static/img/rk-logo.png" alt="connect with RunKeeper" width="120"></a></p>
</div>
<div class="grid_2 suffix_2 omega">
<div class="grid_2">
<p><a href="/rowers/me/underarmourauthorize/"><img src="/static/img/UAbtn.png" alt="connect with Under Armour" width="120"></a></p>
</div>
<div class="grid_2 omega">
<p><a href="/rowers/me/polarauthorize/"><img src="/static/img/Polar_connectwith_btn_white.png"
alt="connect with Polar" width="130"></a></p>
</div>
</div>
</div>

View File

@@ -379,6 +379,7 @@ urlpatterns = [
url(r'^rower/edit/(?P<rowerid>\d+)$',views.rower_edit_view),
url(r'^me/edit/(.+.*)/$',views.rower_edit_view),
url(r'^me/c2authorize/$',views.rower_c2_authorize),
url(r'^me/polarauthorize/$',views.rower_polar_authorize),
url(r'^me/revokeapp/(?P<id>\d+)$',views.rower_revokeapp_view),
url(r'^me/stravaauthorize/$',views.rower_strava_authorize),
url(r'^me/sporttracksauthorize/$',views.rower_sporttracks_authorize),

View File

@@ -21,6 +21,7 @@ from django.views.decorators.csrf import csrf_exempt
from matplotlib.backends.backend_agg import FigureCanvas
import gc
from pyparsing import ParseException
from uuid import uuid4
from django.shortcuts import render
from django.http import (
@@ -93,6 +94,8 @@ from sporttracksstuff import SportTracksNoTokenError,sporttracks_open
from tpstuff import TPNoTokenError,tp_open
from iso8601 import ParseError
import stravastuff
import polarstuff
from polarstuff import PolarNoTokenError
from stravastuff import StravaNoTokenError
import sporttracksstuff
import underarmourstuff
@@ -104,6 +107,7 @@ from ownapistuff import TEST_CLIENT_ID, TEST_CLIENT_SECRET, TEST_REDIRECT_URI
from rowsandall_app.settings import (
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET,
SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI,
SPORTTRACKS_CLIENT_SECRET,
UNDERARMOUR_CLIENT_ID, UNDERARMOUR_REDIRECT_URI,
@@ -2358,7 +2362,7 @@ def workout_sporttracks_upload_view(request,id=0):
def rower_c2_authorize(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
scope = "user:read,results:write"
params = {"client_id": C2_CLIENT_ID,
@@ -2373,7 +2377,7 @@ def rower_c2_authorize(request):
def rower_strava_authorize(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
params = {"client_id": STRAVA_CLIENT_ID,
@@ -2385,12 +2389,30 @@ def rower_strava_authorize(request):
return HttpResponseRedirect(url)
# Polar Authorization
@login_required()
def rower_polar_authorize(request):
state = str(uuid4())
params = {"client_id": POLAR_CLIENT_ID,
"response_type": "code",
"redirect_uri": POLAR_REDIRECT_URI,
"state": state,
# "scope":"accesslink.read_all"
}
url = "https://flow.polar.com/oauth2/authorization?" +urllib.urlencode(params)
return HttpResponseRedirect(url)
# Runkeeper authorization
@login_required()
def rower_runkeeper_authorize(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
params = {"client_id": RUNKEEPER_CLIENT_ID,
@@ -2408,7 +2430,7 @@ def rower_runkeeper_authorize(request):
def rower_sporttracks_authorize(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
params = {"client_id": SPORTTRACKS_CLIENT_ID,
@@ -2426,7 +2448,7 @@ def rower_sporttracks_authorize(request):
def rower_underarmour_authorize(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
redirect_uri = UNDERARMOUR_REDIRECT_URI
@@ -2443,7 +2465,7 @@ def rower_underarmour_authorize(request):
def rower_tp_authorize(request):
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
from uuid import uuid4
state = str(uuid4())
params = {"client_id": TP_CLIENT_KEY,
"response_type": "code",
@@ -2608,6 +2630,40 @@ def test_reverse_view(request):
def rower_process_twittercallback(request):
return "dummy"
# Process Polar Callback
@login_required()
def rower_process_polarcallback(request):
try:
code = request.GET['code']
except MultiValueDictKeyError:
try:
message = request.GET['error']
except MultiValueDictKeyError:
message = "access error"
messages.error(request,message)
return imports_view(request)
res = polarstuff.get_token(code)
access_token = res[0]
expires_in = res[1]
user_id = res[2]
expirydatetime = timezone.now()+datetime.timedelta(seconds=expires_in)
r = getrower(request.user)
r.polartoken = access_token
r.polartokenexpirydate = expirydatetime
r.polaruserid = user_id
r.save()
successmessage = "Tokens stored. Good to go"
messages.info(request,successmessage)
return imports_view(request)
# Process Strava Callback
@login_required()
def rower_process_stravacallback(request):

View File

@@ -254,6 +254,11 @@ RUNKEEPER_CLIENT_ID = CFG['runkeeper_client_id']
RUNKEEPER_CLIENT_SECRET = CFG['runkeeper_client_secret']
RUNKEEPER_REDIRECT_URI = CFG['runkeeper_callback']
# Polar Flow
POLAR_CLIENT_ID = CFG['polarflow_client_id']
POLAR_CLIENT_SECRET = CFG['polarflow_client_secret']
POLAR_REDIRECT_URI = CFG['polarflow_callback']
# Under Armour

View File

@@ -71,6 +71,7 @@ urlpatterns += [
url(r'^stravacall\_back',rowersviews.rower_process_stravacallback),
url(r'^sporttracks\_callback',rowersviews.rower_process_sporttrackscallback),
url(r'^underarmour\_callback',rowersviews.rower_process_underarmourcallback),
url(r'^polarflowcallback',rowersviews.rower_process_polarcallback),
url(r'^runkeeper\_callback',rowersviews.rower_process_runkeepercallback),
url(r'^tp\_callback',rowersviews.rower_process_tpcallback),
url(r'^twitter\_callback',rowersviews.rower_process_twittercallback),

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB