Yii2 create custom rest action with post params - rest

In my yii2 application i need to develop a rest action authUser()
public function actionAuthUser($username, $password)
{
return \api\models\User::findOne(['username' => $username, 'password' => sha1($password)]);
}
The params should be passed with post method because they contain sensitive informations.
How can i do this? How can i set the url manager to receive with post method my params?
Thanks in advance for all the help

[
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
// ...
[
'POST site/auth-user' => 'site/auth-user',
]
],
],
],
]
Or add behavior to Controller
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'auth-user' => ['post'],
],
],
];
}
And in controller action
public function actionAuthUser()
{
return \api\models\User::findOne(['username' => Yii::$app->request->post('username'), 'password' => sha1(Yii::$app->request->post('password'))]);
}

Related

Access translator in Shopware 6 Plugin

I am developing my first Shopware 6 plugin and was wondering how to access snippets in the Plugin class. I checked the Developer Guide but could not make it work.
I want to use the plugin translation as label in customField select options.
myfirstplugin.en-GB.json
{
"myfirstplugin": {
"my_custom_field_option_1": "Option 1",
"my_custom_field_option_2": "Option 2",
}
}
MyFirstPlugin.php
class MyFirstPlugin extends Plugin
{
// ....
private function createCustomFields(Context $context): void
{
if ($this->customFieldSetExists($context)) {
return;
}
$customFieldSetRepository = $this->container->get('custom_field_set.repository');
$customFieldSetRepository->create([
[
'id' => '294865e5c81b434d8349db9ea6b4e135',
'name' => 'my_custom_field_set',
'customFields' => [
[
'name' => 'my_custom_field',
'type' => CustomFieldTypes::SELECT,
'config' => [
'label' => [ 'en-GB' => 'My custom field'],
'options' => [
[
'value' => '294865e5c81b434d8349db9ea6b4e487',
// Access my_custom_field_option_1 of snippet myfirstplugin.en-GB.json
'label' => 'my_custom_field_option_1',
],
[
'value' => '1ce5abe719a04346930c7e43514ed4f1',
// Access my_custom_field_option_2 of snippet myfirstplugin.en-GB.json
'label' => 'my_custom_field_option_2',
],
],
'customFieldType' => 'select',
'componentName' => 'sw-single-select',
'customFieldPosition' => 1,
],
],
]
],
], $context);
}
}
You can inject an argument of type Translator to your service
in services.xml
<argument type="service" id="translator"/>
in your service
use Shopware\Core\Framework\Adapter\Translation\Translator;
/**
* #var Translator
*/
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
then down the way you can use this pretty much the same as in a twig template:
$translated = $this->translator
->trans(
'myfirstplugin.product.detail.294865e5c81b434d8349db9ea6b4e487');
I think you can use the snippet repository and search the label as you want in the Plugin class like
$sRepo = $this->container->get('snippet.repository');
$labels = $sRepo->search((new Criteria())
->addFilter(
new MultiFilter(
MultiFilter::CONNECTION_OR,
[
new ContainsFilter('translationKey', 'my_custom_field_option_1'),
new ContainsFilter('translationKey', 'my_custom_field_option_2')
]
)
), $context)->getElements();
When you create the custom field you don't have to reference a translation snippet. Instead you can just provide the translations in the payload directly.
'config' => [
'label' => ['en-GB' => 'Label english', 'de-DE' => 'Label german'],
'type' => CustomFieldTypes::SELECT,
'options' => [
[
'value' => '294865e5c81b434d8349db9ea6b4e487',
'label' => ['en-GB' => 'Option english', 'de-DE' => 'Option german'],
],
[
'value' => '1ce5abe719a04346930c7e43514ed4f1',
'label' => ['en-GB' => 'Option english', 'de-DE' => 'Option german'],
],
],
],

Yii2 facebook login

I am trying to integrate facebook login in my website. I created the app and i got the app id and app secret. After successfull login in facebook, how should i got the return data. Here is my code.
public function actions() {
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
'auth' => [
'class' => 'yii\authclient\AuthAction',
'successCallback' => [$this, 'oAuthSuccess'],
],
];
}
public function oAuthSuccess($client) {
// get user data from client
$userAttributes = $client->getUserAttributes();
print_r($userAttributes);
exit;
}
here is my config/main.php:
'authClientCollection' => [
'class' => 'yii\authclient\Collection',
'clients' => [
'facebook' => [
'class' => 'yii\authclient\clients\Facebook',
'authUrl' => 'https://www.facebook.com/dialog/oauth?display=popup',
'clientId' => '****',
'clientSecret' => '*****',
'attributeNames' => ['name', 'email', 'first_name', 'last_name'],
// 'returnUrl' => 'https://www.example.com/site/auth',
],
],
],
Is it required to give any return url?
After login to the facebook it returned to a not found page. What is the issue?

