Merge branch 'decorators_refacto' into dev

This commit is contained in:
Sam 2021-12-01 20:34:21 +01:00
commit eaa5eeb897
19 changed files with 143 additions and 247 deletions

View File

@ -11,6 +11,8 @@ build-client: lint-client
check-all: lint-all type-check test-python test-client check-all: lint-all type-check test-python test-client
check-python: lint-python type-check test-python
clean: clean:
rm -rf .mypy_cache rm -rf .mypy_cache
rm -rf .pytest_cache rm -rf .pytest_cache

View File

@ -191,13 +191,8 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Request JSON Object</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Request JSON Object</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>gpx_limit_import</strong> (<em>integer</em>) max number of files in zip archive</p></li> <li><p><strong>gpx_limit_import</strong> (<em>integer</em>) max number of files in zip archive</p></li>
<li><p><strong>is_registration_enabled</strong> (<em>boolean</em>) is registration enabled ?</p></li> <li><p><strong>is_registration_enabled</strong> (<em>boolean</em>) is registration enabled ?</p></li>
<li><p><strong>max_single_file_size</strong> (<em>integer</em>) max size of a single file</p></li> <li><p><strong>max_single_file_size</strong> (<em>integer</em>) max size of a single file</p></li>
@ -205,13 +200,13 @@
<li><p><strong>max_users</strong> (<em>integer</em>) max users allowed to register on instance</p></li> <li><p><strong>max_users</strong> (<em>integer</em>) max users allowed to register on instance</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Request Headers</dt> <dt class="field-even">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-even">Status Codes</dt> <dt class="field-odd">Status Codes</dt>
<dd class="field-even"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">400 Bad Request</a></span> invalid payload</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">400 Bad Request</a></span> invalid payload</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>

View File

@ -212,18 +212,13 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Request Headers</dt>
<dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Status Codes</dt> <dt class="field-even">Status Codes</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>
<li><p>provide a valid auth token</p></li> <li><p>provide a valid auth token</p></li>

View File

@ -270,18 +270,13 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Request Headers</dt>
<dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Status Codes</dt> <dt class="field-even">Status Codes</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>
<li><p>provide a valid auth token</p></li> <li><p>provide a valid auth token</p></li>
@ -368,7 +363,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>sport_id</strong> (<em>integer</em>) sport id</p></li> <li><p><strong>sport_id</strong> (<em>integer</em>) sport id</p></li>
</ul> </ul>
</dd> </dd>
@ -444,7 +438,6 @@ Authenticated user must be an admin</p>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>sport_id</strong> (<em>integer</em>) sport id</p></li> <li><p><strong>sport_id</strong> (<em>integer</em>) sport id</p></li>
</ul> </ul>
</dd> </dd>

View File

@ -206,7 +206,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>user_name</strong> (<em>integer</em>) user name</p></li> <li><p><strong>user_name</strong> (<em>integer</em>) user name</p></li>
</ul> </ul>
</dd> </dd>
@ -321,7 +320,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>user_name</strong> (<em>integer</em>) user name</p></li> <li><p><strong>user_name</strong> (<em>integer</em>) user name</p></li>
</ul> </ul>
</dd> </dd>
@ -378,18 +376,13 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Request Headers</dt>
<dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Status Codes</dt> <dt class="field-even">Status Codes</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>
<li><p>provide a valid auth token</p></li> <li><p>provide a valid auth token</p></li>

View File

@ -242,13 +242,8 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Query Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Query Parameters</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>page</strong> (<em>integer</em>) page if using pagination (default: 1)</p></li> <li><p><strong>page</strong> (<em>integer</em>) page if using pagination (default: 1)</p></li>
<li><p><strong>per_page</strong> (<em>integer</em>) number of users per page (default: 10, max: 50)</p></li> <li><p><strong>per_page</strong> (<em>integer</em>) number of users per page (default: 10, max: 50)</p></li>
<li><p><strong>q</strong> (<em>string</em>) query on user name</p></li> <li><p><strong>q</strong> (<em>string</em>) query on user name</p></li>
@ -257,13 +252,13 @@
<li><p><strong>order</strong> (<em>string</em>) sorting order (default: <code class="docutils literal notranslate"><span class="pre">asc</span></code>)</p></li> <li><p><strong>order</strong> (<em>string</em>) sorting order (default: <code class="docutils literal notranslate"><span class="pre">asc</span></code>)</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Request Headers</dt> <dt class="field-even">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-even">Status Codes</dt> <dt class="field-odd">Status Codes</dt>
<dd class="field-even"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>
<li><p>provide a valid auth token</p></li> <li><p>provide a valid auth token</p></li>
@ -361,7 +356,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>user_name</strong> (<em>integer</em>) user name</p></li> <li><p><strong>user_name</strong> (<em>integer</em>) user name</p></li>
</ul> </ul>
</dd> </dd>
@ -507,7 +501,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>user_name</strong> (<em>string</em>) user name</p></li> <li><p><strong>user_name</strong> (<em>string</em>) user name</p></li>
</ul> </ul>
</dd> </dd>
@ -561,7 +554,6 @@ one admin</p>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>user_name</strong> (<em>string</em>) user name</p></li> <li><p><strong>user_name</strong> (<em>string</em>) user name</p></li>
</ul> </ul>
</dd> </dd>

View File

@ -241,13 +241,8 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Query Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Query Parameters</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>page</strong> (<em>integer</em>) page if using pagination (default: 1)</p></li> <li><p><strong>page</strong> (<em>integer</em>) page if using pagination (default: 1)</p></li>
<li><p><strong>per_page</strong> (<em>integer</em>) number of workouts per page <li><p><strong>per_page</strong> (<em>integer</em>) number of workouts per page
(default: 5, max: 100)</p></li> (default: 5, max: 100)</p></li>
@ -265,13 +260,13 @@
<li><p><strong>order</strong> (<em>string</em>) sorting order (default: <code class="docutils literal notranslate"><span class="pre">desc</span></code>)</p></li> <li><p><strong>order</strong> (<em>string</em>) sorting order (default: <code class="docutils literal notranslate"><span class="pre">desc</span></code>)</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Request Headers</dt> <dt class="field-even">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-even">Status Codes</dt> <dt class="field-odd">Status Codes</dt>
<dd class="field-even"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1">200 OK</a></span> success</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>
<li><p>provide a valid auth token</p></li> <li><p>provide a valid auth token</p></li>
@ -355,7 +350,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
</ul> </ul>
</dd> </dd>
@ -405,7 +399,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
</ul> </ul>
</dd> </dd>
@ -478,7 +471,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
</ul> </ul>
</dd> </dd>
@ -551,7 +543,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
<li><p><strong>segment_id</strong> (<em>integer</em>) segment id</p></li> <li><p><strong>segment_id</strong> (<em>integer</em>) segment id</p></li>
</ul> </ul>
@ -603,7 +594,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
<li><p><strong>segment_id</strong> (<em>integer</em>) segment id</p></li> <li><p><strong>segment_id</strong> (<em>integer</em>) segment id</p></li>
</ul> </ul>
@ -708,7 +698,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
</ul> </ul>
</dd> </dd>
@ -820,24 +809,19 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Form Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Form Parameters</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>file</strong> gpx file (allowed extensions: .gpx, .zip)</p></li> <li><p><strong>file</strong> gpx file (allowed extensions: .gpx, .zip)</p></li>
<li><p><strong>data</strong> sport id and notes (example: <code class="docutils literal notranslate"><span class="pre">{&quot;sport_id&quot;:</span> <span class="pre">1,</span> <span class="pre">&quot;notes&quot;:</span> <span class="pre">&quot;&quot;}</span></code>)</p></li> <li><p><strong>data</strong> sport id and notes (example: <code class="docutils literal notranslate"><span class="pre">{&quot;sport_id&quot;:</span> <span class="pre">1,</span> <span class="pre">&quot;notes&quot;:</span> <span class="pre">&quot;&quot;}</span></code>)</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Request Headers</dt> <dt class="field-even">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-even">Status Codes</dt> <dt class="field-odd">Status Codes</dt>
<dd class="field-even"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2">201 Created</a></span> workout created</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2">201 Created</a></span> workout created</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">400 Bad Request</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">400 Bad Request</a></span> <ul>
<li><p>invalid payload</p></li> <li><p>invalid payload</p></li>
@ -948,13 +932,8 @@
</pre></div> </pre></div>
</div> </div>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Request JSON Object</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
</ul>
</dd>
<dt class="field-even">Request JSON Object</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>workout_date</strong> (<em>string</em>) workout date (format: <code class="docutils literal notranslate"><span class="pre">%Y-%m-%d</span> <span class="pre">%H:%M</span></code>)</p></li> <li><p><strong>workout_date</strong> (<em>string</em>) workout date (format: <code class="docutils literal notranslate"><span class="pre">%Y-%m-%d</span> <span class="pre">%H:%M</span></code>)</p></li>
<li><p><strong>distance</strong> (<em>float</em>) workout distance in km</p></li> <li><p><strong>distance</strong> (<em>float</em>) workout distance in km</p></li>
<li><p><strong>duration</strong> (<em>integer</em>) workout duration in seconds</p></li> <li><p><strong>duration</strong> (<em>integer</em>) workout duration in seconds</p></li>
@ -963,13 +942,13 @@
<li><p><strong>title</strong> (<em>string</em>) workout title</p></li> <li><p><strong>title</strong> (<em>string</em>) workout title</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-odd">Request Headers</dt> <dt class="field-even">Request Headers</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-even"><ul class="simple">
<li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li> <li><p><span><a class="reference external" href="https://tools.ietf.org/html/rfc7235#section-4.2">Authorization</a></span> OAuth 2.0 Bearer Token</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-even">Status Codes</dt> <dt class="field-odd">Status Codes</dt>
<dd class="field-even"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2">201 Created</a></span> workout created</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2">201 Created</a></span> workout created</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">400 Bad Request</a></span> invalid payload</p></li> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1">400 Bad Request</a></span> invalid payload</p></li>
<li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul> <li><p><span><a class="reference external" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">401 Unauthorized</a></span> <ul>
@ -1075,7 +1054,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
</ul> </ul>
</dd> </dd>
@ -1131,7 +1109,6 @@
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>auth_user_id</strong> (<em>integer</em>) authenticate user id (from JSON Web Token)</p></li>
<li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li> <li><p><strong>workout_short_id</strong> (<em>string</em>) workout short id</p></li>
</ul> </ul>
</dd> </dd>

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,7 @@ from fittrackee.responses import (
handle_error_and_return_response, handle_error_and_return_response,
) )
from fittrackee.users.decorators import authenticate_as_admin from fittrackee.users.decorators import authenticate_as_admin
from fittrackee.users.models import User
from .models import AppConfig from .models import AppConfig
from .utils import update_app_config_from_database, verify_app_config from .utils import update_app_config_from_database, verify_app_config
@ -64,7 +65,7 @@ def get_application_config() -> Union[Dict, HttpResponse]:
@config_blueprint.route('/config', methods=['PATCH']) @config_blueprint.route('/config', methods=['PATCH'])
@authenticate_as_admin @authenticate_as_admin
def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]: def update_application_config(auth_user: User) -> Union[Dict, HttpResponse]:
""" """
Update Application config Update Application config
@ -95,8 +96,6 @@ def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:<json integer gpx_limit_import: max number of files in zip archive :<json integer gpx_limit_import: max number of files in zip archive
:<json boolean is_registration_enabled: is registration enabled ? :<json boolean is_registration_enabled: is registration enabled ?
:<json integer max_single_file_size: max size of a single file :<json integer max_single_file_size: max size of a single file

View File

