codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.34k stars 1.9k forks source link

Bug: Validation with request raw body. #3694

Closed agungsugiarto closed 4 years ago

agungsugiarto commented 4 years ago

Describe the bug Capture When request with raw body, this validation didn't capture request, and will be missing input.

<?php

namespace App\Controllers;

use CodeIgniter\Controller

class AuthenticationController extends Controller
{
    /**
     * Register New Users from POST Requests to /api/users.
     * 
     * @return \CodeIgniter\HTTP\Response
     */
    public function register()
    {
        if (! $this->validate(static::rules())) {
            return $this->response->setJSON([
                'errors' => $this->validator->getErrors()
            ])
            ->setStatusCode(422);
        }
    }

    protected static function rules()
    {
        return [
            'email'    => 'required|is_unique[users.email]|valid_email',
            'username' => 'required|is_unique[users.username]|alpha_numeric_space',
            'password' => 'required|min_length[5]',
        ];
    }
}

CodeIgniter 4 version v4.0.4

Affected module(s) CodeIgniter\Validation\Validation

Context

agungsugiarto commented 4 years ago

Oh im fix me problem with change validate() with my validateCustom() to base controller.

BaseController:

/**
 * A shortcut to performing validation on input data. If validation
 * is not successful, a $errors property will be set on this class.
 *
 * @param array|string $rules
 * @param array|string $data
 * @param array        $messages An array of custom error messages
 *
 * @return boolean
 */
protected function validateCustom($rules, $data, array $messages = []): bool
{
    $this->validator = Services::validation();
    // If you replace the $rules array with the name of the group
    if (is_string($rules)) {
        $validation = config('Validation');

        // If the rule wasn't found in the \Config\Validation, we
        // should throw an exception so the developer can find it.
        if (!isset($validation->$rules)) {
            throw ValidationException::forRuleNotFound($rules);
        }

        // If no error message is defined, use the error message in the Config\Validation file
        if (!$messages) {
            $errorName = $rules . '_errors';
            $messages  = $validation->$errorName ?? [];
        }

        $rules = $validation->$rules;
    }

    return $this->validator
        ->setRules($rules, $messages)
        ->run($data);
}

My own controller:

<?php

namespace App\Controllers;

use CodeIgniter\Controller

class AuthenticationController extends Controller
{
    /**
     * Register New Users from POST Requests to /api/users.
     * 
     * @return \CodeIgniter\HTTP\Response
     */
    public function register()
    {
        $request = $this->request->getJSON();

        if (! $this->validateCustom(static::rules(), (array) $request->user))) {
            return $this->response->setJSON([
                'errors' => $this->validator->getErrors()
            ])
            ->setStatusCode(422);
        }
    }
}