1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Http\Middleware;
7
8use App\Singletons\OsuAuthorize;
9use Carbon\Carbon;
10use Closure;
11
12class LegacyInterOpAuth
13{
14 /**
15 * Handle an incoming request.
16 *
17 * @param \Illuminate\Http\Request $request
18 * @param \Closure $next
19 * @return mixed
20 */
21 public function handle($request, Closure $next)
22 {
23 $timestamp = $request->query('timestamp');
24 $diff = Carbon::createFromTimestamp($timestamp)->diffInSeconds();
25 $signature = $request->header('X-LIO-Signature');
26 // don't use $request->fullUrl() because it returns normalised url.
27 $fullUrl = $request->getSchemeAndHttpHost().$request->getRequestUri();
28 $expected = hash_hmac('sha1', $fullUrl, $GLOBALS['cfg']['osu']['legacy']['shared_interop_secret']);
29
30 if (!present($signature) || !present($timestamp) || $diff > 300 || !hash_equals($expected, $signature)) {
31 $reason = match (true) {
32 !present($signature) => 'missing_signature',
33 !present($timestamp) => 'missing_timestamp',
34 $diff > 300 => 'expired_signature',
35 !hash_equals($expected, $signature) => 'invalid_signature',
36 };
37
38 abort(403, "{$reason} ({$fullUrl})");
39 }
40
41 request()->attributes->set(OsuAuthorize::REQUEST_IS_INTEROP_KEY, true);
42
43 return $next($request);
44 }
45}