4

I want to restrict access to a method if a parameter has a specific value. Lets take for example this class:

Simple.php:

class Simple
{
    function item($name)
    {
        if($name == "somerestricted")
        {
            // Here should be an authentication check (or somewhere else), hopefully, using an iAuthenticate class
            // Later, there will be a check using a database to determine if authentication will be required
            // So user/password may vary
            if($authenticated)
            {
                // Proceed
            }
            else
            {
                // ???
            }
        }
        else
        {
            echo "Hi!";
        }
    }
}

Using this authentication class:

BasicAuthentication.php:

class BasicAuthentication implements iAuthenticate
{
    const REALM = 'Restricted API';
    function __isAllowed()
    {
        if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']))
        {
            $user = $_SERVER['PHP_AUTH_USER'];
            $pass = $_SERVER['PHP_AUTH_PW'];
            if($user == 'laterfetched' && $pass == 'fromdatabase')
            {
                return true;
            }
        }
        header('WWW-Authenticate: Basic realm="'.self::REALM.'"');
        throw new RestException(401, 'Basic Authentication Required');
    }
}

Index.php (gateway): addAuthenticationClass('BasicAuthentication'); $r->addAPIClass('Simple'); $r->handle();

The simple/item method is now publicly accessible. However, if I turn item it into a protected function, every request needs authentication. This is not what i want to do. Only simple/item/somerestricted should require authentication.

So is there a way to restrict the iAuthenticate to a specific parameter value? If not, how can I solve this issue anyway?

User name and password will be varying in production use (depending on the given parameter).

I found these relevant questions: Restler 3.0 Basic Authentication and Luracast Restler Authentication

I am using Restler rc4.

nikeee
  • 10,248
  • 7
  • 40
  • 66

1 Answers1

2

You have make yours a hybrid api, which is public and will enhance the results if the user is authenticated

One way to do it is as given below. It is using a hidden property in Restler

class Simple
{
    /**
     * @var \Luracast\Restler\Restler
     */
    public $restler;
    /**
     * @access hybrid
     */
    function item($name)
    {
        if ($name == "somerestricted") {
            if ($this->restler->_authenticated) {
                // Proceed
            } else {
                // ???
            }
        } else {
            echo "Hi!";
        }
    }
}

Another (recommended) way is to use iUseAuthentication Interface

use Luracast\Restler\iUseAuthentication;

class Simple implements iUseAuthentication
{
    protected $authenticated;

    /**
     * @access hybrid
     */
    function item($name)
    {
        if ($name == "somerestricted") {
            if ($this->authenticated) {
                // Proceed
            } else {
                // ???
            }
        } else {
            echo "Hi!";
        }
    }

    public function __setAuthenticationStatus($isAuthenticated = false)
    {
        $this->authenticated = $isAuthenticated;
    }
}
Arul Kumaran
  • 983
  • 7
  • 23
  • 1
    What if the username/password used for authentication depends on the $name parameter? – nikeee Jan 30 '14 at 18:41
  • It need not be, and not in the above use case – Arul Kumaran Jan 31 '14 at 01:11
  • Not in the above case, right. But what if... say I want to protect every item using a (for that item) generated username/password? Is this possible? – nikeee Jan 31 '14 at 19:22
  • 1
    For that case, authentication class will identify the user with the given user name and password and set a static property of User class. Api method will first get the requested object and then compare the owner with the current user. If user is not the owner it can throw an exception for example 403 Forbidden. You are not the owner – Arul Kumaran Feb 01 '14 at 13:32