Skip to content

Laravel assessment #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions app/Concerns/HasUuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
namespace App\Concerns;

use Illuminate\Support\Str;

trait HasUuid
{
public static function bootHasUuid()
{
static::creating(function ($model) {
$model->id = $model->id ?? Str::orderedUuid()->toString();
});
}
}
20 changes: 20 additions & 0 deletions app/Constants/Permissions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
namespace App\Constants;

class Permissions
{
// USERS
public const CREATE_USER = 'create_user';
public const UPDATE_USER = 'update_user';
public const VIEW_USER = 'view_user';
public const DELETE_USER = 'delete_user';

// PROJECTS
public const CREATE_PROJECT = 'create_project';
public const VIEW_PROJECT = 'view_project';
public const UPDATE_PROJECT = 'update_project';
public const DELETE_PROJECT = 'delete_project';

// TASKS
public const CREATE_TASK = 'create_task';
}
22 changes: 22 additions & 0 deletions app/Dto/CreateUserDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
namespace App\Dto;

class CreateUserDto
{
public function __construct(
public string $username,
public string $password,
public string $role,
) {

}

public function toArray(): array
{
return [
'username' => $this->username,
'password' => $this->password,
'role' => $this->role,
];
}
}
22 changes: 22 additions & 0 deletions app/Dto/UpdateUserDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
namespace App\Dto;

class UpdateUserDto
{
public function __construct(
public ?string $username = null,
public ?string $password = null,
public ?string $role = null,
) {

}

public function toArray()
{
return [
'username' => $this->username,
'password' => $this->password,
'role' => $this->role
];
}
}
37 changes: 37 additions & 0 deletions app/Http/Controllers/Auth/AuthController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
namespace App\Http\Controllers\Auth;

use App\Dto\CreateUserDto;
use App\Http\Controllers\Controller;
use App\Http\Requests\Users\CreateUserRequest;
use App\Http\Requests\Users\LoginRequest;
use App\Http\Requests\Users\RegisterRequest;
use App\Http\Resources\AuthUserResource;
use App\Models\User;
use App\Services\Users\CreateUser;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
public function register(CreateUserRequest $request, CreateUser $createUserService)
{
$user = $createUserService->execute(
new CreateUserDto(
username: $request->input('username'),
password: $request->input('password'),
role: $request->input('role')
)
);

return AuthUserResource::make($user);
}

public function store(LoginRequest $request)
{
$user = User::where('username', $request->username)->first();

abort_if(!$user || !Hash::check($request->password, $user->password), 404, 'User not found!');

return AuthUserResource::make($user);
}
}
65 changes: 65 additions & 0 deletions app/Http/Controllers/ProjectController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace App\Http\Controllers;

use App\Http\Requests\Projects\CreateProjectRequest;
use App\Http\Resources\ProjectResource;
use App\Models\Project;
use Illuminate\Http\Request;

class ProjectController extends Controller
{

public function index()
{
$this->authorize('view', Project::class);

return ProjectResource::collection(Project::all());
}

public function store(CreateProjectRequest $request)
{
$this->authorize('create', Project::class);

return ProjectResource::make(Project::create($request->validated()));
}

public function show(Project $project)
{
$this->authorize('view', Project::class);

return ProjectResource::make($project);
}

public function updateWithPut(CreateProjectRequest $createProjectRequest, Project $project)
{
$this->authorize('update', Project::class);

$project->name = $createProjectRequest->input('name', $project->name);
$project->timestamps = false;
$project->save();

return ProjectResource::make($project);
}

public function updateWithPatch(CreateProjectRequest $createProjectRequest, Project $project)
{
$this->authorize('update', Project::class);

$project->update($createProjectRequest->validated());

return ProjectResource::make($project);
}

public function destroy(Project $project)
{
$this->authorize('delete', Project::class);

$project->delete();

return response()->json([
'message' => $project->name . ' has been deleted!',
'success' => true
]);
}
}
10 changes: 10 additions & 0 deletions app/Http/Controllers/RoleController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;

class RoleController extends Controller
{
public function __invoke()
{
return app('roleService')->options();
}
}
78 changes: 78 additions & 0 deletions app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace App\Http\Controllers;

use App\Dto\CreateUserDto;
use App\Dto\UpdateUserDto;
use App\Http\Requests\Users\CreateUserRequest;
use App\Http\Requests\Users\PartiallyUpdateUserRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use App\Services\Users\CreateUser;
use App\Services\Users\UpdateUserWithPatch;
use App\Services\Users\UpdateUserWithPut;

class UserController extends Controller
{
public function index()
{
return UserResource::collection(User::all());
}

public function store(CreateUserRequest $request, CreateUser $createUserService)
{
$user = $createUserService->execute(
new CreateUserDto(
username: $request->input('username'),
password: $request->input('password'),
role: $request->input('role')
));

return UserResource::make($user);
}

public function show(User $user)
{
return UserResource::make($user);
}

// definitely personal choice here to use CreateUserRequest instead of creating other form request
// as i think it would be quite similar
public function updateWithPut(CreateUserRequest $request, User $user, UpdateUserWithPut $updateUserWithPut)
{
$user = $updateUserWithPut->execute(
$user,
new CreateUserDto(
username: $request->input('username'),
password: $request->input('password'),
role: $request->input('role'),
)
);

return UserResource::make($user);
}

public function updateWithPatch(PartiallyUpdateUserRequest $request, User $user, UpdateUserWithPatch $updateUserWithPatch)
{
$user = $updateUserWithPatch->execute(
$user,
new UpdateUserDto(
username: $request->input('username'),
password: $request->input('password'),
role: $request->input('role'),
)
);

return UserResource::make($user);
}

public function destroy(User $user)
{
$user->delete();

return response()->json([
'message' => $user->username . ' has been deleted!',
'success' => true
]);
}
}
23 changes: 23 additions & 0 deletions app/Http/Requests/Projects/CreateProjectRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Requests\Projects;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class CreateProjectRequest extends FormRequest
{
public function rules()
{
$nameAdditionalRule = Rule::unique('projects', 'name');

if ($this->project) {
$nameAdditionalRule = $nameAdditionalRule->ignore($this->project->id);
}
return [
'name' => [
'required',
$nameAdditionalRule,
]
];
}
}
46 changes: 46 additions & 0 deletions app/Http/Requests/Users/CreateUserRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
namespace App\Http\Requests\Users;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Validation\Rule;

class CreateUserRequest extends FormRequest
{

public function rules()
{
$usernameAdditionalRule = Rule::unique('users', 'username');

if ($this->user) {
$usernameAdditionalRule = $usernameAdditionalRule->ignore($this->user->id);
}

return [
'username' => [
'required',
$usernameAdditionalRule,
],
'password' => 'required|confirmed',
'role' => [
'required',
Rule::in(collect(app('roleService')->roles)->map->value()->toArray())
]
];
}

protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json([
'errors' => $validator->errors(),
], 422));
}

public function messages()
{
return [
'role.in' => 'Role should be either admin, product_owner, or dev',
];
}
}
24 changes: 24 additions & 0 deletions app/Http/Requests/Users/LoginRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace App\Http\Requests\Users;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;

class LoginRequest extends FormRequest
{
public function rules()
{
return [
'username' => 'required',
'password' => 'required'
];
}

protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json([
'errors' => $validator->errors(),
], 422));
}
}
Loading