paginate( perPage: $request->input('per_page', 15), page: $request->input('page', 1), total: Usuario::all()->count(), route: 'users.all', ); $data = Usuario::with('restaurantes') ->skip($paginate['from'] - 1) ->take($paginate['per_page'])->get()->all(); return response()->json([ 'pagination' => $paginate, 'data' => $data ]); } /** * Obtiene un usuario por su id * @param $id * @return JsonResponse */ public function get($id) { if (!str_starts_with($id, 'auth0')) { app(UuidService::class)->validOrFail($id); } $usuario = Usuario::findOrFail($id); return response()->json($usuario); } /** * Crea un nuevo usuario localmente y en auth0 * @throws ValidationException */ public function create(Request $request) { $this->validate($request, [ 'nombre' => 'required', 'email' => 'required|email', 'username' => 'required', 'password' => 'required', 'roles' => 'required|array', 'roles.*' => ['required', Rule::in(['admin', 'mesero', 'recaudador', 'productor'])], 'restaurant' => 'required|exists:restaurantes,id', ]); $restaurant = Restaurante::findOrFail($request->input('restaurant')); $this->canManageUsersAndRestaurantOrFail($request->user, $restaurant); $auth0 = app(Auth0Service::class); $auth0User = $auth0->createUser( email: $request->input('email'), username: $request->input('username'), password: $request->input('password'), metadata: [ 'roles' => $request->input('roles'), 'restaurantes' => [$restaurant->id], ] ); if (array_key_exists('error', $auth0User)) { return response()->json([ 'error' => $auth0User['errorCode'], 'message' => $auth0User['message'], ], $auth0User['statusCode']); } $usuario = $restaurant->usuarios()->create([ 'id' => Uuid::uuid4(), 'auth0_id' => $auth0User['identities'][0]['provider'] . '|' . $auth0User['identities'][0]['user_id'], 'nombre' => $request->input('nombre') ]); return response()->json($usuario, 201); } /** * Actualiza un usuario * @param Request $request * @param $id * @return JsonResponse * @throws ValidationException */ public function update(Request $request, $id) { if (!str_starts_with($id, 'auth0')) { app(UuidService::class)->validOrFail($id); } $this->validate($request, [ 'nombre' => 'sometimes', 'email' => 'sometimes|email', 'username' => 'sometimes', 'password' => 'sometimes', 'roles' => 'sometimes|array', 'roles.*' => ['sometimes', Rule::in(['admin', 'mesero', 'recaudador', 'productor'])], ]); $usuario = Usuario::findOrFail($id); $this->canManageUserOrFail($request->user, $usuario); $metadata = []; if ($request->input('roles')) $metadata['roles'] = $request->input('roles'); $auth0 = app(Auth0Service::class); $auth0User = $auth0->updateUser( auth0_id: $usuario->auth0_id, email: $request->input('email'), username: $request->input('username'), password: $request->input('password'), metadata: $metadata ); if (array_key_exists('error', $auth0User)) { return response()->json([ 'error' => $auth0User['errorCode'], 'message' => $auth0User['message'], ], $auth0User['statusCode']); } if ($request->input('nombre')) $usuario->nombre = $request->input('nombre'); $usuario->save(); return response()->json($usuario); } /** * Elimina un usuario * @param Request $request * @param $id * @return JsonResponse */ public function delete(Request $request, $id) { if (!str_starts_with($id, 'auth0')) { app(UuidService::class)->validOrFail($id); } $usuario = Usuario::findOrFail($id); $this->canManageUserOrFail($request->user, $usuario); $auth0 = app(Auth0Service::class); $auth0Response = $auth0->deleteUser($usuario->auth0_id); if ($auth0Response && array_key_exists('error', $auth0Response)) { return response()->json([ 'error' => $auth0Response['errorCode'], 'message' => $auth0Response['message'], ], $auth0Response['statusCode']); } $usuario->delete(); return response()->json([], 204); } /** * Agrega usuario a un restaurant * @param Request $request * @param $id * @param $restaurant * @return JsonResponse */ public function addToRestaurant(Request $request, $id, $restaurant) { if (!str_starts_with($id, 'auth0')) { app(UuidService::class)->validOrFail($id); } if (!str_starts_with($restaurant, 'auth0')) { app(UuidService::class)->validOrFail($restaurant); } $usuario = Usuario::findOrFail($id); $restaurant = Restaurante::findOrFail($restaurant); $this->canManageUsersAndRestaurantOrFail($request->user, $restaurant); if ($usuario->restaurantes->contains($restaurant)) { return response()->json([ 'error' => 'already_on_restaurant', 'message' => 'El usuario ' . $usuario->id . ' ya se encuentra en el restaurante ' . $restaurant->id ], 400); } $restaurant->usuarios()->attach($usuario); return response()->json($usuario->fresh(['restaurantes'])); } /** * Saca a un usuario de un restaurant * * @param Request $request * @param $id * @param $restaurant * @return JsonResponse */ public function removeFromRestaurant(Request $request, $id, $restaurant) { if (!str_starts_with($id, 'auth0')) { app(UuidService::class)->validOrFail($id); } if (!str_starts_with($restaurant, 'auth0')) { app(UuidService::class)->validOrFail($restaurant); } $usuario = Usuario::findOrFail($id); $restaurant = Restaurante::findOrFail($restaurant); canManageUsersAndRestaurantOrFail($request->user, $restaurant); if (!$usuario->restaurantes->contains($restaurant)) { return response()->json([ 'error' => 'already_not_on_restaurant', 'message' => 'El usuario ' . $usuario->id . ' no encuentra en el restaurante ' . $restaurant->id ], 400); } $restaurant->usuarios()->detach($usuario); return response()->json($usuario->fresh(['restaurantes'])); } private function canManageUsersAndRestaurantOrFail(Usuario $user, Restaurante $restaurante) { if (!$user->canManageUsers()) { throw new GenericException('cant_manage_users', 'El usuario ' . $user->id . ' no tiene permisos para manipular usuarios', 403); } if (!$user->hasPermissionsOnRestaurant($restaurante)) { throw new GenericException('cant_manage_user_of_another_restaurant', 'El usuario ' . $user->id . ' no puede manipular un usuario en el restaurant ' . $restaurante->id . ' porque que no pertenece a el', 403); } } private function canManageUserOrFail(Usuario $manager, Usuario $user) { if (!$manager->canManageUsers()) { throw new GenericException('cant_manage_users', 'El usuario ' . $user->id . ' no tiene permisos para manipular usuarios', 403); } if (!$manager->hasPermissionsOverUser($user)) { throw new GenericException('cant_manage_that_user', 'El usuario ' . $manager->id . ' no tiene permisos para manipular al usuario ' . $user->id, 403); } } }