16349: Fix TZ-sensitive comparison in token expiry checks.
authorTom Clegg <tom@tomclegg.ca>
Mon, 27 Apr 2020 20:37:49 +0000 (16:37 -0400)
committerPeter Amstutz <peter.amstutz@curii.com>
Mon, 8 Jun 2020 18:58:18 +0000 (14:58 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@tomclegg.ca>

lib/controller/federation.go
services/api/app/controllers/application_controller.rb
services/api/app/models/api_client_authorization.rb
services/api/lib/create_superuser_token.rb

index c0d127284ce35a21d5618814dd2792984809f5f2..ac239fb9b23f5c4c106034e2a910fb441b9c2218 100644 (file)
@@ -166,7 +166,7 @@ func (h *Handler) validateAPItoken(req *http.Request, token string) (*CurrentUse
        }
        user.Authorization.APIToken = token
        var scopes string
-       err = db.QueryRowContext(req.Context(), `SELECT api_client_authorizations.uuid, api_client_authorizations.scopes, users.uuid FROM api_client_authorizations JOIN users on api_client_authorizations.user_id=users.id WHERE api_token=$1 AND (expires_at IS NULL OR expires_at > current_timestamp) LIMIT 1`, token).Scan(&user.Authorization.UUID, &scopes, &user.UUID)
+       err = db.QueryRowContext(req.Context(), `SELECT api_client_authorizations.uuid, api_client_authorizations.scopes, users.uuid FROM api_client_authorizations JOIN users on api_client_authorizations.user_id=users.id WHERE api_token=$1 AND (expires_at IS NULL OR expires_at > current_timestamp AT TIME ZONE 'UTC') LIMIT 1`, token).Scan(&user.Authorization.UUID, &scopes, &user.UUID)
        if err == sql.ErrNoRows {
                ctxlog.FromContext(req.Context()).Debugf("validateAPItoken(%s): not found in database", token)
                return nil, false, nil
@@ -214,9 +214,9 @@ func (h *Handler) createAPItoken(req *http.Request, userUUID string, scopes []st
 (uuid, api_token, expires_at, scopes,
 user_id,
 api_client_id, created_at, updated_at)
-VALUES ($1, $2, CURRENT_TIMESTAMP + INTERVAL '2 weeks', $3,
+VALUES ($1, $2, CURRENT_TIMESTAMP AT TIME ZONE 'UTC' + INTERVAL '2 weeks', $3,
 (SELECT id FROM users WHERE users.uuid=$4 LIMIT 1),
-0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
+0, CURRENT_TIMESTAMP AT TIME ZONE 'UTC', CURRENT_TIMESTAMP AT TIME ZONE 'UTC')`,
                uuid, token, string(scopesjson), userUUID)
 
        if err != nil {
index 83a233cd54681b18b9fb6bb12c72642a2e95cae4..c7d7ad8148246f883d87b37840da5ed3610946d1 100644 (file)
@@ -386,8 +386,8 @@ class ApplicationController < ActionController::Base
       @read_auths += ApiClientAuthorization
         .includes(:user)
         .where('api_token IN (?) AND
-                (expires_at IS NULL OR expires_at > CURRENT_TIMESTAMP)',
-               secrets)
+                (expires_at IS NULL OR expires_at > CURRENT_TIMESTAMP AT TIME ZONE ?)',
+               secrets, 'UTC')
         .to_a
     end
     @read_auths.select! { |auth| auth.scopes_allow_request? request }
index 503dfc50dd78e3b30cb2ce9660d5d91fdb49223b..a4bf0cd5b261f55127be003ff55e47fadbb5ec05 100644 (file)
@@ -158,7 +158,7 @@ class ApiClientAuthorization < ArvadosModel
       # fast path: look up the token in the local database
       auth = ApiClientAuthorization.
              includes(:user, :api_client).
-             where('uuid=? and (expires_at is null or expires_at > CURRENT_TIMESTAMP)', token_uuid).
+             where('uuid=? and (expires_at is null or expires_at > CURRENT_TIMESTAMP AT TIME ZONE ?)', token_uuid, 'UTC').
              first
       if auth && auth.user &&
          (secret == auth.api_token ||
@@ -284,7 +284,7 @@ class ApiClientAuthorization < ArvadosModel
       # token is not a 'v2' token
       auth = ApiClientAuthorization.
                includes(:user, :api_client).
-               where('api_token=? and (expires_at is null or expires_at > CURRENT_TIMESTAMP)', token).
+               where('api_token=? and (expires_at is null or expires_at > CURRENT_TIMESTAMP AT TIME ZONE ?)', token, 'UTC').
                first
       if auth && auth.user
         return auth
index 57eac048a9595b6d2bb5e139d7a191caa3e70017..c1530162e958d2c8e59b2e8283ef073f33ca54e8 100755 (executable)
@@ -40,7 +40,7 @@ module CreateSuperUserToken
           where(user_id: system_user.id).
           where(api_client_id: apiClient.id).
           where_serialized(:scopes, ['all']).
-          where('(expires_at IS NULL OR expires_at > CURRENT_TIMESTAMP)').
+          where('(expires_at IS NULL OR expires_at > CURRENT_TIMESTAMP AT TIME ZONE ?)', 'UTC').
           first
 
         # none exist; create one with the supplied token