shell bypass 403
<?php namespace Rappasoft\LaravelLivewireTables\Utilities; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Query\Builder; use Illuminate\Support\Str; /** * Class ColumnUtilities * * @package Rappasoft\LaravelLivewireTables\Utilities */ class ColumnUtilities { /** * Grab the relation part of a column * * @param $column * @return bool */ public static function hasRelation($column): bool { return Str::contains($column, '.'); } /** * Grab the relation part of a column * * @param $column * @return string */ public static function parseRelation($column): string { return Str::beforeLast($column, '.'); } /** * Grab the field part of a column * * @param $column * @return string */ public static function parseField($column): string { return Str::afterLast($column, '.'); } /** * Is the column selected? * * @param $column * @param $searchColumns * @return bool */ public static function hasMatch($column, $searchColumns): bool { return in_array($column, $searchColumns ?? [], true); } /** * Is the column selected by a wildcard match? * * @param $column * @param $searchColumns * @return bool */ public static function hasWildcardMatch($column, $searchColumns): bool { return count(array_filter($searchColumns ?? [], function ($searchColumn) use ($column) { // Match wildcards such as * or table.* $hasWildcard = Str::endsWith($searchColumn, '*'); // If no wildcard, skip if (! $hasWildcard) { return false; } if (! self::hasRelation($column)) { return true; } $selectColumnPrefix = self::parseRelation($searchColumn); $columnPrefix = self::parseRelation($column); return $selectColumnPrefix === $columnPrefix; })) > 0; } /** * @param null $queryBuilder * * @return array|null */ public static function columnsFromBuilder($queryBuilder = null): ?array { if ($queryBuilder instanceof EloquentBuilder) { return $queryBuilder->getQuery()->columns; } if ($queryBuilder instanceof Builder) { return $queryBuilder->columns; } return null; } /** * Try to map a given column to an already selected column * * @param $column * @param $queryBuilder * @return string */ public static function mapToSelected($column, $queryBuilder): ?string { // Grab select $select = self::columnsFromBuilder($queryBuilder); // Can't match anything if no select if (is_null($select)) { return null; } // Search builder select for a match $hasMatch = self::hasMatch($column, $select); // example 2 - match // column: service_statuses.name // select: service_statuses.name // maps to: service_statuses.name // If we found a match, lets use that instead of searching relations if ($hasMatch) { return $column; } // Search builder select for a wildcard match $hasWildcardMatch = self::hasWildcardMatch($column, $select); // example 3 - wildcard match // column: service_statuses.name // select: service_statuses.* // maps to: service_statuses.name // If we found a wildcard match, lets use that instead of matching relations if ($hasWildcardMatch) { return $column; } // Split the relation and field $hasRelation = self::hasRelation($column); $relationName = self::parseRelation($column); $fieldName = self::parseField($column); // We know there is a relation and we know it doesn't match any of the // select columns. Let's try to grab the table name for the relation // and see if that matches something in the select // // example 4 - relation to already selected table // column: serviceStatus.name // select: service_statuses.name // maps to: service_statuses.name // If we didn't previously match the column and there isn't a relation if (! $hasRelation) { // There's nothing else to do return null; } // This is easiest when using the eloquent query builder if ($queryBuilder instanceof EloquentBuilder) { $relation = $queryBuilder->getRelation($relationName); $possibleTable = $relation->getModel()->getTable(); } elseif ($queryBuilder instanceof Builder) { // TODO: Possible ways to do this? $possibleTable = null; } else { // We would have already returned before this is possible $possibleTable = null; } // If we found a possible table if (! is_null($possibleTable)) { // Build possible selected column $possibleSelectColumn = $possibleTable . '.' . $fieldName; $possibleMatch = self::hasMatch($possibleSelectColumn, $select); // If we found a possible match for a relation to an already selected column, let's use that if ($possibleMatch) { return $possibleSelectColumn; } $possibleWildcardMatch = self::hasWildcardMatch($possibleSelectColumn, $select); // Ditto with a possible wildcard match if ($possibleWildcardMatch) { return $possibleSelectColumn; } } // We couldn't match to a selected column return null; } }