diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 6b5bae94..c7fe2a0b 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -77,7 +77,7 @@ from rowsandall_app.settings import SITE_URL from rowers.mytypes import otwtypes from rowers.database import * - +from rowers.opaque import encoder # mapping the DB column names to the CSV file column names @@ -1139,7 +1139,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', btvalues=btvalues.to_json()) - return (w.id, message) + return (encoder.encode_hex(w.id), message) parsers = { 'kinomap': KinoMapParser, @@ -1404,7 +1404,7 @@ def split_workout(r, parent, splitsecond, splitmode): setprivate=setprivate, forceunit='N') messages.append(message) - ids.append(id) + ids.append(encoder.encode_hex(id)) if 'keep second' in splitmode: data2['cumdist'] = data2['cumdist'] - data2.iloc[ 0, @@ -1431,7 +1431,7 @@ def split_workout(r, parent, splitsecond, splitmode): setprivate=setprivate, dt=dt, forceunit='N') messages.append(message) - ids.append(id) + ids.append(encoder.encode_hex(id)) if not 'keep original' in splitmode: if 'keep second' in splitmode or 'keep first' in splitmode: @@ -1439,7 +1439,7 @@ def split_workout(r, parent, splitsecond, splitmode): messages.append('Deleted Workout: ' + parent.name) else: messages.append('That would delete your workout') - ids.append(parent.id) + ids.append(encoder.encode_hex(parent.id)) elif 'originalprivate' in splitmode: parent.privacy = 'hidden' parent.save() diff --git a/rowers/opaque.py b/rowers/opaque.py new file mode 100644 index 00000000..0fc59a69 --- /dev/null +++ b/rowers/opaque.py @@ -0,0 +1,59 @@ +import struct +import base64 + +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, + UNDERARMOUR_CLIENT_SECRET,UNDERARMOUR_CLIENT_KEY, + RUNKEEPER_CLIENT_ID,RUNKEEPER_REDIRECT_URI,RUNKEEPER_CLIENT_SECRET, + TP_CLIENT_ID,TP_REDIRECT_URI,TP_CLIENT_KEY,TP_CLIENT_SECRET, + BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY, + PAYMENT_PROCESSING_ON,OPAQUE_SECRET_KEY + ) + +class OpaqueEncoder: + """ + Opaque ID encoder. + Translates between 32-bit integers (such as resource IDs) and obfuscated + scrambled values, as a one-to-one mapping. Supports hex and base64 url-safe + string representations. Expects a secret integer key in the constructor. + (c) 2011 Marek Z. @marekweb + """ + + def __init__(self, key): + self.key = key + self.extra_chars = b'.-'; + + def transform(self, i): + """Produce an integer hash of a 16-bit integer, returning a transformed 16-bit integer.""" + i = (self.key ^ i) * 0x9e3b + return i >> (i & 0xf) & 0xffff + + def transcode(self, i): + """Reversibly transcode a 32-bit integer to a scrambled form, returning a new 32-bit integer.""" + r = i & 0xffff + l = i >> 16 & 0xffff ^ self.transform(r) + return ((r ^ self.transform(l)) << 16) + l + + def encode_hex(self, i): + """Transcode an integer and return it as an 8-character hex string.""" + return "%08x" % self.transcode(i) + + def encode_base64(self, i): + """Transcode an integer and return it as a 6-character base64 string.""" + return base64.b64encode(struct.pack('!L', self.transcode(i)), self.extra_chars)[:6] + + def decode_hex(self, s): + """Decode an 8-character hex string, returning the original integer.""" + return self.transcode(int(s, 16)) + + def decode_base64(self, s): + """Decode a 6-character base64 string, returning the original integer.""" + return self.transcode(struct.unpack('!L', base64.b64decode(s + '==', self.extra_chars))[0]) + + +encoder = OpaqueEncoder(OPAQUE_SECRET_KEY) diff --git a/rowers/templates/image_form.html b/rowers/templates/image_form.html index f0dccc5a..142d7ecf 100644 --- a/rowers/templates/image_form.html +++ b/rowers/templates/image_form.html @@ -171,7 +171,7 @@ $.ajax({ data: data, type: $(this).attr('method'), - url: '/rowers/workout/{{ workout.id }}/image', + url: '/rowers/workout/{{ workout.id|encode }}/image', contentType: false, processData: false, error: function(result) { diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html index 2ccb8c53..01251d8a 100644 --- a/rowers/templates/list_workouts.html +++ b/rowers/templates/list_workouts.html @@ -180,11 +180,11 @@