123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- <?php
- namespace App\Http\Controllers\Api;
- use App\Classes\Pterodactyl;
- use App\Events\UserUpdateCreditsEvent;
- use App\Http\Controllers\Controller;
- use App\Models\DiscordUser;
- use App\Models\User;
- use App\Notifications\ReferralNotification;
- use App\Settings\UserSettings;
- use Carbon\Carbon;
- use Illuminate\Contracts\Foundation\Application;
- use Illuminate\Contracts\Pagination\LengthAwarePaginator;
- use Illuminate\Contracts\Routing\ResponseFactory;
- use Illuminate\Database\Eloquent\Builder;
- use Illuminate\Database\Eloquent\Collection;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Http\Request;
- use Illuminate\Http\Response;
- use Illuminate\Support\Facades\App;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Hash;
- use Illuminate\Support\Str;
- use Illuminate\Validation\Rule;
- use Illuminate\Validation\ValidationException;
- use Spatie\QueryBuilder\QueryBuilder;
- class UserController extends Controller
- {
- const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'roles', 'discordUser'];
- const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'suspended'];
- /**
- * Display a listing of the resource.
- *
- * @param Request $request
- * @return LengthAwarePaginator
- */
- public function index(Request $request)
- {
- $query = QueryBuilder::for(User::class)
- ->allowedIncludes(self::ALLOWED_INCLUDES)
- ->allowedFilters(self::ALLOWED_FILTERS);
- return $query->paginate($request->input('per_page') ?? 50);
- }
- /**
- * Display the specified resource.
- *
- * @param int $id
- * @return User|Builder|Collection|Model
- */
- public function show(int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- $query = QueryBuilder::for($user)
- ->with('discordUser')
- ->allowedIncludes(self::ALLOWED_INCLUDES)
- ->where('users.id', '=', $id)
- ->orWhereHas('discordUser', function (Builder $builder) use ($id) {
- $builder->where('id', '=', $id);
- });
- return $query->firstOrFail();
- }
- /**
- * Update the specified resource in storage.
- *
- * @param Request $request
- * @param int $id
- * @return User
- */
- public function update(Request $request, int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- $request->validate([
- 'name' => 'sometimes|string|min:4|max:30',
- 'email' => 'sometimes|string|email',
- 'credits' => 'sometimes|numeric|min:0|max:1000000',
- 'server_limit' => 'sometimes|numeric|min:0|max:1000000',
- ]);
- event(new UserUpdateCreditsEvent($user));
- //Update Users Password on Pterodactyl
- //Username,Mail,First and Lastname are required aswell
- $response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
- 'username' => $request->name,
- 'first_name' => $request->name,
- 'last_name' => $request->name,
- 'email' => $request->email,
- ]);
- if ($response->failed()) {
- throw ValidationException::withMessages([
- 'pterodactyl_error_message' => $response->toException()->getMessage(),
- 'pterodactyl_error_status' => $response->toException()->getCode(),
- ]);
- }
- $user->update($request->all());
- return $user;
- }
- /**
- * increments the users credits or/and server_limit
- *
- * @param Request $request
- * @param int $id
- * @return User
- *
- * @throws ValidationException
- */
- public function increment(Request $request, int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- $request->validate([
- 'credits' => 'sometimes|numeric|min:0|max:1000000',
- 'server_limit' => 'sometimes|numeric|min:0|max:1000000',
- ]);
- if ($request->credits) {
- if ($user->credits + $request->credits >= 99999999) {
- throw ValidationException::withMessages([
- 'credits' => "You can't add this amount of credits because you would exceed the credit limit",
- ]);
- }
- event(new UserUpdateCreditsEvent($user));
- $user->increment('credits', $request->credits);
- }
- if ($request->server_limit) {
- if ($user->server_limit + $request->server_limit >= 2147483647) {
- throw ValidationException::withMessages([
- 'server_limit' => 'You cannot add this amount of servers because it would exceed the server limit.',
- ]);
- }
- $user->increment('server_limit', $request->server_limit);
- }
- return $user;
- }
- /**
- * decrements the users credits or/and server_limit
- *
- * @param Request $request
- * @param int $id
- * @return User
- *
- * @throws ValidationException
- */
- public function decrement(Request $request, int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- $request->validate([
- 'credits' => 'sometimes|numeric|min:0|max:1000000',
- 'server_limit' => 'sometimes|numeric|min:0|max:1000000',
- ]);
- if ($request->credits) {
- if ($user->credits - $request->credits < 0) {
- throw ValidationException::withMessages([
- 'credits' => "You can't remove this amount of credits because you would exceed the minimum credit limit",
- ]);
- }
- $user->decrement('credits', $request->credits);
- }
- if ($request->server_limit) {
- if ($user->server_limit - $request->server_limit < 0) {
- throw ValidationException::withMessages([
- 'server_limit' => 'You cannot remove this amount of servers because it would exceed the minimum server.',
- ]);
- }
- $user->decrement('server_limit', $request->server_limit);
- }
- return $user;
- }
- /**
- * Suspends the user
- *
- * @param Request $request
- * @param int $id
- * @return bool
- *
- * @throws ValidationException
- */
- public function suspend(Request $request, int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- if ($user->isSuspended()) {
- throw ValidationException::withMessages([
- 'error' => 'The user is already suspended',
- ]);
- }
- $user->suspend();
- return $user;
- }
- /**
- * Unsuspend the user
- *
- * @param Request $request
- * @param int $id
- * @return bool
- *
- * @throws ValidationException
- */
- public function unsuspend(Request $request, int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- if (! $user->isSuspended()) {
- throw ValidationException::withMessages([
- 'error' => 'You cannot unsuspend an User who is not suspended.',
- ]);
- }
- $user->unSuspend();
- return $user;
- }
- /**
- * Create a unique Referral Code for User
- *
- * @return string
- */
- protected function createReferralCode()
- {
- $referralcode = STR::random(8);
- if (User::where('referral_code', '=', $referralcode)->exists()) {
- $this->createReferralCode();
- }
- return $referralcode;
- }
- /**
- * @throws ValidationException
- */
- public function store(Request $request, UserSettings $userSettings)
- {
- $request->validate([
- 'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
- 'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
- 'password' => ['required', 'string', 'min:8', 'max:191'],
- ]);
- // Prevent the creation of new users via API if this is enabled.
- if (! $userSettings->creation_enabled) {
- throw ValidationException::withMessages([
- 'error' => 'The creation of new users has been blocked by the system administrator.',
- ]);
- }
- $user = User::create([
- 'name' => $request->input('name'),
- 'email' => $request->input('email'),
- 'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
- 'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
- 'password' => Hash::make($request->input('password')),
- 'referral_code' => $this->createReferralCode(),
- ]);
- $response = Pterodactyl::client()->post('/application/users', [
- 'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
- 'username' => $user->name,
- 'email' => $user->email,
- 'first_name' => $user->name,
- 'last_name' => $user->name,
- 'password' => $request->input('password'),
- 'root_admin' => false,
- 'language' => 'en',
- ]);
- if ($response->failed()) {
- $user->delete();
- throw ValidationException::withMessages([
- 'pterodactyl_error_message' => $response->toException()->getMessage(),
- 'pterodactyl_error_status' => $response->toException()->getCode(),
- ]);
- }
- $user->update([
- 'pterodactyl_id' => $response->json()['attributes']['id'],
- ]);
- //INCREMENT REFERRAL-USER CREDITS
- if (! empty($request->input('referral_code'))) {
- $ref_code = $request->input('referral_code');
- $new_user = $user->id;
- if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {
- if (config('SETTINGS::REFERRAL:MODE') == 'register' || config('SETTINGS::REFERRAL:MODE') == 'both') {
- $ref_user->increment('credits', config('SETTINGS::REFERRAL::REWARD'));
- $ref_user->notify(new ReferralNotification($ref_user->id, $new_user));
- }
- //INSERT INTO USER_REFERRALS TABLE
- DB::table('user_referrals')->insert([
- 'referral_id' => $ref_user->id,
- 'registered_user_id' => $user->id,
- 'created_at' => Carbon::now(),
- 'updated_at' => Carbon::now(),
- ]);
- }
- }
- $user->sendEmailVerificationNotification();
- return $user;
- }
- /**
- * Remove the specified resource from storage.
- *
- * @param int $id
- * @return Application|Response|ResponseFactory
- */
- public function destroy(int $id)
- {
- $discordUser = DiscordUser::find($id);
- $user = $discordUser ? $discordUser->user : User::findOrFail($id);
- $user->delete();
- return response($user, 200);
- }
- }
|