Added member and invitation endpoints

This commit is contained in:
Constantin Graf
2024-04-10 17:45:53 +02:00
parent 234fa06324
commit b67961cb07
48 changed files with 1186 additions and 106 deletions

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Http\Requests\V1\Invitation\InvitationIndexRequest;
use App\Http\Requests\V1\Invitation\InvitationStoreRequest;
use App\Http\Resources\V1\Invitation\InvitationCollection;
use App\Http\Resources\V1\Invitation\InvitationResource;
use App\Models\Organization;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\JsonResponse;
use Laravel\Jetstream\Contracts\InvitesTeamMembers;
class InvitationController extends Controller
{
/**
* List all invitations of an organization
*
* @return InvitationCollection<InvitationResource>
*
* @throws AuthorizationException
*
* @operationId getInvitations
*/
public function index(Organization $organization, InvitationIndexRequest $request): InvitationCollection
{
$this->checkPermission($organization, 'invitations:view');
$invitations = $organization->teamInvitations()
->paginate();
return InvitationCollection::make($invitations);
}
/**
* Invite a user to the organization
*
* @throws AuthorizationException
*
* @operationId invite
*/
public function store(Organization $organization, InvitationStoreRequest $request): JsonResponse
{
$this->checkPermission($organization, 'invitations:create');
app(InvitesTeamMembers::class)->invite(
$request->user(),
$organization,
$request->input('email'),
$request->input('role')
);
return response()->json(null, 204);
}
}

View File

@@ -6,21 +6,32 @@ namespace App\Http\Controllers\Api\V1;
use App\Exceptions\Api\UserNotPlaceholderApiException;
use App\Http\Requests\V1\Member\MemberIndexRequest;
use App\Http\Resources\V1\User\MemberCollection;
use App\Http\Resources\V1\User\MemberResource;
use App\Http\Requests\V1\Member\MemberUpdateRequest;
use App\Http\Resources\V1\Member\MemberCollection;
use App\Http\Resources\V1\Member\MemberPivotResource;
use App\Http\Resources\V1\Member\MemberResource;
use App\Models\Membership;
use App\Models\Organization;
use App\Models\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Laravel\Jetstream\Contracts\InvitesTeamMembers;
class MemberController extends Controller
{
protected function checkPermission(Organization $organization, string $permission, ?Membership $membership = null): void
{
parent::checkPermission($organization, $permission);
if ($membership !== null && $membership->organization_id !== $organization->id) {
throw new AuthorizationException('Member does not belong to organization');
}
}
/**
* List all members of an organization
*
* @return MemberCollection<MemberResource>>
* @return MemberCollection<MemberPivotResource>>
*
* @throws AuthorizationException
*
@@ -37,15 +48,51 @@ class MemberController extends Controller
}
/**
* Invite a placeholder user to become a member of the organization
* Update a member of the organization
*
* @throws AuthorizationException
*
* @operationId updateMember
*/
public function update(Organization $organization, Membership $membership, MemberUpdateRequest $request): JsonResource
{
$this->checkPermission($organization, 'members:update', $membership);
$membership->billable_rate = $request->input('billable_rate');
$membership->role = $request->input('role');
$membership->save();
return new MemberResource($membership);
}
/**
* Remove a member of the organization.
*
* @throws AuthorizationException
*
* @operationId removeMember
*/
public function destroy(Organization $organization, Membership $membership): JsonResponse
{
$this->checkPermission($organization, 'members:delete', $membership);
$membership->delete();
return response()
->json(null, 204);
}
/**
* Invite a placeholder member to become a real member of the organization
*
* @throws AuthorizationException|UserNotPlaceholderApiException
*
* @operationId invitePlaceholder
*/
public function invitePlaceholder(Organization $organization, User $user, Request $request): JsonResponse
public function invitePlaceholder(Organization $organization, Membership $membership, Request $request): JsonResponse
{
$this->checkPermission($organization, 'members:invite-placeholder');
$this->checkPermission($organization, 'members:invite-placeholder', $membership);
$user = $membership->user;
if (! $user->is_placeholder) {
throw new UserNotPlaceholderApiException();

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Exceptions\Api\InactiveUserCanNotBeUsedApiException;
use App\Exceptions\Api\UserIsAlreadyMemberOfProjectApiException;
use App\Http\Requests\V1\ProjectMember\ProjectMemberStoreRequest;
use App\Http\Requests\V1\ProjectMember\ProjectMemberUpdateRequest;
use App\Http\Resources\V1\ProjectMember\ProjectMemberCollection;
@@ -11,6 +13,7 @@ use App\Http\Resources\V1\ProjectMember\ProjectMemberResource;
use App\Models\Organization;
use App\Models\Project;
use App\Models\ProjectMember;
use App\Models\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -51,16 +54,25 @@ class ProjectMemberController extends Controller
/**
* Add project member to project
*
* @throws AuthorizationException
* @throws AuthorizationException|InactiveUserCanNotBeUsedApiException|UserIsAlreadyMemberOfProjectApiException
*
* @operationId createProjectMember
*/
public function store(Organization $organization, Project $project, ProjectMemberStoreRequest $request): JsonResource
{
$this->checkPermission($organization, 'project-members:create', $project);
$user = User::findOrFail((string) $request->input('user_id'));
if ($user->is_placeholder) {
throw new InactiveUserCanNotBeUsedApiException();
}
if (ProjectMember::whereBelongsTo($project, 'project')->whereBelongsTo($user, 'user')->exists()) {
throw new UserIsAlreadyMemberOfProjectApiException();
}
$projectMember = new ProjectMember();
$projectMember->user_id = $request->input('user_id');
$projectMember->billable_rate = $request->input('billable_rate');
$projectMember->user()->associate($user);
$projectMember->project()->associate($project);
$projectMember->save();