Skip to content

Commit

Permalink
Merge branch 'master' into docs/user-extended-profile-hue
Browse files Browse the repository at this point in the history
  • Loading branch information
nanaya authored Sep 30, 2024
2 parents 9c015fc + 83816db commit e8458a4
Show file tree
Hide file tree
Showing 184 changed files with 926 additions and 340 deletions.
41 changes: 41 additions & 0 deletions app/Console/Commands/StoreGetPaypalOrder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Console\Commands;

use App\Libraries\Payments\PaypalApiContext;
use App\Models\Store\Order;
use Illuminate\Console\Command;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;

class StoreGetPaypalOrder extends Command
{
protected $signature = 'store:get-paypal-order {orderId}';

protected $description = 'Gets order info from paypal.';

public function handle()
{
$order = Order::findOrFail(get_int($this->argument('orderId')));
if ($order->provider !== 'paypal') {
$this->error('Not a Paypal order');
return static::INVALID;
}

$paypalOrderId = $order->reference;
if ($paypalOrderId === null) {
$this->error('Missing Paypal order id');
return static::INVALID;
}

$this->comment("Getting details for Order {$order->getKey()}, Paypal Id: {$paypalOrderId}");
$client = PaypalApiContext::client();
$response = $client->execute(new OrdersGetRequest($paypalOrderId));

$this->line(json_encode((array) $response->result, JSON_PRETTY_PRINT));
}
}
75 changes: 75 additions & 0 deletions app/Console/Commands/StoreGetShopifyCheckout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\Store\Order;
use Illuminate\Console\Command;
use Shopify\ApiVersion;
use Shopify\Auth\FileSessionStorage;
use Shopify\Clients\Storefront;
use Shopify\Context;

class StoreGetShopifyCheckout extends Command
{
protected $signature = 'store:get-shopify-checkout {orderId}';

protected $description = 'Gets checkout info from shopify.';

public function handle()
{
$order = Order::findOrFail(get_int($this->argument('orderId')));
if ($order->provider !== 'shopify') {
$this->error('Not a Shopify order');
return static::INVALID;
}

$this->comment("Getting details for Order {$order->getKey()}");
$this->comment($order->reference);

Context::initialize(
// public unauthenticated Storefront API doesn't need OAuth and we can't use blanks.
'unauthenticated_only',
'unauthenticated_only',
'unauthenticated_read_checkouts',
$GLOBALS['cfg']['store']['shopify']['domain'],
new FileSessionStorage(),
ApiVersion::APRIL_2023,
);

$client = new Storefront(
$GLOBALS['cfg']['store']['shopify']['domain'],
$GLOBALS['cfg']['store']['shopify']['storefront_token'],
);

$id = '"'.$order->reference.'"';
$query = <<<QUERY
{
node(id: $id) {
... on Checkout {
id
ready
webUrl
orderStatusUrl
completedAt
createdAt
updatedAt
order {
id
processedAt
orderNumber
}
}
}
}
QUERY;

$response = $client->query($query);
$body = $response->getDecodedBody() ?? '';
$this->line(is_array($body) ? json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) : $body);
}
}
2 changes: 2 additions & 0 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Kernel extends ConsoleKernel

Commands\StoreCleanupStaleOrders::class,
Commands\StoreExpireProducts::class,
Commands\StoreGetPaypalOrder::class,
Commands\StoreGetShopifyCheckout::class,

// builds
Commands\BuildsCreate::class,
Expand Down
12 changes: 12 additions & 0 deletions app/Exceptions/Store/PaymentRejectedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Exceptions\Store;

class PaymentRejectedException extends OrderException
{
}
2 changes: 1 addition & 1 deletion app/Http/Controllers/Chat/ChannelsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public function show($channelId)
'channel' => json_item($channel, ChannelTransformer::forUser($user), ChannelTransformer::LISTING_INCLUDES),
// TODO: probably going to need a better way to list/fetch/update users on larger channels without sending user on every message.
'users' => json_collection(
$channel->visibleUsers($user)->loadMissing(UserCompactTransformer::CARD_INCLUDES_PRELOAD),
$channel->visibleUsers()->loadMissing(UserCompactTransformer::CARD_INCLUDES_PRELOAD),
new UserCompactTransformer(),
UserCompactTransformer::CARD_INCLUDES
),
Expand Down
3 changes: 3 additions & 0 deletions app/Http/Controllers/Payments/PaypalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use App\Exceptions\InvalidSignatureException;
use App\Exceptions\Store\OrderException;
use App\Exceptions\Store\PaymentRejectedException;
use App\Libraries\OrderCheckout;
use App\Libraries\Payments\NotificationType;
use App\Libraries\Payments\PaypalCreatePayment;
Expand Down Expand Up @@ -61,6 +62,8 @@ public function approved()
(new PaypalExecutePayment($order))->run();
} catch (HttpException $e) {
return $this->setAndRedirectCheckoutError($order, $this->userErrorMessage($e));
} catch (PaymentRejectedException) {
return $this->setAndRedirectCheckoutError($order, osu_trans('paypal/errors.unknown'));
}

return redirect(route('store.invoice.show', ['invoice' => $order->order_id, 'thanks' => 1]));
Expand Down
9 changes: 4 additions & 5 deletions app/Http/Controllers/Users/LookupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ class LookupController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('throttle:30,1');
$this->middleware('throttle:1200,1');
$this->middleware('require-scopes:public');
}

public function lookup()
public function index()
{
// TODO: referer check?
$params = get_params(request()->all(), null, ['ids:string[]'], ['null_missing' => true]);
$ids = array_slice($params['ids'], 0, 50);
$ids = array_slice(array_reject_null(get_arr(request('ids'), presence(...)) ?? []), 0, 50);

$numericIds = [];
$stringIds = [];
Expand Down
13 changes: 0 additions & 13 deletions app/Http/Controllers/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
namespace App\Http\Controllers;

use App\Exceptions\ModelNotSavedException;
use App\Exceptions\UserProfilePageLookupException;
use App\Exceptions\ValidationException;
use App\Http\Middleware\RequestCost;
use App\Libraries\ClientCheck;
Expand All @@ -24,7 +23,6 @@
use App\Models\Solo\Score as SoloScore;
use App\Models\User;
use App\Models\UserAccountHistory;
use App\Models\UserNotFound;
use App\Transformers\CurrentUserTransformer;
use App\Transformers\ScoreTransformer;
use App\Transformers\UserCompactTransformer;
Expand Down Expand Up @@ -114,17 +112,6 @@ private static function storeClientDisabledError()
], 403);
}

public function card($id)
{
try {
$user = FindForProfilePage::find($id, null, false);
} catch (UserProfilePageLookupException $e) {
$user = UserNotFound::instance();
}

return json_item($user, 'UserCompact', UserCompactTransformer::CARD_INCLUDES);
}

public function create()
{
if (!$GLOBALS['cfg']['osu']['user']['registration_mode']['web']) {
Expand Down
2 changes: 1 addition & 1 deletion app/Libraries/Chat.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static function createAnnouncement(User $sender, array $rawParams)
throw new InvariantException('missing channel parameter');
}

$users = User::whereIn('user_id', $params['target_ids'])->get();
$users = User::find($params['target_ids']);
if ($users->isEmpty()) {
throw new InvariantException('Nobody to broadcast to!');
}
Expand Down
4 changes: 3 additions & 1 deletion app/Libraries/Markdown/Osu/DocumentProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ private function loadToc()
}

$title = presence($this->getText($this->node));
$slug = $this->node->data['attributes']['id'] ?? presence(mb_strtolower(str_replace(' ', '-', $title))) ?? 'page';
$slug = $this->node->data['attributes']['id']
?? presence(mb_strtolower(strtr($title ?? '', ' ', '-')))
?? 'page';

if (array_key_exists($slug, $this->tocSlugs)) {
$this->tocSlugs[$slug] += 1;
Expand Down
33 changes: 30 additions & 3 deletions app/Libraries/Payments/PaypalExecutePayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

namespace App\Libraries\Payments;

use App\Exceptions\Store\PaymentRejectedException;
use App\Models\Store\Order;
use App\Models\Store\PaypalBanned;
use Log;
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;
use Throwable;

/**
Expand All @@ -19,8 +23,11 @@
*/
class PaypalExecutePayment
{
private PayPalHttpClient $client;

public function __construct(private Order $order)
{
$this->client = PaypalApiContext::client();
}

public function run()
Expand All @@ -34,13 +41,16 @@ public function run()
);
}

$paypalOrderId = $order->reference;

$this->assertPaypalOrder($paypalOrderId);

$order->status = Order::STATUS_PAYMENT_APPROVED;
$order->saveOrExplode();

$client = PaypalApiContext::client();
$request = new OrdersCaptureRequest($order->reference);
$request = new OrdersCaptureRequest($paypalOrderId);

$response = $client->execute($request);
$response = $this->client->execute($request);

// This block is just extra information for now, errors here should not cause the transaction to fail.
try {
Expand All @@ -53,4 +63,21 @@ public function run()
}
});
}

private function assertPaypalOrder(string $paypalOrderId): void
{
$request = new OrdersGetRequest($paypalOrderId);
$response = $this->client->execute($request);

$paypalSource = $response->result->payment_source->paypal;

if (
PaypalBanned::where('account_id', $paypalSource->account_id)
->orWhere('email', $paypalSource->email_address)
->exists()
) {
datadog_increment('store.payments.banned', ['provider' => $this->order->getPaymentProvider()]);
throw new PaymentRejectedException($this->order);
}
}
}
4 changes: 2 additions & 2 deletions app/Libraries/User/PasswordResetData.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ private function __construct(
$this->cacheKey = static::cacheKey($this->user, $username);
}

public static function create(?User $user, string $username): ?string
public static function create(?User $user, ?string $username): ?string
{
if ($user === null) {
if ($user === null || $username === null) {
return osu_trans('password_reset.error.user_not_found');
}

Expand Down
8 changes: 2 additions & 6 deletions app/Models/Chat/Channel.php
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,9 @@ public function users(): Collection
});
}

public function visibleUsers(?User $user)
public function visibleUsers(): Collection
{
if ($this->isPM() || $this->isAnnouncement() && priv_check_user($user, 'ChatAnnounce', $this)->can()) {
return $this->users();
}

return new Collection();
return $this->isPM() ? $this->users() : new Collection();
}

public function scopePublic($query)
Expand Down
18 changes: 18 additions & 0 deletions app/Models/Store/PaypalBanned.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Models\Store;

/**
* @property int $id
* @property string|null $account_id
* @property string|null $email
*/
class PaypalBanned extends Model
{
public $timestamps = false;
}
41 changes: 0 additions & 41 deletions app/Models/UserNotFound.php

This file was deleted.

Loading

0 comments on commit e8458a4

Please sign in to comment.