@ -46,7 +46,7 @@ class TestStoppedSpeedThreshold:
) as gpx_track_segment_mock: ) as gpx_track_segment_mock:
process_files( process_files(
auth_user_id=user_1.id, auth_user=user_1,
folders=folders, folders=folders,
workout_data={'sport_id': sport_id}, workout_data={'sport_id': sport_id},
workout_file=gpx_file_storage, workout_file=gpx_file_storage,
@ -76,7 +76,7 @@ class TestStoppedSpeedThreshold:
) as gpx_track_segment_mock: ) as gpx_track_segment_mock:
process_files( process_files(
auth_user_id=user_1.id, auth_user=user_1,
folders=folders, folders=folders,
workout_data={'sport_id': sport_1_cycling.id}, workout_data={'sport_id': sport_1_cycling.id},
workout_file=gpx_file_storage, workout_file=gpx_file_storage,

View File

@ -224,7 +224,7 @@ def login_user() -> Union[Dict, HttpResponse]:
@auth_blueprint.route('/auth/logout', methods=['GET']) @auth_blueprint.route('/auth/logout', methods=['GET'])
@authenticate @authenticate
def logout_user(auth_user_id: int) -> Union[Dict, HttpResponse]: def logout_user(auth_user: User) -> Union[Dict, HttpResponse]:
""" """
user logout user logout
@ -274,7 +274,7 @@ def logout_user(auth_user_id: int) -> Union[Dict, HttpResponse]:
auth_token = auth_header.split(' ')[1] auth_token = auth_header.split(' ')[1]
resp = User.decode_auth_token(auth_token) resp = User.decode_auth_token(auth_token)
if isinstance(auth_user_id, str): if isinstance(resp, str):
return UnauthorizedErrorResponse(resp) return UnauthorizedErrorResponse(resp)
return { return {
@ -286,7 +286,7 @@ def logout_user(auth_user_id: int) -> Union[Dict, HttpResponse]:
@auth_blueprint.route('/auth/profile', methods=['GET']) @auth_blueprint.route('/auth/profile', methods=['GET'])
@authenticate @authenticate
def get_authenticated_user_profile( def get_authenticated_user_profile(
auth_user_id: int, auth_user: User,
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
get authenticated user info get authenticated user info
@ -381,13 +381,12 @@ def get_authenticated_user_profile(
- invalid token, please log in again - invalid token, please log in again
""" """
user = User.query.filter_by(id=auth_user_id).first() return {'status': 'success', 'data': auth_user.serialize()}
return {'status': 'success', 'data': user.serialize()}
@auth_blueprint.route('/auth/profile/edit', methods=['POST']) @auth_blueprint.route('/auth/profile/edit', methods=['POST'])
@authenticate @authenticate
def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]: def edit_user(auth_user: User) -> Union[Dict, HttpResponse]:
""" """
edit authenticated user edit authenticated user
@ -523,24 +522,23 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]:
).decode() ).decode()
try: try:
user = User.query.filter_by(id=auth_user_id).first() auth_user.first_name = first_name
user.first_name = first_name auth_user.last_name = last_name
user.last_name = last_name auth_user.bio = bio
user.bio = bio auth_user.location = location
user.location = location auth_user.birth_date = (
user.birth_date = (
datetime.datetime.strptime(birth_date, '%Y-%m-%d') datetime.datetime.strptime(birth_date, '%Y-%m-%d')
if birth_date if birth_date
else None else None
) )
if password is not None and password != '': if password is not None and password != '':
user.password = password auth_user.password = password
db.session.commit() db.session.commit()
return { return {
'status': 'success', 'status': 'success',
'message': 'user profile updated', 'message': 'user profile updated',
'data': user.serialize(), 'data': auth_user.serialize(),
} }
# handler errors # handler errors
@ -550,7 +548,7 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]:
@auth_blueprint.route('/auth/profile/edit/preferences', methods=['POST']) @auth_blueprint.route('/auth/profile/edit/preferences', methods=['POST'])
@authenticate @authenticate
def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
""" """
edit authenticated user preferences edit authenticated user preferences
@ -670,17 +668,16 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]:
weekm = post_data.get('weekm') weekm = post_data.get('weekm')
try: try:
user = User.query.filter_by(id=auth_user_id).first() auth_user.imperial_units = imperial_units
user.imperial_units = imperial_units auth_user.language = language
user.language = language auth_user.timezone = timezone
user.timezone = timezone auth_user.weekm = weekm
user.weekm = weekm
db.session.commit() db.session.commit()
return { return {
'status': 'success', 'status': 'success',
'message': 'user preferences updated', 'message': 'user preferences updated',
'data': user.serialize(), 'data': auth_user.serialize(),
} }
# handler errors # handler errors
@ -691,7 +688,7 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]:
@auth_blueprint.route('/auth/profile/edit/sports', methods=['POST']) @auth_blueprint.route('/auth/profile/edit/sports', methods=['POST'])
@authenticate @authenticate
def edit_user_sport_preferences( def edit_user_sport_preferences(
auth_user_id: int, auth_user: User,
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
edit authenticated user sport preferences edit authenticated user sport preferences
@ -758,12 +755,12 @@ def edit_user_sport_preferences(
try: try:
user_sport = UserSportPreference.query.filter_by( user_sport = UserSportPreference.query.filter_by(
user_id=auth_user_id, user_id=auth_user.id,
sport_id=sport_id, sport_id=sport_id,
).first() ).first()
if not user_sport: if not user_sport:
user_sport = UserSportPreference( user_sport = UserSportPreference(
user_id=auth_user_id, user_id=auth_user.id,
sport_id=sport_id, sport_id=sport_id,
stopped_speed_threshold=sport.stopped_speed_threshold, stopped_speed_threshold=sport.stopped_speed_threshold,
) )
@ -792,7 +789,7 @@ def edit_user_sport_preferences(
@auth_blueprint.route('/auth/picture', methods=['POST']) @auth_blueprint.route('/auth/picture', methods=['POST'])
@authenticate @authenticate
def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]: def edit_picture(auth_user: User) -> Union[Dict, HttpResponse]:
""" """
update authenticated user picture update authenticated user picture
@ -848,23 +845,22 @@ def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]:
file = request.files['file'] file = request.files['file']
filename = secure_filename(file.filename) # type: ignore filename = secure_filename(file.filename) # type: ignore
dirpath = os.path.join( dirpath = os.path.join(
current_app.config['UPLOAD_FOLDER'], 'pictures', str(auth_user_id) current_app.config['UPLOAD_FOLDER'], 'pictures', str(auth_user.id)
) )
if not os.path.exists(dirpath): if not os.path.exists(dirpath):
os.makedirs(dirpath) os.makedirs(dirpath)
absolute_picture_path = os.path.join(dirpath, filename) absolute_picture_path = os.path.join(dirpath, filename)
relative_picture_path = os.path.join( relative_picture_path = os.path.join(
'pictures', str(auth_user_id), filename 'pictures', str(auth_user.id), filename
) )
try: try:
user = User.query.filter_by(id=auth_user_id).first() if auth_user.picture is not None:
if user.picture is not None: old_picture_path = get_absolute_file_path(auth_user.picture)
old_picture_path = get_absolute_file_path(user.picture)
if os.path.isfile(get_absolute_file_path(old_picture_path)): if os.path.isfile(get_absolute_file_path(old_picture_path)):
os.remove(old_picture_path) os.remove(old_picture_path)
file.save(absolute_picture_path) file.save(absolute_picture_path)
user.picture = relative_picture_path auth_user.picture = relative_picture_path
db.session.commit() db.session.commit()
return { return {
'status': 'success', 'status': 'success',
@ -879,7 +875,7 @@ def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]:
@auth_blueprint.route('/auth/picture', methods=['DELETE']) @auth_blueprint.route('/auth/picture', methods=['DELETE'])
@authenticate @authenticate
def del_picture(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: def del_picture(auth_user: User) -> Union[Tuple[Dict, int], HttpResponse]:
""" """
delete authenticated user picture delete authenticated user picture
@ -908,11 +904,10 @@ def del_picture(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]:
""" """
try: try:
user = User.query.filter_by(id=auth_user_id).first() picture_path = get_absolute_file_path(auth_user.picture)
picture_path = get_absolute_file_path(user.picture)
if os.path.isfile(picture_path): if os.path.isfile(picture_path):
os.remove(picture_path) os.remove(picture_path)
user.picture = None auth_user.picture = None
db.session.commit() db.session.commit()
return {'status': 'no content'}, 204 return {'status': 'no content'}, 204
except (exc.IntegrityError, ValueError) as e: except (exc.IntegrityError, ValueError) as e:

View File

@ -8,16 +8,22 @@ from fittrackee.responses import HttpResponse
from .utils import verify_user from .utils import verify_user
def verify_auth_user(
f: Callable, verify_admin: bool, *args: Any, **kwargs: Any
) -> Union[Callable, HttpResponse]:
response_object, user = verify_user(request, verify_admin=verify_admin)
if response_object:
return response_object
return f(user, *args, **kwargs)
def authenticate(f: Callable) -> Callable: def authenticate(f: Callable) -> Callable:
@wraps(f) @wraps(f)
def decorated_function( def decorated_function(
*args: Any, **kwargs: Any *args: Any, **kwargs: Any
) -> Union[Callable, HttpResponse]: ) -> Union[Callable, HttpResponse]:
verify_admin = False verify_admin = False
response_object, resp = verify_user(request, verify_admin) return verify_auth_user(f, verify_admin, *args, **kwargs)
if response_object:
return response_object
return f(resp, *args, **kwargs)
return decorated_function return decorated_function
@ -28,9 +34,6 @@ def authenticate_as_admin(f: Callable) -> Callable:
*args: Any, **kwargs: Any *args: Any, **kwargs: Any
) -> Union[Callable, HttpResponse]: ) -> Union[Callable, HttpResponse]:
verify_admin = True verify_admin = True
response_object, resp = verify_user(request, verify_admin) return verify_auth_user(f, verify_admin, *args, **kwargs)
if response_object:
return response_object
return f(resp, *args, **kwargs)
return decorated_function return decorated_function

View File

@ -27,7 +27,7 @@ USER_PER_PAGE = 10
@users_blueprint.route('/users', methods=['GET']) @users_blueprint.route('/users', methods=['GET'])
@authenticate @authenticate
def get_users(auth_user_id: int) -> Dict: def get_users(auth_user: User) -> Dict:
""" """
Get all users Get all users
@ -144,8 +144,6 @@ def get_users(auth_user_id: int) -> Dict:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:query integer page: page if using pagination (default: 1) :query integer page: page if using pagination (default: 1)
:query integer per_page: number of users per page (default: 10, max: 50) :query integer per_page: number of users per page (default: 10, max: 50)
:query string q: query on user name :query string q: query on user name
@ -219,7 +217,7 @@ def get_users(auth_user_id: int) -> Dict:
@users_blueprint.route('/users/<user_name>', methods=['GET']) @users_blueprint.route('/users/<user_name>', methods=['GET'])
@authenticate @authenticate
def get_single_user( def get_single_user(
auth_user_id: int, user_name: str auth_user: User, user_name: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get single user details Get single user details
@ -306,7 +304,6 @@ def get_single_user(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param integer user_name: user name :param integer user_name: user name
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -371,9 +368,7 @@ def get_picture(user_name: str) -> Any:
@users_blueprint.route('/users/<user_name>', methods=['PATCH']) @users_blueprint.route('/users/<user_name>', methods=['PATCH'])
@authenticate_as_admin @authenticate_as_admin
def update_user( def update_user(auth_user: User, user_name: str) -> Union[Dict, HttpResponse]:
auth_user_id: int, user_name: str
) -> Union[Dict, HttpResponse]:
""" """
Update user to add admin rights Update user to add admin rights
@ -461,7 +456,6 @@ def update_user(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string user_name: user name :param string user_name: user name
:<json boolean admin: does the user have administrator rights :<json boolean admin: does the user have administrator rights
@ -500,7 +494,7 @@ def update_user(
@users_blueprint.route('/users/<user_name>', methods=['DELETE']) @users_blueprint.route('/users/<user_name>', methods=['DELETE'])
@authenticate @authenticate
def delete_user( def delete_user(
auth_user_id: int, user_name: str auth_user: User, user_name: str
) -> Union[Tuple[Dict, int], HttpResponse]: ) -> Union[Tuple[Dict, int], HttpResponse]:
""" """
Delete a user account Delete a user account
@ -524,7 +518,6 @@ def delete_user(
HTTP/1.1 204 NO CONTENT HTTP/1.1 204 NO CONTENT
Content-Type: application/json Content-Type: application/json
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string user_name: user name :param string user_name: user name
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -543,12 +536,11 @@ def delete_user(
""" """
try: try:
auth_user = User.query.filter_by(id=auth_user_id).first()
user = User.query.filter_by(username=user_name).first() user = User.query.filter_by(username=user_name).first()
if not user: if not user:
return UserNotFoundErrorResponse() return UserNotFoundErrorResponse()
if user.id != auth_user_id and not auth_user.admin: if user.id != auth_user.id and not auth_user.admin:
return ForbiddenErrorResponse() return ForbiddenErrorResponse()
if ( if (
user.admin is True user.admin is True

View File

@ -12,14 +12,6 @@ from fittrackee.responses import (
from .models import User from .models import User
def is_admin(user_id: int) -> bool:
"""
Return if user has admin rights
"""
user = User.query.filter_by(id=user_id).first()
return user.admin
def is_valid_email(email: str) -> bool: def is_valid_email(email: str) -> bool:
""" """
Return if email format is valid Return if email format is valid
@ -62,10 +54,10 @@ def register_controls(
def verify_user( def verify_user(
current_request: Request, verify_admin: bool current_request: Request, verify_admin: bool
) -> Tuple[Optional[HttpResponse], Optional[int]]: ) -> Tuple[Optional[HttpResponse], Optional[User]]:
""" """
Return user id, if the provided token is valid and if user has admin Return authenticated user, if the provided token is valid and user has
rights if 'verify_admin' is True admin rights if 'verify_admin' is True
""" """
default_message = 'provide a valid auth token' default_message = 'provide a valid auth token'
auth_header = current_request.headers.get('Authorization') auth_header = current_request.headers.get('Authorization')
@ -78,9 +70,9 @@ def verify_user(
user = User.query.filter_by(id=resp).first() user = User.query.filter_by(id=resp).first()
if not user: if not user:
return UnauthorizedErrorResponse(default_message), None return UnauthorizedErrorResponse(default_message), None
if verify_admin and not is_admin(resp): if verify_admin and not user.admin:
return ForbiddenErrorResponse(), None return ForbiddenErrorResponse(), None
return None, resp return None, user
def can_view_workout( def can_view_workout(

View File

@ -3,6 +3,7 @@ from typing import Dict
from flask import Blueprint from flask import Blueprint
from fittrackee.users.decorators import authenticate from fittrackee.users.decorators import authenticate
from fittrackee.users.models import User
from .models import Record from .models import Record
@ -11,7 +12,7 @@ records_blueprint = Blueprint('records', __name__)
@records_blueprint.route('/records', methods=['GET']) @records_blueprint.route('/records', methods=['GET'])
@authenticate @authenticate
def get_records(auth_user_id: int) -> Dict: def get_records(auth_user: User) -> Dict:
""" """
Get all records for authenticated user. Get all records for authenticated user.
@ -95,8 +96,6 @@ def get_records(auth_user_id: int) -> Dict:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
:statuscode 200: success :statuscode 200: success
@ -107,7 +106,7 @@ def get_records(auth_user_id: int) -> Dict:
""" """
records = ( records = (
Record.query.filter_by(user_id=auth_user_id) Record.query.filter_by(user_id=auth_user.id)
.order_by(Record.sport_id.asc(), Record.record_type.asc()) .order_by(Record.sport_id.asc(), Record.record_type.asc())
.all() .all()
) )

View File

@ -20,7 +20,7 @@ sports_blueprint = Blueprint('sports', __name__)
@sports_blueprint.route('/sports', methods=['GET']) @sports_blueprint.route('/sports', methods=['GET'])
@authenticate @authenticate
def get_sports(auth_user_id: int) -> Dict: def get_sports(auth_user: User) -> Dict:
""" """
Get all sports Get all sports
@ -165,8 +165,6 @@ def get_sports(auth_user_id: int) -> Dict:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
:statuscode 200: success :statuscode 200: success
@ -176,16 +174,15 @@ def get_sports(auth_user_id: int) -> Dict:
- invalid token, please log in again - invalid token, please log in again
""" """
user = User.query.filter_by(id=int(auth_user_id)).first()
sports = Sport.query.order_by(Sport.id).all() sports = Sport.query.order_by(Sport.id).all()
sports_data = [] sports_data = []
for sport in sports: for sport in sports:
sport_preferences = UserSportPreference.query.filter_by( sport_preferences = UserSportPreference.query.filter_by(
user_id=user.id, sport_id=sport.id user_id=auth_user.id, sport_id=sport.id
).first() ).first()
sports_data.append( sports_data.append(
sport.serialize( sport.serialize(
is_admin=user.admin, is_admin=auth_user.admin,
sport_preferences=sport_preferences.serialize() sport_preferences=sport_preferences.serialize()
if sport_preferences if sport_preferences
else None, else None,
@ -199,7 +196,7 @@ def get_sports(auth_user_id: int) -> Dict:
@sports_blueprint.route('/sports/<int:sport_id>', methods=['GET']) @sports_blueprint.route('/sports/<int:sport_id>', methods=['GET'])
@authenticate @authenticate
def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]: def get_sport(auth_user: User, sport_id: int) -> Union[Dict, HttpResponse]:
""" """
Get a sport Get a sport
@ -273,7 +270,6 @@ def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]:
"status": "not found" "status": "not found"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param integer sport_id: sport id :param integer sport_id: sport id
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -286,18 +282,17 @@ def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]:
:statuscode 404: sport not found :statuscode 404: sport not found
""" """
user = User.query.filter_by(id=int(auth_user_id)).first()
sport = Sport.query.filter_by(id=sport_id).first() sport = Sport.query.filter_by(id=sport_id).first()
if sport: if sport:
sport_preferences = UserSportPreference.query.filter_by( sport_preferences = UserSportPreference.query.filter_by(
user_id=user.id, sport_id=sport.id user_id=auth_user.id, sport_id=sport.id
).first() ).first()
return { return {
'status': 'success', 'status': 'success',
'data': { 'data': {
'sports': [ 'sports': [
sport.serialize( sport.serialize(
is_admin=user.admin, is_admin=auth_user.admin,
sport_preferences=sport_preferences.serialize() sport_preferences=sport_preferences.serialize()
if sport_preferences if sport_preferences
else None, else None,
@ -310,9 +305,7 @@ def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]:
@sports_blueprint.route('/sports/<int:sport_id>', methods=['PATCH']) @sports_blueprint.route('/sports/<int:sport_id>', methods=['PATCH'])
@authenticate_as_admin @authenticate_as_admin
def update_sport( def update_sport(auth_user: User, sport_id: int) -> Union[Dict, HttpResponse]:
auth_user_id: int, sport_id: int
) -> Union[Dict, HttpResponse]:
""" """
Update a sport Update a sport
Authenticated user must be an admin Authenticated user must be an admin
@ -364,7 +357,6 @@ def update_sport(
"status": "not found" "status": "not found"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param integer sport_id: sport id :param integer sport_id: sport id
:<json string is_active: sport active status :<json string is_active: sport active status
@ -387,7 +379,6 @@ def update_sport(
return InvalidPayloadErrorResponse() return InvalidPayloadErrorResponse()
try: try:
user = User.query.filter_by(id=int(auth_user_id)).first()
sport = Sport.query.filter_by(id=sport_id).first() sport = Sport.query.filter_by(id=sport_id).first()
if not sport: if not sport:
return DataNotFoundErrorResponse('sports') return DataNotFoundErrorResponse('sports')
@ -395,14 +386,14 @@ def update_sport(
sport.is_active = sport_data.get('is_active') sport.is_active = sport_data.get('is_active')
db.session.commit() db.session.commit()
sport_preferences = UserSportPreference.query.filter_by( sport_preferences = UserSportPreference.query.filter_by(
user_id=user.id, sport_id=sport.id user_id=auth_user.id, sport_id=sport.id
).first() ).first()
return { return {
'status': 'success', 'status': 'success',
'data': { 'data': {
'sports': [ 'sports': [
sport.serialize( sport.serialize(
is_admin=user.admin, is_admin=auth_user.admin,
sport_preferences=sport_preferences.serialize() sport_preferences=sport_preferences.serialize()
if sport_preferences if sport_preferences
else None, else None,

View File

@ -179,7 +179,7 @@ def get_workouts(
@stats_blueprint.route('/stats/<user_name>/by_time', methods=['GET']) @stats_blueprint.route('/stats/<user_name>/by_time', methods=['GET'])
@authenticate @authenticate
def get_workouts_by_time( def get_workouts_by_time(
auth_user_id: int, user_name: str auth_user: User, user_name: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get workouts statistics for a user by time Get workouts statistics for a user by time
@ -258,7 +258,6 @@ def get_workouts_by_time(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param integer user_name: user name :param integer user_name: user name
:query string from: start date (format: ``%Y-%m-%d``) :query string from: start date (format: ``%Y-%m-%d``)
@ -287,7 +286,7 @@ def get_workouts_by_time(
@stats_blueprint.route('/stats/<user_name>/by_sport', methods=['GET']) @stats_blueprint.route('/stats/<user_name>/by_sport', methods=['GET'])
@authenticate @authenticate
def get_workouts_by_sport( def get_workouts_by_sport(
auth_user_id: int, user_name: str auth_user: User, user_name: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get workouts statistics for a user by sport Get workouts statistics for a user by sport
@ -361,7 +360,6 @@ def get_workouts_by_sport(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param integer user_name: user name :param integer user_name: user name
:query integer sport_id: sport id :query integer sport_id: sport id
@ -383,7 +381,7 @@ def get_workouts_by_sport(
@stats_blueprint.route('/stats/all', methods=['GET']) @stats_blueprint.route('/stats/all', methods=['GET'])
@authenticate_as_admin @authenticate_as_admin
def get_application_stats(auth_user_id: int) -> Dict: def get_application_stats(auth_user: User) -> Dict:
""" """
Get all application statistics Get all application statistics
@ -411,8 +409,6 @@ def get_application_stats(auth_user_id: int) -> Dict:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
:statuscode 200: success :statuscode 200: success

View File

@ -186,7 +186,7 @@ def update_workout(workout: Workout) -> Workout:
def edit_workout( def edit_workout(
workout: Workout, workout_data: Dict, auth_user_id: int workout: Workout, workout_data: Dict, auth_user: User
) -> Workout: ) -> Workout:
""" """
Edit an workout Edit an workout
@ -195,7 +195,6 @@ def edit_workout(
In a next version, map_data and weather_data will be updated In a next version, map_data and weather_data will be updated
(case of a modified gpx file, see issue #7) (case of a modified gpx file, see issue #7)
""" """
user = User.query.filter_by(id=auth_user_id).first()
if workout_data.get('refresh'): if workout_data.get('refresh'):
workout = update_workout(workout) workout = update_workout(workout)
if workout_data.get('sport_id'): if workout_data.get('sport_id'):
@ -210,7 +209,7 @@ def edit_workout(
workout_data['workout_date'], '%Y-%m-%d %H:%M' workout_data['workout_date'], '%Y-%m-%d %H:%M'
) )
_, workout.workout_date = get_datetime_with_tz( _, workout.workout_date = get_datetime_with_tz(
user.timezone, workout_date auth_user.timezone, workout_date
) )
if workout_data.get('duration'): if workout_data.get('duration'):
@ -299,9 +298,9 @@ def process_one_gpx_file(
gpx_data, map_data, weather_data = get_gpx_info( gpx_data, map_data, weather_data = get_gpx_info(
params['file_path'], stopped_speed_threshold params['file_path'], stopped_speed_threshold
) )
auth_user_id = params['user'].id auth_user = params['auth_user']
new_filepath = get_new_file_path( new_filepath = get_new_file_path(
auth_user_id=auth_user_id, auth_user_id=auth_user.id,
workout_date=gpx_data['start'], workout_date=gpx_data['start'],
old_filename=filename, old_filename=filename,
sport=params['sport_label'], sport=params['sport_label'],
@ -311,7 +310,7 @@ def process_one_gpx_file(
gpx_data['filename'] = new_filepath gpx_data['filename'] = new_filepath
map_filepath = get_new_file_path( map_filepath = get_new_file_path(
auth_user_id=auth_user_id, auth_user_id=auth_user.id,
workout_date=gpx_data['start'], workout_date=gpx_data['start'],
extension='.png', extension='.png',
sport=params['sport_label'], sport=params['sport_label'],
@ -325,7 +324,7 @@ def process_one_gpx_file(
try: try:
new_workout = create_workout( new_workout = create_workout(
params['user'], params['workout_data'], gpx_data auth_user, params['workout_data'], gpx_data
) )
new_workout.map = map_filepath new_workout.map = map_filepath
new_workout.map_id = get_map_hash(map_filepath) new_workout.map_id = get_map_hash(map_filepath)
@ -380,7 +379,7 @@ def process_zip_archive(
def process_files( def process_files(
auth_user_id: int, auth_user: User,
workout_data: Dict, workout_data: Dict,
workout_file: FileStorage, workout_file: FileStorage,
folders: Dict, folders: Dict,
@ -399,9 +398,8 @@ def process_files(
'error', 'error',
f"Sport id: {workout_data.get('sport_id')} does not exist", f"Sport id: {workout_data.get('sport_id')} does not exist",
) )
user = User.query.filter_by(id=auth_user_id).first()
sport_preferences = UserSportPreference.query.filter_by( sport_preferences = UserSportPreference.query.filter_by(
user_id=user.id, sport_id=sport.id user_id=auth_user.id, sport_id=sport.id
).first() ).first()
stopped_speed_threshold = ( stopped_speed_threshold = (
sport.stopped_speed_threshold sport.stopped_speed_threshold
@ -410,7 +408,7 @@ def process_files(
) )
common_params = { common_params = {
'user': user, 'auth_user': auth_user,
'workout_data': workout_data, 'workout_data': workout_data,
'file_path': file_path, 'file_path': file_path,
'sport_label': sport.label, 'sport_label': sport.label,

View File

@ -56,7 +56,7 @@ MAX_WORKOUTS_PER_PAGE = 100
@workouts_blueprint.route('/workouts', methods=['GET']) @workouts_blueprint.route('/workouts', methods=['GET'])
@authenticate @authenticate
def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]: def get_workouts(auth_user: User) -> Union[Dict, HttpResponse]:
""" """
Get workouts for the authenticated user. Get workouts for the authenticated user.
@ -171,8 +171,6 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:query integer page: page if using pagination (default: 1) :query integer page: page if using pagination (default: 1)
:query integer per_page: number of workouts per page :query integer per_page: number of workouts per page
(default: 5, max: 100) (default: 5, max: 100)
@ -200,10 +198,9 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]:
""" """
try: try:
user = User.query.filter_by(id=auth_user_id).first()
params = request.args.copy() params = request.args.copy()
page = int(params.get('page', 1)) page = int(params.get('page', 1))
date_from, date_to = get_datetime_from_request_args(params, user) date_from, date_to = get_datetime_from_request_args(params, auth_user)
distance_from = params.get('distance_from') distance_from = params.get('distance_from')
distance_to = params.get('distance_to') distance_to = params.get('distance_to')
duration_from = params.get('duration_from') duration_from = params.get('duration_from')
@ -220,7 +217,7 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]:
per_page = MAX_WORKOUTS_PER_PAGE per_page = MAX_WORKOUTS_PER_PAGE
workouts_pagination = ( workouts_pagination = (
Workout.query.filter( Workout.query.filter(
Workout.user_id == auth_user_id, Workout.user_id == auth_user.id,
Workout.sport_id == sport_id if sport_id else True, Workout.sport_id == sport_id if sport_id else True,
Workout.workout_date >= date_from if date_from else True, Workout.workout_date >= date_from if date_from else True,
Workout.workout_date < date_to + timedelta(seconds=1) Workout.workout_date < date_to + timedelta(seconds=1)
@ -302,7 +299,7 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]:
) )
@authenticate @authenticate
def get_workout( def get_workout(
auth_user_id: int, workout_short_id: str auth_user: User, workout_short_id: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get an workout Get an workout
@ -373,7 +370,6 @@ def get_workout(
"status": "not found" "status": "not found"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -392,7 +388,7 @@ def get_workout(
if not workout: if not workout:
return DataNotFoundErrorResponse('workouts') return DataNotFoundErrorResponse('workouts')
error_response = can_view_workout(auth_user_id, workout.user_id) error_response = can_view_workout(auth_user.id, workout.user_id)
if error_response: if error_response:
return error_response return error_response
@ -403,7 +399,7 @@ def get_workout(
def get_workout_data( def get_workout_data(
auth_user_id: int, auth_user: User,
workout_short_id: str, workout_short_id: str,
data_type: str, data_type: str,
segment_id: Optional[int] = None, segment_id: Optional[int] = None,
@ -417,7 +413,7 @@ def get_workout_data(
message=f'workout not found (id: {workout_short_id})', message=f'workout not found (id: {workout_short_id})',
) )
error_response = can_view_workout(auth_user_id, workout.user_id) error_response = can_view_workout(auth_user.id, workout.user_id)
if error_response: if error_response:
return error_response return error_response
if not workout.gpx or workout.gpx == '': if not workout.gpx or workout.gpx == '':
@ -467,7 +463,7 @@ def get_workout_data(
) )
@authenticate @authenticate
def get_workout_gpx( def get_workout_gpx(
auth_user_id: int, workout_short_id: str auth_user: User, workout_short_id: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get gpx file for an workout displayed on map with Leaflet Get gpx file for an workout displayed on map with Leaflet
@ -494,7 +490,6 @@ def get_workout_gpx(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -510,7 +505,7 @@ def get_workout_gpx(
:statuscode 500: :statuscode 500:
""" """
return get_workout_data(auth_user_id, workout_short_id, 'gpx') return get_workout_data(auth_user, workout_short_id, 'gpx')
@workouts_blueprint.route( @workouts_blueprint.route(
@ -518,7 +513,7 @@ def get_workout_gpx(
) )
@authenticate @authenticate
def get_workout_chart_data( def get_workout_chart_data(
auth_user_id: int, workout_short_id: str auth_user: User, workout_short_id: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get chart data from an workout gpx file, to display it with Recharts Get chart data from an workout gpx file, to display it with Recharts
@ -564,7 +559,6 @@ def get_workout_chart_data(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -580,7 +574,7 @@ def get_workout_chart_data(
:statuscode 500: :statuscode 500:
""" """
return get_workout_data(auth_user_id, workout_short_id, 'chart_data') return get_workout_data(auth_user, workout_short_id, 'chart_data')
@workouts_blueprint.route( @workouts_blueprint.route(
@ -589,7 +583,7 @@ def get_workout_chart_data(
) )
@authenticate @authenticate
def get_segment_gpx( def get_segment_gpx(
auth_user_id: int, workout_short_id: str, segment_id: int auth_user: User, workout_short_id: str, segment_id: int
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get gpx file for an workout segment displayed on map with Leaflet Get gpx file for an workout segment displayed on map with Leaflet
@ -616,7 +610,6 @@ def get_segment_gpx(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:param integer segment_id: segment id :param integer segment_id: segment id
@ -632,7 +625,7 @@ def get_segment_gpx(
:statuscode 500: :statuscode 500:
""" """
return get_workout_data(auth_user_id, workout_short_id, 'gpx', segment_id) return get_workout_data(auth_user, workout_short_id, 'gpx', segment_id)
@workouts_blueprint.route( @workouts_blueprint.route(
@ -642,7 +635,7 @@ def get_segment_gpx(
) )
@authenticate @authenticate
def get_segment_chart_data( def get_segment_chart_data(
auth_user_id: int, workout_short_id: str, segment_id: int auth_user: User, workout_short_id: str, segment_id: int
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Get chart data from an workout gpx file, to display it with Recharts Get chart data from an workout gpx file, to display it with Recharts
@ -688,7 +681,6 @@ def get_segment_chart_data(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:param integer segment_id: segment id :param integer segment_id: segment id
@ -705,7 +697,7 @@ def get_segment_chart_data(
""" """
return get_workout_data( return get_workout_data(
auth_user_id, workout_short_id, 'chart_data', segment_id auth_user, workout_short_id, 'chart_data', segment_id
) )
@ -714,7 +706,7 @@ def get_segment_chart_data(
) )
@authenticate @authenticate
def download_workout_gpx( def download_workout_gpx(
auth_user_id: int, workout_short_id: str auth_user: User, workout_short_id: str
) -> Union[HttpResponse, Response]: ) -> Union[HttpResponse, Response]:
""" """
Download gpx file Download gpx file
@ -732,7 +724,6 @@ def download_workout_gpx(
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/gpx+xml Content-Type: application/gpx+xml
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:statuscode 200: success :statuscode 200: success
@ -746,7 +737,7 @@ def download_workout_gpx(
""" """
workout_uuid = decode_short_id(workout_short_id) workout_uuid = decode_short_id(workout_short_id)
workout = Workout.query.filter_by( workout = Workout.query.filter_by(
uuid=workout_uuid, user_id=auth_user_id uuid=workout_uuid, user_id=auth_user.id
).first() ).first()
if not workout: if not workout:
return DataNotFoundErrorResponse( return DataNotFoundErrorResponse(
@ -852,7 +843,7 @@ def get_map_tile(s: str, z: str, x: str, y: str) -> Tuple[Response, int]:
@workouts_blueprint.route('/workouts', methods=['POST']) @workouts_blueprint.route('/workouts', methods=['POST'])
@authenticate @authenticate
def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: def post_workout(auth_user: User) -> Union[Tuple[Dict, int], HttpResponse]:
""" """
Post an workout with a gpx file Post an workout with a gpx file
@ -944,8 +935,6 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]:
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:form file: gpx file (allowed extensions: .gpx, .zip) :form file: gpx file (allowed extensions: .gpx, .zip)
:form data: sport id and notes (example: ``{"sport_id": 1, "notes": ""}``) :form data: sport id and notes (example: ``{"sport_id": 1, "notes": ""}``)
@ -983,7 +972,7 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]:
workout_file = request.files['file'] workout_file = request.files['file']
upload_dir = os.path.join( upload_dir = os.path.join(
current_app.config['UPLOAD_FOLDER'], 'workouts', str(auth_user_id) current_app.config['UPLOAD_FOLDER'], 'workouts', str(auth_user.id)
) )
folders = { folders = {
'extract_dir': os.path.join(upload_dir, 'extract'), 'extract_dir': os.path.join(upload_dir, 'extract'),
@ -992,7 +981,7 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]:
try: try:
new_workouts = process_files( new_workouts = process_files(
auth_user_id, workout_data, workout_file, folders auth_user, workout_data, workout_file, folders
) )
if len(new_workouts) > 0: if len(new_workouts) > 0:
response_object = { response_object = {
@ -1021,7 +1010,7 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]:
@workouts_blueprint.route('/workouts/no_gpx', methods=['POST']) @workouts_blueprint.route('/workouts/no_gpx', methods=['POST'])
@authenticate @authenticate
def post_workout_no_gpx( def post_workout_no_gpx(
auth_user_id: int, auth_user: User,
) -> Union[Tuple[Dict, int], HttpResponse]: ) -> Union[Tuple[Dict, int], HttpResponse]:
""" """
Post an workout without gpx file Post an workout without gpx file
@ -1114,8 +1103,6 @@ def post_workout_no_gpx(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:<json string workout_date: workout date (format: ``%Y-%m-%d %H:%M``) :<json string workout_date: workout date (format: ``%Y-%m-%d %H:%M``)
:<json float distance: workout distance in km :<json float distance: workout distance in km
:<json integer duration: workout duration in seconds :<json integer duration: workout duration in seconds
@ -1145,8 +1132,7 @@ def post_workout_no_gpx(
return InvalidPayloadErrorResponse() return InvalidPayloadErrorResponse()
try: try:
user = User.query.filter_by(id=auth_user_id).first() new_workout = create_workout(auth_user, workout_data)
new_workout = create_workout(user, workout_data)
db.session.add(new_workout) db.session.add(new_workout)
db.session.commit() db.session.commit()
@ -1172,7 +1158,7 @@ def post_workout_no_gpx(
) )
@authenticate @authenticate
def update_workout( def update_workout(
auth_user_id: int, workout_short_id: str auth_user: User, workout_short_id: str
) -> Union[Dict, HttpResponse]: ) -> Union[Dict, HttpResponse]:
""" """
Update an workout Update an workout
@ -1265,7 +1251,6 @@ def update_workout(
"status": "success" "status": "success"
} }
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:<json string workout_date: workout date (format: ``%Y-%m-%d %H:%M``) :<json string workout_date: workout date (format: ``%Y-%m-%d %H:%M``)
@ -1300,11 +1285,11 @@ def update_workout(
if not workout: if not workout:
return DataNotFoundErrorResponse('workouts') return DataNotFoundErrorResponse('workouts')
response_object = can_view_workout(auth_user_id, workout.user_id) response_object = can_view_workout(auth_user.id, workout.user_id)
if response_object: if response_object:
return response_object return response_object
workout = edit_workout(workout, workout_data, auth_user_id) workout = edit_workout(workout, workout_data, auth_user)
db.session.commit() db.session.commit()
return { return {
'status': 'success', 'status': 'success',
@ -1320,7 +1305,7 @@ def update_workout(
) )
@authenticate @authenticate
def delete_workout( def delete_workout(
auth_user_id: int, workout_short_id: str auth_user: User, workout_short_id: str
) -> Union[Tuple[Dict, int], HttpResponse]: ) -> Union[Tuple[Dict, int], HttpResponse]:
""" """
Delete an workout Delete an workout
@ -1339,7 +1324,6 @@ def delete_workout(
HTTP/1.1 204 NO CONTENT HTTP/1.1 204 NO CONTENT
Content-Type: application/json Content-Type: application/json
:param integer auth_user_id: authenticate user id (from JSON Web Token)
:param string workout_short_id: workout short id :param string workout_short_id: workout short id
:reqheader Authorization: OAuth 2.0 Bearer Token :reqheader Authorization: OAuth 2.0 Bearer Token
@ -1359,7 +1343,7 @@ def delete_workout(
workout = Workout.query.filter_by(uuid=workout_uuid).first() workout = Workout.query.filter_by(uuid=workout_uuid).first()
if not workout: if not workout:
return DataNotFoundErrorResponse('workouts') return DataNotFoundErrorResponse('workouts')
error_response = can_view_workout(auth_user_id, workout.user_id) error_response = can_view_workout(auth_user.id, workout.user_id)
if error_response: if error_response:
return error_response return error_response