Skip to content

Instantly share code, notes, and snippets.

@waqqas
Last active January 5, 2018 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waqqas/7f773454b778bf1da63a to your computer and use it in GitHub Desktop.
Save waqqas/7f773454b778bf1da63a to your computer and use it in GitHub Desktop.
API RBAC
public function checkApiAccess($model, $params = array()){
$op = strtolower(substr($this->action->id, strpos($this->action->id, ".") + 1));
if(is_object($model))
$model = strtolower(get_class($model));
$key = Yii::app()->getRequest()->getParam('apikey');
return Yii::app()->apiAuthManager->checkAccess($op. "-" . $model, $key, $params);
}
<?php
class m150512_070256_create_api_rbac_tables extends CDbMigration
{
public function safeUp()
{
$this->createTable('{{auth_item}}', array(
'name' => 'varchar(64) not null',
'type' => 'integer not null',
'description' => 'text',
'bizrule' => 'text',
'data' => 'text',
'primary key (`name`)',
), 'ENGINE=InnoDB'
);
$this->createTable('{{auth_item_child}}', array(
'parent' => 'varchar(64) not null',
'child' => 'varchar(64) not null',
'primary key (`parent`,`child`)',
'foreign key (`parent`) references `{{auth_item}}` (`name`) on delete cascade on update cascade',
'foreign key (`child`) references `{{auth_item}}` (`name`) on delete cascade on update cascade'
), 'ENGINE=InnoDB'
);
$this->createTable('{{auth_assignment}}', array(
'itemname' => 'varchar(64) not null',
'userid' => 'varchar(64) not null',
'bizrule' => 'text',
'data' => 'text',
'primary key (`itemname`,`userid`)',
'foreign key (`itemname`) references `{{auth_item}}` (`name`) on delete cascade on update cascade'
), 'ENGINE=InnoDB'
);
}
public function safeDown()
{
$this->dropTable('{{auth_assignment}}');
$this->dropTable('{{auth_item_child}}');
$this->dropTable('{{auth_item}}');
}
}
'apiAuthManager' => array(
'class' => 'CDbAuthManager',
'assignmentTable' => 'tbl_auth_assignment',
'itemChildTable' => 'tbl_auth_item_child',
'itemTable' => 'tbl_auth_item',
),
$this->onRest('model.count', function ($model) {
if (!$this->checkApiAccess($model))
return 0;
return $model->count();
});
$this->onRest('model.find.all', function ($model) {
if (!$this->checkApiAccess($model))
return array();
return $model->findAll();
});
$this->onRest('model.find', function ($model, $id) {
if ($this->checkApiAccess($model))
return $model->findByPk($id);
});
$this->onRest('model.with.relations', function ($model) {
$nestedRelations = [];
foreach ($model->metadata->relations as $rel => $val) {
$className = $val->className;
if ($this->checkApiAccess(strtolower($className))) {
$rel_model = call_user_func([$className, 'model']);
if (!is_array($rel_model->tableSchema->primaryKey) && substr($rel, 0, 1) != '_') {
$nestedRelations[] = $rel;
}
}
}
return $nestedRelations;
});
$this->onRest('req.is.subresource', function ($model, $subresource_name, $http_verb) {
if (!array_key_exists($subresource_name, $model->relations())) {
return false;
}
if(!$this->checkApiAccess($model->metadata->relations[$subresource_name]->className))
return false;
return true;
});
@amjadsoftrove
Copy link

An updated version of SeriesController.php here:

$this->onRest(ERestEvent::REQ_CORS_ACCESS_CONTROL_ALLOW_ORIGIN, function() {
return ApiHelper::GetAllowedOrigins();
});

    $this->onRest(ERestEvent::REQ_CORS_ACCESS_CONTROL_ALLOW_METHODS, function() {
        return array('GET', 'POST', 'PUT', 'DELETE','OPTIONS');
    });

    $this->onRest(ERestEvent::REQ_CORS_ACCESS_CONTROL_ALLOW_HEADERS, function($application_id) {
        return array();
    });

    $this->onRest(ERestEvent::REQ_AUTH_TYPE, function($application_id) {
        // set value of origin header, if not present
        $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : Yii::app()->getBaseUrl(true);
        $_SERVER['HTTP_ORIGIN'] = $origin;

        // treat all request as CORS
        return ERestEventListenerRegistry::REQ_TYPE_CORS;
    });

    $this->onRest(ERestEvent::MODEL_INSTANCE, function() {
        return new Episode();
    });
    /**/
    $this->onRest(ERestEvent::MODEL_COUNT, function ($model) {
        if (!$this->checkApiAccess($model))
            return 0;
        return $model->count();
    });

    $this->onRest(ERestEvent::MODEL_FIND_ALL, function ($model) {
        if (!$this->checkApiAccess($model))
            return array();
        return $model->findAll();
    });

    $this->onRest(ERestEvent::MODEL_FIND, function ($model, $id) {
        if ($this->checkApiAccess($model))
            return $model->findByPk($id);
    });


    $this->onRest(ERestEvent::MODEL_WITH_RELATIONS, function ($model) {
        $nestedRelations = [];
        foreach ($model->metadata->relations as $rel => $val) {
            $className = $val->className;
            if ($this->checkApiAccess(strtolower($className))) {
                $rel_model = call_user_func([$className, 'model']);
                if (!is_array($rel_model->tableSchema->primaryKey) && substr($rel, 0, 1) != '_') {
                    $nestedRelations[] = $rel;
                }
            }
        }
        return $nestedRelations;
    });

    $this->onRest(ERestEvent::REQ_IS_SUBRESOURCE, function ($model, $subresource_name, $http_verb) {
        if (!array_key_exists($subresource_name, $model->relations())) {
            return false;
        }
        if(!$this->checkApiAccess($model->metadata->relations[$subresource_name]->className))
            return false;
        return true;
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment