From 0433a5302cd028158b99f1f115a72daca9d601e4 Mon Sep 17 00:00:00 2001 From: Andrei Mihu Date: Sat, 7 Oct 2023 16:57:38 +0100 Subject: [PATCH] Optionally accept HTTP key through header in RPC requests. --- CHANGELOG.md | 5 +++-- server/api_rpc.go | 33 +++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 648e81cd55..f0890d4c55 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,14 @@ All notable changes to this project are documented below. The format is based on [keep a changelog](http://keepachangelog.com) and this project uses [semantic versioning](http://semver.org). ## [Unreleased] +### Added +- Allow HTTP key to be read from an HTTP request's Basic auth header if present. + ### Changed - Use Steam partner API instead of public API for Steam profiles and friends requests. ### Fixed - Fixed multiple issues found by linter. - -### Fixed - Fixes calculation of leaderboard and tournament times for rare types of CRON expressions that don't execute at a fixed interval. - Improved how start and end times are calculated for tournaments occuring in the future. diff --git a/server/api_rpc.go b/server/api_rpc.go index cdce638d5c..6291533f5a 100644 --- a/server/api_rpc.go +++ b/server/api_rpc.go @@ -63,17 +63,30 @@ func (s *ApiServer) RpcFuncHttp(w http.ResponseWriter, r *http.Request) { return } } else if auth := r.Header["Authorization"]; len(auth) >= 1 { - var token string - userID, username, vars, expiry, token, isTokenAuth = parseBearerAuth([]byte(s.config.GetSession().EncryptionKey), auth[0]) - if !isTokenAuth || !s.sessionCache.IsValidSession(userID, expiry, token) { - // Auth token not valid or expired. - w.Header().Set("content-type", "application/json") - w.WriteHeader(http.StatusUnauthorized) - _, err := w.Write(authTokenInvalidBytes) - if err != nil { - s.logger.Debug("Error writing response to client", zap.Error(err)) + if httpKey, _, ok := parseBasicAuth(auth[0]); ok { + if httpKey != s.config.GetRuntime().HTTPKey { + // HTTP key did not match. + w.Header().Set("content-type", "application/json") + w.WriteHeader(http.StatusUnauthorized) + _, err := w.Write(httpKeyInvalidBytes) + if err != nil { + s.logger.Debug("Error writing response to client", zap.Error(err)) + } + return + } + } else { + var token string + userID, username, vars, expiry, token, isTokenAuth = parseBearerAuth([]byte(s.config.GetSession().EncryptionKey), auth[0]) + if !isTokenAuth || !s.sessionCache.IsValidSession(userID, expiry, token) { + // Auth token not valid or expired. + w.Header().Set("content-type", "application/json") + w.WriteHeader(http.StatusUnauthorized) + _, err := w.Write(authTokenInvalidBytes) + if err != nil { + s.logger.Debug("Error writing response to client", zap.Error(err)) + } + return } - return } } else { // No authentication present.