Method not allowed(#405)

following code throws out error like this:
"Method Not Allowed (#405)
Method Not Allowed. This url can only handle the following request methods: ."
Any ideas,how to fix this?
['label' => 'Logout', 'url' => ['/site/logout'], 'linkOptions' => ['data' => ['method' => 'post']]],
Here is still method in SiteController:
public function actionLogout() {
Yii::$app->user->logout();
return $this->goHome();
}
use data-method in linkOptions
['label' => 'logOut',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
],
notice:check behavior in sitecontroller
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'dashboard'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}

rewrite POST method on rest api yii2

I must rewrite post request on rest yii2.
Every time i've post request on url v1/availability
I want to call actionCreate for manage request.
This is my main.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability'],
'pluralize' => true,
'extraPatterns' => [
'POST v1/availability' => 'v1/availability/create'
]
],
'OPTIONS v1/user/login' => 'v1/user/login',
'POST v1/user/login' => 'v1/user/login',
'POST v2/user/login' => 'v2/user/login',
'OPTIONS v2/user/login' => 'v2/user/login',
],
],
In the v1/controllers/AvailabilityController.php
i've
public function actions()
{
$actions = parent::actions();
unset($actions['view']);
return array_merge(
$actions,
[
'index' => [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
'prepareDataProvider' => [$this, 'index']
],
]
);
}
public function actionCreate(){
throw new \yii\web\HttpException(200, 'IT WORKS!', 200);
}
Any idea?
add url rule outside like below.
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability']
],
'POST v1/availability' => 'v1/availability/create',
'OPTIONS v1/user/login' => 'v1/user/login',
'POST v1/user/login' => 'v1/user/login',
'POST v2/user/login' => 'v2/user/login',
'OPTIONS v2/user/login' => 'v2/user/login',
],
],
And here you need understand rules of Yii. if you add one rule like below.
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
this open many urls for clients.
[
'PUT,PATCH users/<id>' => 'user/update',
'DELETE users/<id>' => 'user/delete',
'GET,HEAD users/<id>' => 'user/view',
'POST users' => 'user/create',
'GET,HEAD users' => 'user/index',
'users/<id>' => 'user/options',
'users' => 'user/options',
]
above all urls will open for clients.
So...
there are 2 way to override post.
First #Irfan Ali method
This method permit to declare single call in main.php and work with single function in controller.
Second method is
in main.php declare general call to availability
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability'],
'pluralize' => true,
],
],
],
for intercept post method you must override in the controller
public function createAction($id){
throw new \yii\web\HttpException(200, 'You receive post or put', 200);
}
and in this function you must intercept if call is post you do anything.
I love first method!

Yii2 backend url manager rules for module

I have created a module in Yii2 using Gii code generator. My new generated module location is
backend/modules/cms
cms is new generated module name.
backend/config/main.php after setting module configuration looks as following
return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'bootstrap' => ['log'],
'modules' => [
'gii' => [
'class' => 'yii\gii\Module', //adding gii module
'allowedIPs' => ['127.0.0.1', '::1'] //allowing ip's
],
'cms' => [
'class' => 'backend\modules\cms\Cms',
],
],
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<controller:\w+>/<action:\w+>/<id:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'<module:\w+>/<controller:\w+>/<action:\w+>' => '<module>/<controller>/<action>',
'<module:\w+><controller:\w+>/<action:update|delete>/<id:\d+>' => '<module>/<controller>/<action>',
]
],
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'js' => []
],
],
],
],
'params' => $params,
];
behaviors function in controller looks as after setting access rules
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index', 'create', 'update', 'delete'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
Only index action of my controller is accessible. when i access any other action in controller url changes but shows index action contents.
How can i access all actions in controller?
It will be appreciable if someone help me resolving this issue.
my controller
namespace backend\modules\cms\controllers;
use Yii;
use yii\filters\AccessControl;
use backend\modules\cms\models\Pages;
use backend\modules\cms\models\PagesSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* PagesController implements the CRUD actions for Pages model.
*/
class PagesController extends Controller
{
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index', 'create', 'update', 'delete'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
// 'delete' => ['post'],
],
],
];
}
/**
* Lists all Pages models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new PagesSearch();
$dataProvider = $searchModel->search(Yii::$app->request->post());
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Pages model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Pages model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
echo "here";
exit;
$model = new Pages();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
/**
* Updates an existing Pages model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Pages model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Pages model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Pages the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Pages::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
I am using Url as follows:
http://localhost/yii2-demo/backend/cms/pages/index
http://localhost/yii2-demo/backend/cms/pages/create
What Url(s) are you using?
For a module it should be:
?r=cms/pages/index,
?r=cms/pages/create
etc...
The only problem I can spot is on your $matchCallback attribute on the second AccessControl rule. It should use this signature
function ($rule, $action)
And it should return a boolean that indicates wheter this rule should be applied or not. In your case, you're saying that it should be applied to users that are not guests and that have the role '0'. You're also calling a redirect inside the function, and it doesn't return a boolean. See more info here http://www.yiiframework.com/doc-2.0/yii-filters-accessrule.html#$matchCallback-detail
Try to remove this attribute completely and see if you get a different result.