shell bypass 403
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\Subscription\StoreSubscription;
use App\Library\Tool;
use App\Models\Plan;
use App\Models\Subscription;
use App\Models\User;
use App\Repositories\Contracts\SubscriptionRepository;
use Auth;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use JetBrains\PhpStorm\NoReturn;
class SubscriptionController extends AdminBaseController
{
protected SubscriptionRepository $subscriptions;
/**
* SubscriptionController constructor.
*
* @param SubscriptionRepository $subscriptions
*/
public function __construct(SubscriptionRepository $subscriptions)
{
$this->subscriptions = $subscriptions;
}
/**
* @return Application|Factory|View
* @throws AuthorizationException
*/
public function index(): Factory|View|Application
{
$this->authorize('view subscription');
$breadcrumbs = [
['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Customer')],
['name' => __('locale.menu.Subscriptions')],
];
return view('admin.subscriptions.index', compact('breadcrumbs'));
}
/**
* @param Request $request
*
* @return void
* @throws AuthorizationException
*/
#[NoReturn] public function search(Request $request): void
{
$this->authorize('view subscription');
$columns = [
0 => 'responsive_id',
1 => 'uid',
2 => 'uid',
3 => 'name',
4 => 'subscribed_by',
5 => 'start_at',
6 => 'end_at',
7 => 'status',
8 => 'action',
];
$totalData = Subscription::count();
$totalFiltered = $totalData;
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
if (empty($request->input('search.value'))) {
$subscriptions = Subscription::offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} else {
$search = $request->input('search.value');
$subscriptions = Subscription::whereLike(['uid', 'user.first_name', 'user.last_name', 'plan.name'], $search)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
$totalFiltered = Subscription::whereLike(['uid', 'user.first_name', 'user.last_name', 'plan.name'], $search)->count();
}
$data = [];
if ( ! empty($subscriptions)) {
foreach ($subscriptions as $subscription) {
if ($subscription->status == 'active') {
$color = 'success';
$status_label = __('locale.labels.active');
} elseif ($subscription->status == 'new') {
$color = 'primary';
$status_label = __('locale.labels.pending');
} else {
$color = 'danger';
$status_label = __('locale.labels.'.$subscription->status);
}
if ($subscription->status == 'pending') {
$color = 'warning';
}
if ($subscription->status == 'renew') {
$color = 'primary';
}
$customer_name = $subscription->user->displayName();
$customer_profile = route('admin.customers.show', $subscription->user->uid);
if ($subscription->start_at) {
$subscribed_on = Tool::dateTime($subscription->start_at)->format('M d, Y');
} else {
$subscribed_on = Tool::dateTime($subscription->created_at)->format('M d, Y');
}
if ($subscription->isEnded()) {
$end_at = Tool::dateTime($subscription->end_at)->diffForHumans();
} elseif ($subscription->cancelled()) {
if ($subscription->current_period_ends_at) {
$end_at = Tool::dateTime($subscription->current_period_ends_at)->diffForHumans();
} else {
$end_at = '--';
}
} elseif ($subscription->isRecurring()) {
if ($subscription->current_period_ends_at) {
$end_at = Tool::dateTime($subscription->current_period_ends_at)->diffForHumans();
} else {
$end_at = '--';
}
} else {
$end_at = Tool::dateTime($subscription->end_at)->diffForHumans();
}
$is_active = false;
$is_ended = false;
$is_new = false;
if ($subscription->isActive()) {
$is_active = true;
}
if ($subscription->isNew()) {
$is_new = true;
}
if ($subscription->isEnded()) {
$is_ended = true;
}
$nestedData['responsive_id'] = '';
$nestedData['avatar'] = route('admin.customers.avatar', $subscription->user->uid);
$nestedData['email'] = $subscription->user->email;
$nestedData['uid'] = $subscription->uid;
$nestedData['name'] = $subscription->plan->name;
$nestedData['subscribed_by'] = "<a href='$customer_profile' class='text-primary mr-1'>$customer_name</a>";
$nestedData['start_at'] = $subscribed_on;
$nestedData['end_at'] = $end_at;
$nestedData['logs'] = route('admin.subscriptions.logs', $subscription->uid);
$nestedData['logs_label'] = __('locale.subscription.logs');
$nestedData['is_active'] = $is_active;
$nestedData['is_ended'] = $is_ended;
$nestedData['is_new'] = $is_new;
$nestedData['approve_label'] = __('locale.labels.approve');
$nestedData['cancel_label'] = __('locale.buttons.cancel');
$nestedData['delete_label'] = __('locale.buttons.delete');
$nestedData['status'] = "<span class='badge bg-$color'>$status_label</span>";
$data[] = $nestedData;
}
}
$json_data = [
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data,
];
echo json_encode($json_data);
exit();
}
/**
* @return Application|Factory|View
* @throws AuthorizationException
*/
public function create(): Factory|View|Application
{
$this->authorize('new subscription');
$breadcrumbs = [
['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url(config('app.admin_path')."/subscriptions"), 'name' => __('locale.menu.Subscriptions')],
['name' => __('locale.buttons.new_subscription')],
];
$customers = User::where('status', true)->where('is_customer', true)->cursor();
$plans = Plan::where('status', true)->orderBy('price')->cursor();
return view('admin.subscriptions.create', compact('breadcrumbs', 'customers', 'plans'));
}
/**
* assign new subscription to customer
*
* @param StoreSubscription $request
*
* @return RedirectResponse
*/
public function store(StoreSubscription $request): RedirectResponse
{
if (config('app.stage') == 'demo') {
return redirect()->route('admin.subscriptions.index')->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$response = $this->subscriptions->store($request->input());
if (isset($response->getData()->status) && $response->getData()->status == 'error') {
return redirect()->route('admin.subscriptions.create')->with([
'status' => 'error',
'message' => $response->getData()->message,
]);
}
return redirect()->route('admin.subscriptions.index')->with([
'status' => 'success',
'message' => __('locale.subscription.subscription_successfully_added'),
]);
}
/**
* view specific subscription logs
*
* @param Subscription $subscription
*
* @return Application|Factory|\Illuminate\Contracts\View\View
* @throws AuthorizationException
*/
public function logs(Subscription $subscription): \Illuminate\Contracts\View\View|Factory|Application
{
$this->authorize('manage subscription');
$breadcrumbs = [
['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url(config('app.admin_path')."/subscriptions"), 'name' => __('locale.menu.Subscriptions')],
['name' => __('locale.subscription.logs')],
];
return view('admin.subscriptions.logs', compact('breadcrumbs', 'subscription'));
}
/**
* approve pending subscription
*
* @param Subscription $subscription
*
* @return JsonResponse
* @throws AuthorizationException
*/
public function approvePending(Subscription $subscription): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('manage subscription');
$this->subscriptions->approvePending($subscription);
return response()->json([
'status' => 'success',
'message' => __('locale.subscription.subscription_successfully_active'),
]);
}
/**
* reject pending subscription
*
* @param Subscription $subscription
*
* @param Request $request
*
* @return JsonResponse
* @throws AuthorizationException
*/
public function rejectPending(Subscription $subscription, Request $request): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('manage subscription');
if ( ! $request->reason) {
return response()->json([
'status' => 'error',
'message' => __('locale.subscription.reject_reason_required'),
]);
}
$this->subscriptions->rejectPending($subscription, $request->only('reason'));
return response()->json([
'status' => 'success',
'message' => __('locale.subscription.subscription_successfully_active'),
]);
}
/**
* cancel subscription
*
* @param Subscription $subscription
*
* @return JsonResponse
* @throws AuthorizationException
*/
public function cancel(Subscription $subscription): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('manage subscription');
$subscription->setEnded(Auth::user()->id);
return response()->json([
'status' => 'success',
'message' => __('locale.subscription.subscription_successfully_cancelled'),
]);
}
/**
* @param Subscription $subscription
*
* @return JsonResponse
*
* @throws AuthorizationException
*/
public function destroy(Subscription $subscription): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('delete subscription');
$this->subscriptions->destroy($subscription);
return response()->json([
'status' => 'success',
'message' => __('locale.subscription.subscription_successfully_deleted'),
]);
}
/**
* Bulk Action with Enable, Disable and Delete
*
* @param Request $request
*
* @return JsonResponse
* @throws AuthorizationException
*/
public function batchAction(Request $request): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$action = $request->get('action');
$ids = $request->get('ids');
if ($action == 'cancel') {
$this->authorize('manage subscription');
$this->subscriptions->batchCancel($ids);
return response()->json([
'status' => 'success',
'message' => __('locale.subscription.subscriptions_cancelled'),
]);
}
return response()->json([
'status' => 'error',
'message' => __('locale.exceptions.invalid_action'),
]);
}
}