Commit 9744f0d3eb676bf48b8f64eb0c500905ae66bb9f

Authored by Yarik
2 parents 777eb8ff e4e181f1

Merge remote-tracking branch 'origin/master'

Showing 135 changed files with 10197 additions and 917 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 135 files are displayed.

backend/controllers/MenuController.php
... ... @@ -3,13 +3,11 @@
3 3 namespace backend\controllers;
4 4  
5 5 use Yii;
6   -use common\models\Menu;
  6 +use backend\models\Menu;
7 7 use backend\models\MenuSearch;
8 8 use yii\web\Controller;
9 9 use yii\web\NotFoundHttpException;
10 10 use yii\filters\VerbFilter;
11   -use common\models\TerminLang;
12   -use backend\models\SearchMenu;
13 11  
14 12 /**
15 13 * MenuController implements the CRUD actions for Menu model.
... ... @@ -34,7 +32,7 @@ class MenuController extends Controller
34 32 */
35 33 public function actionIndex()
36 34 {
37   - $searchModel = new SearchMenu();
  35 + $searchModel = new MenuSearch();
38 36 $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
39 37  
40 38 return $this->render('index', [
... ... @@ -64,32 +62,11 @@ class MenuController extends Controller
64 62 {
65 63 $model = new Menu();
66 64  
67   - $menu = yii::$app->db->createCommand('
68   - SELECT *
69   - FROM menu
70   - LEFT JOIN termin_lang ON termin_lang.termin_id = menu.termin_id
71   - ')->queryAll();
72   -
73   -
74   - $termin = TerminLang::find()->all();
75   -
76   - if ($model->load(Yii::$app->request->post())) {
77   -
78   - if($model->menu_pid == null)
79   - {
80   - $model->menu_pid = 0;
81   - }
82   -
83   -
84   - $model->save();
85   -
86   -
  65 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
87 66 return $this->redirect(['view', 'id' => $model->menu_id]);
88 67 } else {
89 68 return $this->render('create', [
90 69 'model' => $model,
91   - 'termin' => $termin,
92   - 'menu' => $menu,
93 70 ]);
94 71 }
95 72 }
... ... @@ -103,22 +80,12 @@ class MenuController extends Controller
103 80 public function actionUpdate($id)
104 81 {
105 82 $model = $this->findModel($id);
106   - $menu = yii::$app->db->createCommand('
107   - SELECT *
108   - FROM menu
109   - LEFT JOIN termin_lang ON termin_lang.termin_id = menu.termin_id
110   - ')->queryAll() + ['termin_id' => 0, 'termin_title' => 'ROOT'];
111   -
112   -
113   - $termin = TerminLang::find()->all();
114 83  
115 84 if ($model->load(Yii::$app->request->post()) && $model->save()) {
116 85 return $this->redirect(['view', 'id' => $model->menu_id]);
117 86 } else {
118 87 return $this->render('update', [
119 88 'model' => $model,
120   - 'termin' => $termin,
121   - 'menu' => $menu,
122 89 ]);
123 90 }
124 91 }
... ...
backend/controllers/CatalogController.php renamed to backend/controllers/MenuLocationController.php
... ... @@ -3,17 +3,16 @@
3 3 namespace backend\controllers;
4 4  
5 5 use Yii;
6   -use common\models\Catalog;
7   -use backend\models\SearchCatalog;
  6 +use backend\models\MenuLocation;
  7 +use backend\models\MenuSearchLocation;
8 8 use yii\web\Controller;
9 9 use yii\web\NotFoundHttpException;
10 10 use yii\filters\VerbFilter;
11   -use common\models\CatalogLang;
12 11  
13 12 /**
14   - * CatalogController implements the CRUD actions for Catalog model.
  13 + * MenuLocationController implements the CRUD actions for MenuLocation model.
15 14 */
16   -class CatalogController extends Controller
  15 +class MenuLocationController extends Controller
17 16 {
18 17 public function behaviors()
19 18 {
... ... @@ -28,12 +27,12 @@ class CatalogController extends Controller
28 27 }
29 28  
30 29 /**
31   - * Lists all Catalog models.
  30 + * Lists all MenuLocation models.
32 31 * @return mixed
33 32 */
34 33 public function actionIndex()
35 34 {
36   - $searchModel = new SearchCatalog();
  35 + $searchModel = new MenuSearchLocation();
37 36 $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
38 37  
39 38 return $this->render('index', [
... ... @@ -43,7 +42,7 @@ class CatalogController extends Controller
43 42 }
44 43  
45 44 /**
46   - * Displays a single Catalog model.
  45 + * Displays a single MenuLocation model.
47 46 * @param integer $id
48 47 * @return mixed
49 48 */
... ... @@ -55,20 +54,17 @@ class CatalogController extends Controller
55 54 }
56 55  
57 56 /**
58   - * Creates a new Catalog model.
  57 + * Creates a new MenuLocation model.
59 58 * If creation is successful, the browser will be redirected to the 'view' page.
60 59 * @return mixed
61 60 */
62 61 public function actionCreate()
63 62 {
64   - $model = new Catalog();
  63 + $model = new MenuLocation();
65 64  
66   - if ($model->load(Yii::$app->request->post()) && $model->save())
67   - {
68   - return $this->redirect(['view', 'id' => $model->id]);
69   - }
70   - else
71   - {
  65 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  66 + return $this->redirect(['view', 'id' => $model->menu_location_id]);
  67 + } else {
72 68 return $this->render('create', [
73 69 'model' => $model,
74 70 ]);
... ... @@ -76,7 +72,7 @@ class CatalogController extends Controller
76 72 }
77 73  
78 74 /**
79   - * Updates an existing Catalog model.
  75 + * Updates an existing MenuLocation model.
80 76 * If update is successful, the browser will be redirected to the 'view' page.
81 77 * @param integer $id
82 78 * @return mixed
... ... @@ -84,21 +80,10 @@ class CatalogController extends Controller
84 80 public function actionUpdate($id)
85 81 {
86 82 $model = $this->findModel($id);
87   - $model_lang = CatalogLang::find()
88   - ->where(['catalog_id' => $id, 'lang_id' => 1])
89   - ->one();
90 83  
91   - if ($model->load(Yii::$app->request->post()))
92   - {
93   - $model_lang->title = $model->title;
94   -
95   - $model->save();
96   - $model_lang->save();
97   -
98   - return $this->redirect(['view', 'id' => $model->id]);
99   - }
100   - else
101   - {
  84 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  85 + return $this->redirect(['view', 'id' => $model->menu_location_id]);
  86 + } else {
102 87 return $this->render('update', [
103 88 'model' => $model,
104 89 ]);
... ... @@ -106,7 +91,7 @@ class CatalogController extends Controller
106 91 }
107 92  
108 93 /**
109   - * Deletes an existing Catalog model.
  94 + * Deletes an existing MenuLocation model.
110 95 * If deletion is successful, the browser will be redirected to the 'index' page.
111 96 * @param integer $id
112 97 * @return mixed
... ... @@ -119,20 +104,17 @@ class CatalogController extends Controller
119 104 }
120 105  
121 106 /**
122   - * Finds the Catalog model based on its primary key value.
  107 + * Finds the MenuLocation model based on its primary key value.
123 108 * If the model is not found, a 404 HTTP exception will be thrown.
124 109 * @param integer $id
125   - * @return Catalog the loaded model
  110 + * @return MenuLocation the loaded model
126 111 * @throws NotFoundHttpException if the model cannot be found
127 112 */
128 113 protected function findModel($id)
129 114 {
130   - if (($model = Catalog::findOne($id)) !== null)
131   - {
  115 + if (($model = MenuLocation::findOne($id)) !== null) {
132 116 return $model;
133   - }
134   - else
135   - {
  117 + } else {
136 118 throw new NotFoundHttpException('The requested page does not exist.');
137 119 }
138 120 }
... ...
backend/controllers/TerminController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use Yii;
  6 +use backend\models\Termin;
  7 +use backend\models\TerminSearch;
  8 +use yii\web\Controller;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +use backend\models\TerminLang;
  12 +use backend\models\TerminStructure;
  13 +
  14 +/**
  15 + * TerminController implements the CRUD actions for Termin model.
  16 + */
  17 +class TerminController extends Controller
  18 +{
  19 + public function behaviors()
  20 + {
  21 + return [
  22 + 'access' => [
  23 + 'class' => AccessControl::className(),
  24 + 'except' => ['login', 'error', 'index', 'create', 'update'],
  25 + 'rules' => [
  26 + [
  27 + 'allow' => true,
  28 + 'roles' => ['admin']
  29 + ],
  30 + ],
  31 + ],
  32 + 'verbs' => [
  33 + 'class' => VerbFilter::className(),
  34 + 'actions' => [
  35 + 'logout' => ['post'],
  36 + 'delete-req' => ['post']
  37 + ],
  38 + ],
  39 + ];
  40 + }
  41 +
  42 + /**
  43 + * Lists all Termin models.
  44 + * @return mixed
  45 + */
  46 + public function actionIndex()
  47 + {
  48 + $searchModel = new TerminSearch();
  49 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  50 +
  51 + return $this->render('index', [
  52 + 'searchModel' => $searchModel,
  53 + 'dataProvider' => $dataProvider,
  54 + ]);
  55 + }
  56 +
  57 + /**
  58 + * Displays a single Termin model.
  59 + * @param integer $id
  60 + * @return mixed
  61 + */
  62 + public function actionView($id)
  63 + {
  64 + return $this->render('view', [
  65 + 'model' => $this->findModel($id),
  66 + ]);
  67 + }
  68 +
  69 + /**
  70 + * Creates a new Termin model.
  71 + * If creation is successful, the browser will be redirected to the 'view' page.
  72 + * @return mixed
  73 + */
  74 + public function actionCreate()
  75 + {
  76 + $model = new Termin();
  77 + $model_lang = new TerminLang();
  78 +
  79 + if ($model->load(Yii::$app->request->post())
  80 + && $model_lang->load(Yii::$app->request->post()))
  81 + {
  82 + $model->save();
  83 + $model_lang->termin_id = $model->termin_id;
  84 + $model_lang->save();
  85 +
  86 + return $this->redirect(['view', 'id' => $model->termin_id]);
  87 + }
  88 + else
  89 + {
  90 + return $this->render('create', [
  91 + 'model' => $model,
  92 + 'model_lang' => $model_lang,
  93 + ]);
  94 + }
  95 + }
  96 +
  97 + /**
  98 + * Updates an existing Termin model.
  99 + * If update is successful, the browser will be redirected to the 'view' page.
  100 + * @param integer $id
  101 + * @return mixed
  102 + */
  103 + public function actionUpdate($id)
  104 + {
  105 + $model = $this->findModel($id);
  106 + $model_lang = TerminLang::findOne($id);
  107 + $model_pid = TerminStructure::findOne($id)->getRelation('terminPid')->one();
  108 +
  109 + //var_dump(Yii::$app->request->post());
  110 + //var_dump($model_pid->termin->termin_id); die;
  111 +
  112 + if ($model->load(Yii::$app->request->post())
  113 + && $model_lang->load(Yii::$app->request->post())
  114 + && $model_pid->load(Yii::$app->request->post())
  115 + )
  116 + {
  117 + $model->save();
  118 + $model_lang->save();
  119 + $model_pid->termin_pid = $model_pid->termin->termin_id;
  120 +
  121 + return $this->redirect(['view', 'id' => $model->termin_id]);
  122 + }
  123 + else
  124 + {
  125 + return $this->render('update', [
  126 + 'model' => $model,
  127 + 'model_lang' => $model_lang,
  128 + 'model_pid' => $model_pid,
  129 + ]);
  130 + }
  131 + }
  132 +
  133 + /**
  134 + * Deletes an existing Termin model.
  135 + * If deletion is successful, the browser will be redirected to the 'index' page.
  136 + * @param integer $id
  137 + * @return mixed
  138 + */
  139 + public function actionDelete($id)
  140 + {
  141 + $this->findModel($id)->delete();
  142 +
  143 + return $this->redirect(['index']);
  144 + }
  145 +
  146 + /**
  147 + * Finds the Termin model based on its primary key value.
  148 + * If the model is not found, a 404 HTTP exception will be thrown.
  149 + * @param integer $id
  150 + * @return Termin the loaded model
  151 + * @throws NotFoundHttpException if the model cannot be found
  152 + */
  153 + protected function findModel($id)
  154 + {
  155 + if (($model = Termin::findOne($id)) !== null) {
  156 + return $model;
  157 + } else {
  158 + throw new NotFoundHttpException('The requested page does not exist.');
  159 + }
  160 + }
  161 +}
... ...
common/models/Menu.php renamed to backend/models/Menu.php
1 1 <?php
2 2  
3   -namespace common\models;
  3 +namespace backend\models;
4 4  
5 5 use Yii;
6   -
7 6  
8 7 /**
9 8 * This is the model class for table "menu".
10 9 *
11 10 * @property integer $menu_id
12 11 * @property integer $menu_pid
13   - * @property integer $menu_lft
14   - * @property integer $menu_rgt
  12 + * @property integer $level
15 13 * @property integer $termin_id
16 14 * @property integer $show
  15 + * @property integer $is_open
  16 + * @property integer $menu_location_id
17 17 * @property integer $sortorder
  18 + * @property string $name
  19 + * @property string $url
  20 + *
  21 + * @property Termin $termin
18 22 */
19 23 class Menu extends \yii\db\ActiveRecord
20   -{
21   - public function getMenuList ($location_name)
22   - {
23   - return yii::$app->db->createCommand('
24   - SELECT
25   - menu.menu_id, menu.menu_pid, menu.level,
26   - termin_lang.termin_title, termin_lang.termin_alias
27   - FROM menu
28   - INNER JOIN menu_location ON menu_location.menu_location_id = menu.menu_location_id
29   - AND menu_location.menu_location_name = \''.$location_name.'\'
30   - INNER JOIN termin ON termin.termin_id = menu.termin_id
31   - INNER JOIN termin_lang ON termin_lang.termin_id = menu.termin_id
32   - AND termin_lang.lang_id = '.Yii::$app->params['lang_id'].'
33   - ORDER BY menu.level ASC, menu.sortorder ASC
34   - ')->queryAll();
35   -/*
36   - return $this->find()
37   - ->selectOption('termin_lang.termin_title')
38   - ->from('menu')
39   - ->join(
40   - 'INNER JOIN',
41   - 'termin_lang.termin_id = menu.termin_id',
42   - ['lang_id' => yii::$app->params['lang_id']])
43   - ->all();
44   -*/
45   - }
46   -
47   - // ==== YII ====
48   -
  24 +{
49 25 /**
50 26 * @inheritdoc
51 27 */
... ... @@ -60,8 +36,9 @@ class Menu extends \yii\db\ActiveRecord
60 36 public function rules()
61 37 {
62 38 return [
63   - [['menu_pid', 'menu_lft', 'menu_rgt', 'termin_id', 'show', 'sortorder'], 'safe'],
64   - [['menu_pid', 'menu_lft', 'menu_rgt', 'termin_id', 'show', 'sortorder'], 'integer']
  39 + [['menu_id', 'menu_pid', 'level', 'termin_id', 'show', 'is_open', 'menu_location_id', 'sortorder'], 'required'],
  40 + [['menu_id', 'menu_pid', 'level', 'termin_id', 'show', 'is_open', 'menu_location_id', 'sortorder'], 'integer'],
  41 + [['name', 'url'], 'string', 'max' => 250]
65 42 ];
66 43 }
67 44  
... ... @@ -73,12 +50,48 @@ class Menu extends \yii\db\ActiveRecord
73 50 return [
74 51 'menu_id' => Yii::t('app', 'Menu ID'),
75 52 'menu_pid' => Yii::t('app', 'Menu Pid'),
76   - 'menu_lft' => Yii::t('app', 'Menu Lft'),
77   - 'menu_rgt' => Yii::t('app', 'Menu Rgt'),
  53 + 'level' => Yii::t('app', 'Level'),
78 54 'termin_id' => Yii::t('app', 'Termin ID'),
79 55 'show' => Yii::t('app', 'Show'),
  56 + 'is_open' => Yii::t('app', 'Is Open'),
  57 + 'menu_location_id' => Yii::t('app', 'Menu Location ID'),
80 58 'sortorder' => Yii::t('app', 'Sortorder'),
  59 + 'name' => Yii::t('app', 'Name'),
  60 + 'url' => Yii::t('app', 'Url'),
81 61 ];
82 62 }
83   -
  63 +
  64 + /**
  65 + * @return \yii\db\ActiveQuery
  66 + */
  67 + public function getTermin()
  68 + {
  69 + return $this->hasOne(Termin::className(), ['termin_id' => 'termin_id']);
  70 + }
  71 +
  72 + public function getMenuList ($location_name)
  73 + {
  74 + return yii::$app->db->createCommand('
  75 + SELECT
  76 + menu.menu_id, menu.menu_pid, menu.level,
  77 + termin_lang.termin_title, termin_lang.termin_alias
  78 + FROM menu
  79 + INNER JOIN menu_location ON menu_location.menu_location_id = menu.menu_location_id
  80 + AND menu_location.menu_location_name = \''.$location_name.'\'
  81 + INNER JOIN termin ON termin.termin_id = menu.termin_id
  82 + INNER JOIN termin_lang ON termin_lang.termin_id = menu.termin_id
  83 + AND termin_lang.lang_id = '.Yii::$app->params['lang_id'].'
  84 + ORDER BY menu.level ASC, menu.sortorder ASC
  85 + ')->queryAll();
  86 +/*
  87 + return $this->find()
  88 + ->selectOption('termin_lang.termin_title')
  89 + ->from('menu')
  90 + ->join(
  91 + 'INNER JOIN',
  92 + 'termin_lang.termin_id = menu.termin_id',
  93 + ['lang_id' => yii::$app->params['lang_id']])
  94 + ->all();
  95 + */
  96 + }
84 97 }
... ...
backend/models/MenuLocation.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "menu_location".
  9 + *
  10 + * @property integer $menu_location_id
  11 + * @property string $menu_location_name
  12 + *
  13 + * @property MenuLocationLang[] $menuLocationLangs
  14 + * @property Language[] $langs
  15 + */
  16 +class MenuLocation extends \yii\db\ActiveRecord
  17 +{
  18 + /**
  19 + * @inheritdoc
  20 + */
  21 + public static function tableName()
  22 + {
  23 + return 'menu_location';
  24 + }
  25 +
  26 + /**
  27 + * @inheritdoc
  28 + */
  29 + public function rules()
  30 + {
  31 + return [
  32 + [['menu_location_id'], 'required'],
  33 + [['menu_location_id'], 'integer'],
  34 + [['menu_location_name'], 'string', 'max' => 250]
  35 + ];
  36 + }
  37 +
  38 + /**
  39 + * @inheritdoc
  40 + */
  41 + public function attributeLabels()
  42 + {
  43 + return [
  44 + 'menu_location_id' => Yii::t('app', 'Menu Location ID'),
  45 + 'menu_location_name' => Yii::t('app', 'Menu Location Name'),
  46 + ];
  47 + }
  48 +
  49 + /**
  50 + * @return \yii\db\ActiveQuery
  51 + */
  52 + public function getMenuLocationLangs()
  53 + {
  54 + return $this->hasMany(MenuLocationLang::className(), ['menu_location_id' => 'menu_location_id']);
  55 + }
  56 +
  57 + /**
  58 + * @return \yii\db\ActiveQuery
  59 + */
  60 + public function getLangs()
  61 + {
  62 + return $this->hasMany(Language::className(), ['language_id' => 'lang_id'])->viaTable('menu_location_lang', ['menu_location_id' => 'menu_location_id']);
  63 + }
  64 +}
... ...
backend/models/MenuLocationLang.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "menu_location_lang".
  9 + *
  10 + * @property integer $menu_location_id
  11 + * @property string $menu_location_title
  12 + * @property integer $lang_id
  13 + *
  14 + * @property Language $lang
  15 + * @property MenuLocation $menuLocation
  16 + */
  17 +class MenuLocationLang extends \yii\db\ActiveRecord
  18 +{
  19 + /**
  20 + * @inheritdoc
  21 + */
  22 + public static function tableName()
  23 + {
  24 + return 'menu_location_lang';
  25 + }
  26 +
  27 + /**
  28 + * @inheritdoc
  29 + */
  30 + public function rules()
  31 + {
  32 + return [
  33 + [['menu_location_id', 'menu_location_title', 'lang_id'], 'required'],
  34 + [['menu_location_id', 'lang_id'], 'integer'],
  35 + [['menu_location_title'], 'string', 'max' => 250]
  36 + ];
  37 + }
  38 +
  39 + /**
  40 + * @inheritdoc
  41 + */
  42 + public function attributeLabels()
  43 + {
  44 + return [
  45 + 'menu_location_id' => Yii::t('app', 'Menu Location ID'),
  46 + 'menu_location_title' => Yii::t('app', 'Menu Location Title'),
  47 + 'lang_id' => Yii::t('app', 'Lang ID'),
  48 + ];
  49 + }
  50 +
  51 + /**
  52 + * @return \yii\db\ActiveQuery
  53 + */
  54 + public function getLang()
  55 + {
  56 + return $this->hasOne(Language::className(), ['language_id' => 'lang_id']);
  57 + }
  58 +
  59 + /**
  60 + * @return \yii\db\ActiveQuery
  61 + */
  62 + public function getMenuLocation()
  63 + {
  64 + return $this->hasOne(MenuLocation::className(), ['menu_location_id' => 'menu_location_id']);
  65 + }
  66 +}
... ...
backend/models/TerminLangSearch.php renamed to backend/models/MenuLocationSearch.php
... ... @@ -5,12 +5,12 @@ namespace backend\models;
5 5 use Yii;
6 6 use yii\base\Model;
7 7 use yii\data\ActiveDataProvider;
8   -use common\models\TerminLang;
  8 +use backend\models\MenuLocation;
9 9  
10 10 /**
11   - * TerminLangSearch represents the model behind the search form about `common\models\TerminLang`.
  11 + * MenuLocationSearch represents the model behind the search form about `backend\models\MenuLocation`.
12 12 */
13   -class TerminLangSearch extends TerminLang
  13 +class MenuLocationSearch extends MenuLocation
14 14 {
15 15 /**
16 16 * @inheritdoc
... ... @@ -18,8 +18,8 @@ class TerminLangSearch extends TerminLang
18 18 public function rules()
19 19 {
20 20 return [
21   - [['termin_id', 'lang_id'], 'integer'],
22   - [['termin_title'], 'safe'],
  21 + [['menu_location_id'], 'integer'],
  22 + [['menu_location_name'], 'safe'],
23 23 ];
24 24 }
25 25  
... ... @@ -41,7 +41,7 @@ class TerminLangSearch extends TerminLang
41 41 */
42 42 public function search($params)
43 43 {
44   - $query = TerminLang::find();
  44 + $query = MenuLocation::find();
45 45  
46 46 $dataProvider = new ActiveDataProvider([
47 47 'query' => $query,
... ... @@ -56,11 +56,10 @@ class TerminLangSearch extends TerminLang
56 56 }
57 57  
58 58 $query->andFilterWhere([
59   - 'termin_id' => $this->termin_id,
60   - 'lang_id' => $this->lang_id,
  59 + 'menu_location_id' => $this->menu_location_id,
61 60 ]);
62 61  
63   - $query->andFilterWhere(['like', 'termin_title', $this->termin_title]);
  62 + $query->andFilterWhere(['like', 'menu_location_name', $this->menu_location_name]);
64 63  
65 64 return $dataProvider;
66 65 }
... ...
backend/models/SearchMenu.php renamed to backend/models/MenuSearch.php
... ... @@ -5,12 +5,12 @@ namespace backend\models;
5 5 use Yii;
6 6 use yii\base\Model;
7 7 use yii\data\ActiveDataProvider;
8   -use common\models\Menu;
  8 +use backend\models\Menu;
9 9  
10 10 /**
11   - * SearchMenu represents the model behind the search form about `common\models\Menu`.
  11 + * MenuSearch represents the model behind the search form about `backend\models\Menu`.
12 12 */
13   -class SearchMenu extends Menu
  13 +class MenuSearch extends Menu
14 14 {
15 15 /**
16 16 * @inheritdoc
... ... @@ -18,7 +18,8 @@ class SearchMenu extends Menu
18 18 public function rules()
19 19 {
20 20 return [
21   - [['menu_id', 'menu_pid', 'menu_lft', 'menu_rgt', 'termin_id', 'show', 'sortorder'], 'integer'],
  21 + [['menu_id', 'menu_pid', 'level', 'termin_id', 'show', 'is_open', 'menu_location_id', 'sortorder'], 'integer'],
  22 + [['name', 'url'], 'safe'],
22 23 ];
23 24 }
24 25  
... ... @@ -57,13 +58,17 @@ class SearchMenu extends Menu
57 58 $query->andFilterWhere([
58 59 'menu_id' => $this->menu_id,
59 60 'menu_pid' => $this->menu_pid,
60   - 'menu_lft' => $this->menu_lft,
61   - 'menu_rgt' => $this->menu_rgt,
  61 + 'level' => $this->level,
62 62 'termin_id' => $this->termin_id,
63 63 'show' => $this->show,
  64 + 'is_open' => $this->is_open,
  65 + 'menu_location_id' => $this->menu_location_id,
64 66 'sortorder' => $this->sortorder,
65 67 ]);
66 68  
  69 + $query->andFilterWhere(['like', 'name', $this->name])
  70 + ->andFilterWhere(['like', 'url', $this->url]);
  71 +
67 72 return $dataProvider;
68 73 }
69 74 }
... ...
backend/models/SearchCatalog.php deleted
1   -<?php
2   -
3   -namespace backend\models;
4   -
5   -use Yii;
6   -use yii\base\Model;
7   -use yii\data\ActiveDataProvider;
8   -use common\models\Catalog;
9   -
10   -/**
11   - * SearchCatalog represents the model behind the search form about `common\models\Catalog`.
12   - */
13   -class SearchCatalog extends Catalog
14   -{
15   - /**
16   - * для поиска
17   - * @var $title
18   - */
19   - var $title;
20   -
21   - /**
22   - * @inheritdoc
23   - */
24   - public function rules()
25   - {
26   - return [
27   - [['catalog_id', 'parent_id', 'status', 'sort'], 'integer'],
28   - // + поиск по title
29   - [['title'], 'safe']
30   - ];
31   - }
32   -
33   - /**
34   - * @inheritdoc
35   - */
36   - public function scenarios()
37   - {
38   - // bypass scenarios() implementation in the parent class
39   - return Model::scenarios();
40   - }
41   -
42   - /**
43   - * Creates data provider instance with search query applied
44   - *
45   - * @param array $params
46   - *
47   - * @return ActiveDataProvider
48   - */
49   - public function search($params)
50   - {
51   - $query = Catalog::find();
52   -
53   - $dataProvider = new ActiveDataProvider([
54   - 'query' => $query,
55   - ]);
56   -
57   - // + поиск по title
58   - $dataProvider->setSort([
59   - 'attributes' => [
60   - 'catalog_id',
61   - 'title' => [
62   - 'asc' => ['title' => SORT_ASC],
63   - 'desc' => ['title' => SORT_DESC],
64   - 'label' => 'title',
65   - 'default' => SORT_ASC
66   - ]
67   - ]
68   - ]);
69   -
70   - $this->load($params);
71   -
72   - // + поиск по title
73   - $query->joinWith(['relationCatalogLangPlus']);
74   -
75   - if (!$this->validate())
76   - {
77   - // uncomment the following line if you do not want to return any records when validation fails
78   - // $query->where('0=1');
79   -
80   - return $dataProvider;
81   - }
82   -
83   - $query->andFilterWhere([
84   - 'catalog_id' => $this->catalog_id,
85   - 'parent_id' => $this->parent_id,
86   - 'status' => $this->status,
87   - 'sort' => $this->sort,
88   - ]);
89   -
90   - $query->andFilterWhere(['like', 'cover', $this->cover]);
91   -
92   - // + поиск по title
93   - if (! empty ($this->title))
94   - {
95   - $query->joinWith(['relationCatalogLangPlus' => function ($q)
96   - {
97   - $q->where(['like', 'catalog_i18n.title', $this->title]);
98   - }]);
99   - }
100   -
101   - return $dataProvider;
102   - }
103   -}
backend/models/SearchPage.php deleted
1   -<?php
2   -
3   -namespace backend\models;
4   -
5   -use yii\base\Model;
6   -use yii\data\ActiveDataProvider;
7   -use common\models\Page;
8   -
9   -
10   -/**
11   - * SearchPage represents the model behind the search form about `common\models\Page`.
12   - */
13   -class SearchPage extends Page
14   -{
15   - /**
16   - * @inheritdoc
17   - */
18   - public function rules()
19   - {
20   - return [
21   - [['page_id', 'template_id', 'image_id', 'show'], 'integer'],
22   - [['date_add'], 'safe'],
23   - ];
24   - }
25   -
26   - /**
27   - * @inheritdoc
28   - */
29   - public function scenarios()
30   - {
31   - // bypass scenarios() implementation in the parent class
32   - return Model::scenarios();
33   - }
34   -
35   -
36   - /**
37   - * Creates data provider instance with search query applied
38   - *
39   - * @param array $params
40   - *
41   - * @return ActiveDataProvider
42   - */
43   - public function search($params)
44   - {
45   - $query = Page::find();
46   -
47   - $dataProvider = new ActiveDataProvider([
48   - 'query' => $query,
49   - ]);
50   -
51   - $this->load($params);
52   -
53   - if (!$this->validate()) {
54   - // uncomment the following line if you do not want to return any records when validation fails
55   - // $query->where('0=1');
56   - return $dataProvider;
57   - }
58   -
59   - $query->andFilterWhere([
60   - 'page_id' => $this->page_id,
61   - 'date_add' => $this->date_add,
62   - 'template_id' => $this->template_id,
63   - 'image_id' => $this->image_id,
64   - 'show' => $this->show,
65   - ]);
66   -
67   - return $dataProvider;
68   - }
69   -}
backend/models/Termin.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +use common\models\Tools;
  7 +
  8 +/**
  9 + * This is the model class for table "termin".
  10 + *
  11 + * @property integer $termin_id
  12 + * @property string $termin_name
  13 + * @property integer $is_book
  14 + *
  15 + * @property Menu[] $menus
  16 + * @property TerminLang[] $terminLangs
  17 + * @property Language[] $langs
  18 + * @property TerminStructure[] $terminStructures
  19 + */
  20 +class Termin extends \yii\db\ActiveRecord
  21 +{
  22 + var $termin_title;
  23 + var $termin_pid;
  24 +
  25 + /**
  26 + * @inheritdoc
  27 + */
  28 + public static function tableName()
  29 + {
  30 + return 'termin';
  31 + }
  32 +
  33 + /**
  34 + * @inheritdoc
  35 + */
  36 + public function rules()
  37 + {
  38 + return [
  39 + [['is_book'], 'integer'],
  40 + [['termin_pid'], 'safe'],
  41 + [['termin_title'], 'string', 'max' => 250],
  42 + [['termin_name'], 'string', 'max' => 250]
  43 + ];
  44 + }
  45 +
  46 + /**
  47 + * @inheritdoc
  48 + */
  49 + public function attributeLabels()
  50 + {
  51 + return [
  52 + 'termin_id' => Yii::t('app', 'termin'),
  53 + 'termin_name' => Yii::t('app', 'name').' (SYSTEM NAME)',
  54 + 'is_book' => Yii::t('app', 'book'),
  55 + ];
  56 + }
  57 +
  58 + /**
  59 + * Выполняет поиск по параметрам
  60 + * @param array $param принимает [termin_id, lang_id, return_one, return_field, show_all]
  61 + * @return array one | array all | string значение масива
  62 + */
  63 + public function finInfo (array $params = [])
  64 + {
  65 + Tools::ifNotExist ($params, array (
  66 + 'termin_id' => false,
  67 + 'termin_pid' => false,
  68 + 'lang_id' => Yii::$app->params['lang_id'],
  69 + 'return_one' => false,
  70 + 'return_field' => false,
  71 + 'show_all' => false,
  72 + 'to_array' => true,
  73 + 'pid_title' => false,
  74 + ));
  75 +
  76 + $WHERE = $SELECT = array ();
  77 +
  78 + $model = new self();
  79 +
  80 + $SELECT[] = 'termin.*';
  81 + $query = $model->find();
  82 +
  83 + if ($params['termin_id'])
  84 + {
  85 + $WHERE['termin.termin_id'] = $params['termin_id'];
  86 + }
  87 +
  88 + // перевод
  89 + $SELECT[] = 'termin_lang.*';
  90 + $query->join(
  91 + 'INNER JOIN', 'termin_lang',
  92 + 'termin.termin_id = termin_lang.termin_id'
  93 + );
  94 +
  95 + if ($params['lang_id'])
  96 + {
  97 + $WHERE['termin_lang.lang_id'] = $params['lang_id'];
  98 + }
  99 +
  100 + // структура
  101 + $SELECT[] = 'termin_structure.*';
  102 + $query->join(
  103 + 'INNER JOIN', 'termin_structure',
  104 + 'termin.termin_id = termin_structure.termin_id'
  105 + );
  106 +
  107 + if ($params['termin_pid'] !== false)
  108 + {
  109 + $WHERE['termin_structure.termin_pid'] = $params['termin_pid'];
  110 + }
  111 +
  112 + if ($params['pid_title'])
  113 + {
  114 + $SELECT[] = 'termin_pid_lang.termin_title as termin_pid_title';
  115 + $query->join(
  116 + 'LEFT JOIN', 'termin_lang as termin_pid_lang',
  117 + 'termin_pid_lang.termin_id = termin_structure.termin_pid'
  118 + );
  119 + }
  120 +
  121 + // SELECT
  122 + if (! empty ($SELECT))
  123 + {
  124 + $query->select($SELECT);
  125 + }
  126 +
  127 + // WHERE
  128 + if (! empty ($WHERE))
  129 + {
  130 + $query->where($WHERE);
  131 + }
  132 +
  133 + if ($params['to_array'])
  134 + {
  135 + $query = $query->asArray();
  136 + }
  137 +
  138 + if ($params['return_one'] || $params['return_field'])
  139 + {
  140 +
  141 + $result = $params['return_field'] ? $query->one($params['return_field']) : $query->one();
  142 + }
  143 + else
  144 + {
  145 + $result = $query->all();
  146 + }
  147 +
  148 + return $result;
  149 + }
  150 +
  151 + /**
  152 + * @return \yii\db\ActiveQuery
  153 + */
  154 + public function getMenus()
  155 + {
  156 + return $this->hasMany(Menu::className(), ['termin_id' => 'termin_id']);
  157 + }
  158 +
  159 + /**
  160 + * @return \yii\db\ActiveQuery
  161 + */
  162 + public function getTerminLangs()
  163 + {
  164 + return $this->hasMany(TerminLang::className(), ['termin_id' => 'termin_id']);
  165 + }
  166 +
  167 + /**
  168 + * @return \yii\db\ActiveQuery
  169 + */
  170 + public function getLangs()
  171 + {
  172 + return $this->hasMany(Language::className(), ['language_id' => 'lang_id'])
  173 + ->viaTable('termin_lang', ['termin_id' => 'termin_id']);
  174 + }
  175 +
  176 + /**
  177 + * @return \yii\db\ActiveQuery
  178 + */
  179 + public function getTerminStructures()
  180 + {
  181 + return $this->hasMany(TerminStructure::className(), ['termin_id' => 'termin_id']);
  182 + }
  183 +
  184 +}
... ...
backend/models/TerminLang.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "termin_lang".
  9 + *
  10 + * @property integer $termin_id
  11 + * @property integer $lang_id
  12 + * @property string $termin_title
  13 + * @property string $termin_alias
  14 + *
  15 + * @property Language $lang
  16 + * @property Termin $termin
  17 + */
  18 +class TerminLang extends \yii\db\ActiveRecord
  19 +{
  20 + /**
  21 + * @inheritdoc
  22 + */
  23 + public static function tableName()
  24 + {
  25 + return 'termin_lang';
  26 + }
  27 +
  28 + /**
  29 + * @inheritdoc
  30 + */
  31 + public function rules()
  32 + {
  33 + return [
  34 + [['lang_id'], 'required'],
  35 + [['lang_id'], 'integer'],
  36 + [['termin_title', 'termin_alias'], 'string', 'max' => 250]
  37 + ];
  38 + }
  39 +
  40 + /**
  41 + * @inheritdoc
  42 + */
  43 + public function attributeLabels()
  44 + {
  45 + return [
  46 + 'termin_id' => Yii::t('app', 'Termin ID'),
  47 + 'lang_id' => Yii::t('app', 'Lang ID'),
  48 + 'termin_title' => Yii::t('app', 'Termin Title'),
  49 + 'termin_alias' => Yii::t('app', 'Termin Alias'),
  50 + ];
  51 + }
  52 +
  53 + /**
  54 + * @return \yii\db\ActiveQuery
  55 + */
  56 + public function getLang()
  57 + {
  58 + return $this->hasOne(Language::className(), ['language_id' => 'lang_id']);
  59 + }
  60 +
  61 + /**
  62 + * @return \yii\db\ActiveQuery
  63 + */
  64 + public function getTermin()
  65 + {
  66 + return $this->hasOne(Termin::className(), ['termin_id' => 'termin_id']);
  67 + }
  68 +}
... ...
common/models/CatalogLang.php renamed to backend/models/TerminRelation.php
1 1 <?php
2 2  
3   -namespace common\models;
  3 +namespace backend\models;
4 4  
5 5 use Yii;
6 6  
7 7 /**
8   - * This is the model class for table "catalog_i18n".
  8 + * This is the model class for table "termin_relation".
9 9 *
10   - * @property integer $catalog_id
11   - * @property integer $lang_id
12   - * @property string $title
13   - * @property string $alias
14   - * @property string $meta_title
15   - * @property string $meta_keywords
16   - * @property string $meta_description
17   - * @property string $full_alias
  10 + * @property integer $termin_id
  11 + * @property integer $termin_id_related
18 12 */
19   -class CatalogLang extends \yii\db\ActiveRecord
  13 +class TerminRelation extends \yii\db\ActiveRecord
20 14 {
21 15 /**
22 16 * @inheritdoc
23 17 */
24 18 public static function tableName()
25 19 {
26   - return 'catalog_i18n';
  20 + return 'termin_relation';
27 21 }
28 22  
29 23 /**
... ... @@ -32,12 +26,7 @@ class CatalogLang extends \yii\db\ActiveRecord
32 26 public function rules()
33 27 {
34 28 return [
35   - [['catalog_id', 'lang_id', 'title', 'alias'], 'required'],
36   - [['catalog_id', 'lang_id'], 'integer'],
37   - [['title'], 'string', 'max' => 1024],
38   - [['alias'], 'string', 'max' => 128],
39   - [['meta_title', 'meta_keywords', 'meta_description', 'full_alias'], 'string', 'max' => 255],
40   - [['alias', 'lang_id'], 'unique', 'targetAttribute' => ['alias', 'lang_id'], 'message' => 'The combination of Lang ID and Alias has already been taken.']
  29 + [['termin_id', 'termin_id_related'], 'integer']
41 30 ];
42 31 }
43 32  
... ... @@ -47,14 +36,8 @@ class CatalogLang extends \yii\db\ActiveRecord
47 36 public function attributeLabels()
48 37 {
49 38 return [
50   - 'catalog_id' => Yii::t('app', 'catalog_id'),
51   - 'lang_id' => Yii::t('app', 'Lang ID'),
52   - 'title' => Yii::t('app', 'Title'),
53   - 'alias' => Yii::t('app', 'Alias'),
54   - 'meta_title' => Yii::t('app', 'Meta Title'),
55   - 'meta_keywords' => Yii::t('app', 'Meta Keywords'),
56   - 'meta_description' => Yii::t('app', 'Meta Description'),
57   - 'full_alias' => Yii::t('app', 'Full Alias'),
  39 + 'termin_id' => Yii::t('app', 'Termin ID'),
  40 + 'termin_id_related' => Yii::t('app', 'Termin Id Related'),
58 41 ];
59   - }
  42 + }
60 43 }
... ...
backend/models/SearchTermin.php renamed to backend/models/TerminSearch.php
... ... @@ -5,12 +5,12 @@ namespace backend\models;
5 5 use Yii;
6 6 use yii\base\Model;
7 7 use yii\data\ActiveDataProvider;
8   -use common\models\Termin;
  8 +use backend\models\Termin;
9 9  
10 10 /**
11   - * SearchTermin represents the model behind the search form about `common\models\Termin`.
  11 + * TerminSearch represents the model behind the search form about `backend\models\Termin`.
12 12 */
13   -class SearchTermin extends Termin
  13 +class TerminSearch extends Termin
14 14 {
15 15 /**
16 16 * @inheritdoc
... ... @@ -18,7 +18,8 @@ class SearchTermin extends Termin
18 18 public function rules()
19 19 {
20 20 return [
21   - [['termin_id', 'termin_pid', 'lfr', 'rgt', 'termin_type_id', 'page_id'], 'integer'],
  21 + [['termin_id', 'is_book'], 'integer'],
  22 + [['termin_name'], 'safe'],
22 23 ];
23 24 }
24 25  
... ... @@ -56,13 +57,11 @@ class SearchTermin extends Termin
56 57  
57 58 $query->andFilterWhere([
58 59 'termin_id' => $this->termin_id,
59   - 'termin_pid' => $this->termin_pid,
60   - 'lfr' => $this->lfr,
61   - 'rgt' => $this->rgt,
62   - 'termin_type_id' => $this->termin_type_id,
63   - 'page_id' => $this->page_id,
  60 + 'is_book' => $this->is_book,
64 61 ]);
65 62  
  63 + $query->andFilterWhere(['like', 'termin_name', $this->termin_name]);
  64 +
66 65 return $dataProvider;
67 66 }
68 67 }
... ...
backend/models/TerminStructure.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "termin_structure".
  9 + *
  10 + * @property integer $termin_id
  11 + * @property integer $termin_pid
  12 + *
  13 + * @property Termin $termin
  14 + */
  15 +class TerminStructure extends \yii\db\ActiveRecord
  16 +{
  17 + /**
  18 + * @inheritdoc
  19 + */
  20 + public static function tableName()
  21 + {
  22 + return 'termin_structure';
  23 + }
  24 +
  25 + /**
  26 + * @inheritdoc
  27 + */
  28 + public function rules()
  29 + {
  30 + return [
  31 + [['termin_id', 'termin_pid'], 'required'],
  32 + [['termin_id', 'termin_pid'], 'integer']
  33 + ];
  34 + }
  35 +
  36 + /**
  37 + * @inheritdoc
  38 + */
  39 + public function attributeLabels()
  40 + {
  41 + return [
  42 + 'termin_id' => Yii::t('app', 'Termin ID'),
  43 + 'termin_pid' => Yii::t('app', 'Termin Pid'),
  44 + ];
  45 + }
  46 +
  47 + /**
  48 + * @return \yii\db\ActiveQuery
  49 + */
  50 + public function getTermin()
  51 + {
  52 + return $this->hasOne(Termin::className(), ['termin_id' => 'termin_id']);
  53 + }
  54 +
  55 + /**
  56 + * @return \yii\db\ActiveQuery
  57 + */
  58 + public function getTerminPid()
  59 + {
  60 + return $this->hasMany(TerminLang::className(), ['termin_id' => 'termin_pid']);
  61 + }
  62 +}
... ...
backend/views/catalog/_form.php deleted
1   -<?php
2   -
3   -use yii\helpers\Html;
4   -use yii\widgets\ActiveForm;
5   -use yii\helpers\ArrayHelper;
6   -use common\models\Catalog;
7   -
8   -/* @var $this yii\web\View */
9   -/* @var $model common\models\Catalog */
10   -/* @var $form yii\widgets\ActiveForm */
11   -?>
12   -
13   -<div class="catalog-form">
14   -
15   - <?php $form = ActiveForm::begin(); ?>
16   -
17   - <?= $form->field($model, 'title')->textInput() ?>
18   -
19   - <?= $form->field($model, 'parent_id')->dropDownList(
20   - ArrayHelper::map($model->find()->all(), 'parent_id', 'title')
21   - )
22   - ?>
23   -
24   - <?= $form->field($model, 'cover')->textInput(['maxlength' => true]) ?>
25   -
26   - <?= $form->field($model, 'status')->dropDownList([
27   - '1' => Yii::t('action', 'show'),
28   - '0' => Yii::t('action', 'hide'),
29   - ]);
30   -
31   - echo '<pre>';
32   -
33   - $array = $model->findInfo([
34   - 'catalog_id' => 1,
35   - 'return_one' => true,
36   - 'to_array' => false,
37   - ]);
38   -
39   - var_dump($array->relationCatalogLang2->title);
40   - //var_dump($array->relationCatalogLang2->title);
41   -
42   - echo '</pre>';
43   -
44   - ?>
45   -
46   - <?= $form->field($model, 'sort')->textInput() ?>
47   -
48   - <div class="form-group">
49   - <?= Html::submitButton($model->isNewRecord ? Yii::t('action', 'add') : Yii::t('action', 'update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
50   - </div>
51   -
52   - <?php ActiveForm::end(); ?>
53   -
54   -</div>
backend/views/layouts/left.php
... ... @@ -33,7 +33,7 @@
33 33 ['label' => 'Термины', 'icon' => 'fa fa-file-code-o', 'url' => ['/termin/']],
34 34 //['label' => Yii::t('app', 'Pages'), 'icon' => 'fa fa-file-code-o', 'url' => ['/page/']],
35 35 //['label' => 'Каталог', 'icon' => 'fa fa-file-code-o', 'url' => ['/catalog/']],
36   - //['label' => 'Меню', 'icon' => 'fa fa-file-code-o', 'url' => ['/menu/']],
  36 + ['label' => 'Меню', 'icon' => 'fa fa-file-code-o', 'url' => ['/menu/']],
37 37 ['label' => 'Заявки', 'icon' => 'fa fa-file-code-o', 'url' => ['/site/requests/']],
38 38 ['label' => 'Gii', 'icon' => 'fa fa-file-code-o', 'url' => ['/gii']],
39 39 ['label' => 'Debug', 'icon' => 'fa fa-dashboard', 'url' => ['/debug']],
... ...
backend/views/menu-location/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\MenuLocation */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="menu-location-form">
  12 +
  13 + <?php $form = ActiveForm::begin(); ?>
  14 +
  15 + <?= $form->field($model, 'menu_location_id')->textInput() ?>
  16 +
  17 + <?= $form->field($model, 'menu_location_name')->textInput(['maxlength' => true]) ?>
  18 +
  19 + <?= $form->field($model->menuLocationLangs[0], 'menu_location_title')->textInput() ?>
  20 +
  21 + <div class="form-group">
  22 + <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  23 + </div>
  24 +
  25 + <?php ActiveForm::end(); ?>
  26 +
  27 +</div>
... ...
backend/views/catalog/_search.php renamed to backend/views/menu-location/_search.php
... ... @@ -4,26 +4,20 @@ use yii\helpers\Html;
4 4 use yii\widgets\ActiveForm;
5 5  
6 6 /* @var $this yii\web\View */
7   -/* @var $model backend\models\SearchCatalog */
  7 +/* @var $model backend\models\MenuSearchLocation */
8 8 /* @var $form yii\widgets\ActiveForm */
9 9 ?>
10 10  
11   -<div class="catalog-search">
  11 +<div class="menu-location-search">
12 12  
13 13 <?php $form = ActiveForm::begin([
14 14 'action' => ['index'],
15 15 'method' => 'get',
16 16 ]); ?>
17 17  
18   - <?= $form->field($model, 'catalog_id') ?>
  18 + <?= $form->field($model, 'menu_location_id') ?>
19 19  
20   - <?= $form->field($model, 'parent_id') ?>
21   -
22   - <?= $form->field($model, 'cover') ?>
23   -
24   - <?php // echo $form->field($model, 'status') ?>
25   -
26   - <?php // echo $form->field($model, 'sort') ?>
  20 + <?= $form->field($model, 'menu_location_name') ?>
27 21  
28 22 <div class="form-group">
29 23 <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
... ...
backend/views/catalog/create.php renamed to backend/views/menu-location/create.php
... ... @@ -4,13 +4,13 @@ use yii\helpers\Html;
4 4  
5 5  
6 6 /* @var $this yii\web\View */
7   -/* @var $model common\models\Catalog */
  7 +/* @var $model backend\models\MenuLocation */
8 8  
9   -$this->title = Yii::t('app', 'Create Catalog');
10   -$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Catalogs'), 'url' => ['index']];
  9 +$this->title = Yii::t('app', 'Create Menu Location');
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Menu Locations'), 'url' => ['index']];
11 11 $this->params['breadcrumbs'][] = $this->title;
12 12 ?>
13   -<div class="catalog-create">
  13 +<div class="menu-location-create">
14 14  
15 15 <h1><?= Html::encode($this->title) ?></h1>
16 16  
... ...
backend/views/menu-location/index.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $searchModel backend\models\MenuLocation */
  8 +/* @var $dataProvider yii\data\ActiveDataProvider */
  9 +
  10 +$this->title = Yii::t('app', 'Menu Locations');
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="menu-location-index">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  17 +
  18 + <p>
  19 + <?= Html::a(Yii::t('app', 'Create').' '.Yii::t('app', 'location'), ['create'], ['class' => 'btn btn-success']) ?>
  20 + </p>
  21 +
  22 + <?= GridView::widget([
  23 + 'dataProvider' => $dataProvider,
  24 + 'filterModel' => $searchModel,
  25 + 'columns' => [
  26 + ['class' => 'yii\grid\SerialColumn'],
  27 +
  28 + 'menu_location_id',
  29 + 'menu_location_name',
  30 + [
  31 + 'attribute' => 'menu_location_title',
  32 + 'value' => function ($model)
  33 + {
  34 +
  35 + return $model->menuLocationLangs[0]->menu_location_title;
  36 + },
  37 + ],
  38 +
  39 + ['class' => 'yii\grid\ActionColumn'],
  40 + ],
  41 + ]); ?>
  42 +
  43 +</div>
... ...
backend/views/catalog/update.php renamed to backend/views/menu-location/update.php
... ... @@ -3,16 +3,16 @@
3 3 use yii\helpers\Html;
4 4  
5 5 /* @var $this yii\web\View */
6   -/* @var $model common\models\Catalog */
  6 +/* @var $model backend\models\MenuLocation */
7 7  
8 8 $this->title = Yii::t('app', 'Update {modelClass}: ', [
9   - 'modelClass' => 'Catalog',
10   -]) . ' ' . $model->catalog_id;
11   -$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Catalogs'), 'url' => ['index']];
12   -$this->params['breadcrumbs'][] = ['label' => $model->catalog_id, 'url' => ['view', 'id' => $model->catalog_id]];
  9 + 'modelClass' => 'Menu Location',
  10 +]) . ' ' . $model->menu_location_id;
  11 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Menu Locations'), 'url' => ['index']];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->menu_location_id, 'url' => ['view', 'id' => $model->menu_location_id]];
13 13 $this->params['breadcrumbs'][] = Yii::t('app', 'Update');
14 14 ?>
15   -<div class="catalog-update">
  15 +<div class="menu-location-update">
16 16  
17 17 <h1><?= Html::encode($this->title) ?></h1>
18 18  
... ...
backend/views/catalog/view.php renamed to backend/views/menu-location/view.php
... ... @@ -4,19 +4,19 @@ use yii\helpers\Html;
4 4 use yii\widgets\DetailView;
5 5  
6 6 /* @var $this yii\web\View */
7   -/* @var $model common\models\Catalog */
  7 +/* @var $model backend\models\MenuLocation */
8 8  
9   -$this->title = $model->catalog_id;
10   -$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Catalogs'), 'url' => ['index']];
  9 +$this->title = $model->menu_location_id;
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Menu Locations'), 'url' => ['index']];
11 11 $this->params['breadcrumbs'][] = $this->title;
12 12 ?>
13   -<div class="catalog-view">
  13 +<div class="menu-location-view">
14 14  
15 15 <h1><?= Html::encode($this->title) ?></h1>
16 16  
17 17 <p>
18   - <?= Html::a(Yii::t('app', 'Update'), ['update', 'catalog_id' => $model->catalog_id], ['class' => 'btn btn-primary']) ?>
19   - <?= Html::a(Yii::t('app', 'Delete'), ['delete', 'catalog_id' => $model->catalog_id], [
  18 + <?= Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->menu_location_id], ['class' => 'btn btn-primary']) ?>
  19 + <?= Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $model->menu_location_id], [
20 20 'class' => 'btn btn-danger',
21 21 'data' => [
22 22 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),
... ... @@ -28,11 +28,8 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
28 28 <?= DetailView::widget([
29 29 'model' => $model,
30 30 'attributes' => [
31   - 'catalog_id',
32   - 'parent_id',
33   - 'cover',
34   - 'status',
35   - 'sort',
  31 + 'menu_location_id',
  32 + 'menu_location_name',
36 33 ],
37 34 ]) ?>
38 35  
... ...
backend/views/menu/_form.php
... ... @@ -2,11 +2,9 @@
2 2  
3 3 use yii\helpers\Html;
4 4 use yii\widgets\ActiveForm;
5   -use yii\helpers\ArrayHelper;
6   -use kartik\select2\Select2;
7 5  
8 6 /* @var $this yii\web\View */
9   -/* @var $model common\models\Menu */
  7 +/* @var $model backend\models\Menu */
10 8 /* @var $form yii\widgets\ActiveForm */
11 9 ?>
12 10  
... ... @@ -14,33 +12,25 @@ use kartik\select2\Select2;
14 12  
15 13 <?php $form = ActiveForm::begin(); ?>
16 14  
17   -
18   -
19   - <?= $form->field($model, 'termin_id')->widget(Select2::classname(), [
20   - //'data' => $data,
21   - 'language' => 'ru',
22   - 'options' => ['placeholder' => 'под меню ...'],
23   - 'pluginOptions' => [
24   -
25   - ],
26   - 'data' => ArrayHelper::map($termin, 'termin_id', 'termin_title'), // data as array
27   - ]) ?>
28   -
29   - <?= $form->field($model, 'menu_pid')->widget(Select2::classname(), [
30   - //'data' => $data,
31   - 'language' => 'ru',
32   - 'options' => ['placeholder' => 'Меню родитель ...'],
33   - 'pluginOptions' => [
34   -
35   - ],
36   - 'data' => ArrayHelper::map($menu, 'termin_id', 'termin_title'), // data as array
37   - ]) ?>
38   -
39   -
40   -
41   - <?= $form->field($model, 'show')->dropDownList(['1' => Yii::t('action', 'show'), '0' => Yii::t('action', 'hide')]) ?>
42   -
43   - <?= $form->field($model, 'sortorder')->dropDownList(['1' => '1', '0' => '2']) ?>
  15 + <?= $form->field($model, 'menu_id')->textInput() ?>
  16 +
  17 + <?= $form->field($model, 'menu_pid')->textInput() ?>
  18 +
  19 + <?= $form->field($model, 'level')->textInput() ?>
  20 +
  21 + <?= $form->field($model, 'termin_id')->textInput() ?>
  22 +
  23 + <?= $form->field($model, 'show')->textInput() ?>
  24 +
  25 + <?= $form->field($model, 'is_open')->textInput() ?>
  26 +
  27 + <?= $form->field($model, 'menu_location_id')->textInput() ?>
  28 +
  29 + <?= $form->field($model, 'sortorder')->textInput() ?>
  30 +
  31 + <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
  32 +
  33 + <?= $form->field($model, 'url')->textInput(['maxlength' => true]) ?>
44 34  
45 35 <div class="form-group">
46 36 <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
... ...
backend/views/menu/_search.php
... ... @@ -19,16 +19,22 @@ use yii\widgets\ActiveForm;
19 19  
20 20 <?= $form->field($model, 'menu_pid') ?>
21 21  
22   - <?= $form->field($model, 'menu_lft') ?>
23   -
24   - <?= $form->field($model, 'menu_rgt') ?>
  22 + <?= $form->field($model, 'level') ?>
25 23  
26 24 <?= $form->field($model, 'termin_id') ?>
27 25  
28   - <?php // echo $form->field($model, 'show') ?>
  26 + <?= $form->field($model, 'show') ?>
  27 +
  28 + <?php // echo $form->field($model, 'is_open') ?>
  29 +
  30 + <?php // echo $form->field($model, 'menu_location_id') ?>
29 31  
30 32 <?php // echo $form->field($model, 'sortorder') ?>
31 33  
  34 + <?php // echo $form->field($model, 'name') ?>
  35 +
  36 + <?php // echo $form->field($model, 'url') ?>
  37 +
32 38 <div class="form-group">
33 39 <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
34 40 <?= Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-default']) ?>
... ...
backend/views/menu/create.php
... ... @@ -4,7 +4,7 @@ use yii\helpers\Html;
4 4  
5 5  
6 6 /* @var $this yii\web\View */
7   -/* @var $model common\models\Menu */
  7 +/* @var $model backend\models\Menu */
8 8  
9 9 $this->title = Yii::t('app', 'Create Menu');
10 10 $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Menus'), 'url' => ['index']];
... ... @@ -16,8 +16,6 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
16 16  
17 17 <?= $this->render('_form', [
18 18 'model' => $model,
19   - 'termin' => $termin,
20   - 'menu' => $menu,
21 19 ]) ?>
22 20  
23 21 </div>
... ...
backend/views/menu/index.php
... ... @@ -16,7 +16,8 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
16 16 <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
17 17  
18 18 <p>
19   - <?= Html::a(Yii::t('app', 'Create Menu'), ['create'], ['class' => 'btn btn-success']) ?>
  19 + <?= Html::a(Yii::t('app', 'Create').' '.Yii::t('app', 'menu'), ['create'], ['class' => 'btn btn-success']) ?>
  20 + <?= Html::a(Yii::t('app', 'Create').' '.Yii::t('app', 'location'), ['/menu-location/'], ['class' => 'btn btn-primary']) ?>
20 21 </p>
21 22  
22 23 <?= GridView::widget([
... ... @@ -25,18 +26,14 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
25 26 'columns' => [
26 27 ['class' => 'yii\grid\SerialColumn'],
27 28  
28   - 'menu_id',
29   - 'menu_pid',
30 29 [
31   - 'attribute' => 'menu_pid',
  30 + 'attribute' => Yii::t('app', 'termin'),
32 31 'value' => function ($model) {
33 32 return empty($model->termin_id) ? '-' : $model->termin_lang->termin_title;
34 33 },
35   - ],
36   - // 'menu_lft',
37   - // 'menu_rgt',
38   - 'termin_id',
39   - // 'show',
  34 + ],
  35 + 'menu_pid',
  36 + 'level',
40 37 // 'sortorder',
41 38  
42 39 ['class' => 'yii\grid\ActionColumn'],
... ...
backend/views/menu/update.php
... ... @@ -3,13 +3,13 @@
3 3 use yii\helpers\Html;
4 4  
5 5 /* @var $this yii\web\View */
6   -/* @var $model common\models\Menu */
  6 +/* @var $model backend\models\Menu */
7 7  
8 8 $this->title = Yii::t('app', 'Update {modelClass}: ', [
9 9 'modelClass' => 'Menu',
10   -]) . ' ' . $model->menu_id;
  10 +]) . ' ' . $model->name;
11 11 $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Menus'), 'url' => ['index']];
12   -$this->params['breadcrumbs'][] = ['label' => $model->menu_id, 'url' => ['view', 'id' => $model->menu_id]];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->menu_id]];
13 13 $this->params['breadcrumbs'][] = Yii::t('app', 'Update');
14 14 ?>
15 15 <div class="menu-update">
... ... @@ -18,8 +18,6 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = Yii::t(&#39;app&#39;, &#39;Update&#39;);
18 18  
19 19 <?= $this->render('_form', [
20 20 'model' => $model,
21   - 'termin' => $termin,
22   - 'menu' => $menu,
23 21 ]) ?>
24 22  
25 23 </div>
... ...
backend/views/menu/view.php
... ... @@ -4,9 +4,9 @@ use yii\helpers\Html;
4 4 use yii\widgets\DetailView;
5 5  
6 6 /* @var $this yii\web\View */
7   -/* @var $model common\models\Menu */
  7 +/* @var $model backend\models\Menu */
8 8  
9   -$this->title = $model->menu_id;
  9 +$this->title = $model->name;
10 10 $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Menus'), 'url' => ['index']];
11 11 $this->params['breadcrumbs'][] = $this->title;
12 12 ?>
... ... @@ -30,11 +30,14 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
30 30 'attributes' => [
31 31 'menu_id',
32 32 'menu_pid',
33   - 'menu_lft',
34   - 'menu_rgt',
  33 + 'level',
35 34 'termin_id',
36 35 'show',
  36 + 'is_open',
  37 + 'menu_location_id',
37 38 'sortorder',
  39 + 'name',
  40 + 'url:url',
38 41 ],
39 42 ]) ?>
40 43  
... ...
backend/views/termin/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +use backend\models\Termin;
  6 +use kartik\select2\Select2;
  7 +use yii\helpers\ArrayHelper;
  8 +
  9 +/* @var $this yii\web\View */
  10 +/* @var $model backend\models\Termin */
  11 +/* @var $form yii\widgets\ActiveForm */
  12 +
  13 +?>
  14 +
  15 +<div class="termin-form">
  16 +
  17 + <?php $form = ActiveForm::begin(); ?>
  18 +
  19 + <?= $form->field($model_pid->termin, 'termin_pid')->widget(Select2::classname(),
  20 + [
  21 + 'data' => ArrayHelper::map((new Termin)->finInfo([
  22 + 'show_all' => true,
  23 + ]),
  24 + 'termin_id',
  25 + 'termin_title'
  26 + ),
  27 + 'options' => ['placeholder' => 'Select a state ...'],
  28 + 'pluginOptions' => [
  29 + 'allowClear' => true
  30 + ],
  31 + ]);
  32 + ?>
  33 +
  34 + <?= $form->field($model, 'termin_name')->textInput(['maxlength' => true]) ?>
  35 +
  36 + <?= $form->field($model_lang, 'termin_title')->textInput() ?>
  37 +
  38 + <?= $form->field($model_lang, 'termin_alias')->textInput() ?>
  39 +
  40 + <?= Html::activeHiddenInput ($model_lang, 'lang_id', [
  41 + 'value' => ($model_lang->lang_id != 0 ? $model_lang->lang_id : Yii::$app->params['lang_id']),
  42 + ]) ?>
  43 +
  44 + <div class="form-group">
  45 + <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  46 + </div>
  47 +
  48 + <?php ActiveForm::end(); ?>
  49 +
  50 +</div>
... ...
backend/views/termin/_search.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\TerminSearch */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="termin-search">
  12 +
  13 + <?php $form = ActiveForm::begin([
  14 + 'action' => ['index'],
  15 + 'method' => 'get',
  16 + ]); ?>
  17 +
  18 + <?= $form->field($model, 'termin_id') ?>
  19 +
  20 + <?= $form->field($model, 'termin_name') ?>
  21 +
  22 + <?= $form->field($model, 'is_book') ?>
  23 +
  24 + <div class="form-group">
  25 + <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
  26 + <?= Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-default']) ?>
  27 + </div>
  28 +
  29 + <?php ActiveForm::end(); ?>
  30 +
  31 +</div>
... ...
backend/views/termin/create.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\Termin */
  8 +
  9 +$this->title = Yii::t('app', 'Create').' '.Yii::t('app', 'termin');
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Termins'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="termin-create">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <?= $this->render('_form', [
  18 + 'model' => $model,
  19 + 'model_lang' => $model_lang,
  20 + ]) ?>
  21 +
  22 +</div>
... ...
backend/views/catalog/index.php renamed to backend/views/termin/index.php
... ... @@ -4,19 +4,19 @@ use yii\helpers\Html;
4 4 use yii\grid\GridView;
5 5  
6 6 /* @var $this yii\web\View */
7   -/* @var $searchModel backend\models\SearchCatalog */
  7 +/* @var $searchModel backend\models\TerminSearch */
8 8 /* @var $dataProvider yii\data\ActiveDataProvider */
9 9  
10   -$this->title = Yii::t('app', 'Catalogs');
  10 +$this->title = Yii::t('app', 'termin');
11 11 $this->params['breadcrumbs'][] = $this->title;
12 12 ?>
13   -<div class="catalog-index">
  13 +<div class="termin-index">
14 14  
15 15 <h1><?= Html::encode($this->title) ?></h1>
16 16 <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
17 17  
18 18 <p>
19   - <?= Html::a(Yii::t('app', 'Create Catalog'), ['create'], ['class' => 'btn btn-success']) ?>
  19 + <?= Html::a(Yii::t('app', 'Create'), ['create'], ['class' => 'btn btn-success']) ?>
20 20 </p>
21 21  
22 22 <?= GridView::widget([
... ... @@ -24,12 +24,14 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
24 24 'filterModel' => $searchModel,
25 25 'columns' => [
26 26 ['class' => 'yii\grid\SerialColumn'],
27   -
28   - 'catalog_id',
29   - 'parent_id',
30   - 'title',
31   - // 'status',
32   - // 'sort',
  27 + [
  28 + 'attribute' => Yii::t('app', 'termin'),
  29 + 'value' => function ($model) {
  30 + return $model->terminLangs[0]->termin_title;
  31 + },
  32 + ],
  33 + 'termin_name',
  34 + 'is_book',
33 35  
34 36 ['class' => 'yii\grid\ActionColumn'],
35 37 ],
... ...
backend/views/termin/update.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +/* @var $this yii\web\View */
  6 +/* @var $model backend\models\Termin */
  7 +
  8 +$this->title = Yii::t('app', 'Update {modelClass}: ', [
  9 + 'modelClass' => 'Termin',
  10 +]) . ' ' . $model->termin_id;
  11 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Termins'), 'url' => ['index']];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->termin_id, 'url' => ['view', 'id' => $model->termin_id]];
  13 +$this->params['breadcrumbs'][] = Yii::t('app', 'Update');
  14 +?>
  15 +<div class="termin-update">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <?= $this->render('_form', [
  20 + 'model' => $model,
  21 + 'model_lang' => $model_lang,
  22 + 'model_pid' => $model_pid,
  23 + ]) ?>
  24 +
  25 +
  26 +</div>
... ...
backend/views/termin/view.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\DetailView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model backend\models\Termin */
  8 +
  9 +$this->title = $model->termin_id;
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Termins'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="termin-view">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <p>
  18 + <?= Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->termin_id], ['class' => 'btn btn-primary']) ?>
  19 + <?= Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $model->termin_id], [
  20 + 'class' => 'btn btn-danger',
  21 + 'data' => [
  22 + 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),
  23 + 'method' => 'post',
  24 + ],
  25 + ]) ?>
  26 + </p>
  27 +
  28 + <?= DetailView::widget([
  29 + 'model' => $model,
  30 + 'attributes' => [
  31 + 'termin_id',
  32 + 'termin_name',
  33 + 'is_book',
  34 + ],
  35 + ]) ?>
  36 +
  37 +</div>
... ...
common/components/developeruz/db_rbac/LICENSE 0 → 100644
  1 +The MIT License (MIT)
  2 +
  3 +Copyright (c) 2014 Elvira Sheina
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
  22 +
... ...
common/components/developeruz/db_rbac/README.md 0 → 100644
  1 +Динамическая настройка прав доступа для Yii2
  2 +============
  3 +
  4 +Модуль для создания ролей и прав доступа через веб-интерфейс, так же имеющий веб интерфейс для назначения ролей пользователям
  5 +Поведение для приложения, проверяющее право доступа к action по внесенным в модуле правилам.
  6 +
  7 +###Установка:###
  8 +```bash
  9 +$ php composer.phar require developeruz/yii2-db-rbac "*"
  10 +```
  11 +
  12 +Для корректной работы модуля необходимо настроить authManager в конфиге приложения (common/config/main.php для advanced или config/web.php и config/console для basic приложения)
  13 +```php
  14 + 'components' => [
  15 + 'authManager' => [
  16 + 'class' => 'yii\rbac\DbManager',
  17 + ],
  18 + ...
  19 + ]
  20 +```
  21 +
  22 +И выполнить миграции, создающие таблицы для DbManager (подразумевается, что коннект к БД для приложения уже настроен)
  23 +```bash
  24 +$ yii migrate --migrationPath=@yii/rbac/migrations/
  25 +```
  26 +
  27 +##Подключение модуля##
  28 +В конфиге приложения (backend/config/main.php для advanced или config/web.php для basic приложения) прописываем модуль
  29 +```php
  30 + 'modules' => [
  31 + 'permit' => [
  32 + 'class' => 'developeruz\db_rbac\Yii2DbRbac',
  33 + ],
  34 + ],
  35 +```
  36 +Если нужно передать layout это можно сделать так:
  37 +```php
  38 + 'modules' => [
  39 + 'permit' => [
  40 + 'class' => 'developeruz\db_rbac\Yii2DbRbac',
  41 + 'layout' => '//admin'
  42 + ],
  43 + ],
  44 +```
  45 +
  46 +Если вы используете ЧПУ, то убедитесь что у вас прописаны правила роутинга для модулей
  47 +```php
  48 +'<module:\w+>/<controller:\w+>/<action:(\w|-)+>' => '<module>/<controller>/<action>',
  49 +'<module:\w+>/<controller:\w+>/<action:(\w|-)+>/<id:\d+>' => '<module>/<controller>/<action>',
  50 +```
  51 +
  52 +**Добавляем ссылки в меню**
  53 +
  54 +**/permit/access/role - управление ролями**
  55 +
  56 +**/permit/access/permission - управление правами доступа**
  57 +
  58 +###Назначение ролей пользователям###
  59 +По многочисленным просьбам в модуль добавлен интерфейс для назначения ролей пользователям.
  60 +
  61 +Для корректной работы модуля нужно указать в параметрах модуля класс `User`.
  62 +```php
  63 +'modules' => [
  64 + 'permit' => [
  65 + 'class' => 'app\modules\db_rbac\Yii2DbRbac',
  66 + 'params' => [
  67 + 'userClass' => 'app\models\User'
  68 + ]
  69 + ],
  70 + ],
  71 +```
  72 +
  73 +Класс User должен реализовывать интерфейс `developeruz\db_rbac\interfaces\UserRbacInterface`.
  74 +В большинстве случаев придется дописать в нем 1 функцию `getUserName()` которая будет возвращать отображаемое имя пользователя.
  75 +```php
  76 +use developeruz\db_rbac\interfaces\UserRbacInterface;
  77 +
  78 +class User extends ActiveRecord implements IdentityInterface, UserRbacInterface
  79 +{
  80 +...
  81 + public function getUserName()
  82 + {
  83 + return $this->username;
  84 + }
  85 +}
  86 +```
  87 +
  88 +**Управление ролью пользователя происходит на странице `/permit/user/view/1` для пользователя с id=1.**
  89 +Удобнее всего дописать кнопку на эту страницу в Grid со списком пользователей.
  90 +```php
  91 +echo GridView::widget([
  92 + 'dataProvider' => $dataProvider,
  93 + 'columns' => [
  94 + ['class' => 'yii\grid\SerialColumn'],
  95 +
  96 + 'id',
  97 + 'username',
  98 + 'email:email',
  99 +
  100 + ['class' => 'yii\grid\ActionColumn',
  101 + 'template' => '{view}&nbsp;&nbsp;{update}&nbsp;&nbsp;{permit}&nbsp;&nbsp;{delete}',
  102 + 'buttons' =>
  103 + [
  104 + 'permit' => function ($url, $model) {
  105 + return Html::a('<span class="glyphicon glyphicon-wrench"></span>', Url::to(['/permit/user/view', 'id' => $model->id]), [
  106 + 'title' => Yii::t('yii', 'Change user role')
  107 + ]); },
  108 + ]
  109 + ],
  110 + ],
  111 +]);
  112 +```
  113 +
  114 +Присвоить роль пользователю можно и в коде, например при создании нового пользователя.
  115 +```php
  116 +$userRole = Yii::$app->authManager->getRole('name_of_role');
  117 +Yii::$app->authManager->assign($userRole, $user->getId());
  118 +```
  119 +
  120 +Проверить, имеет ли пользователь право на действие можно через метод `can()` компонента User
  121 +```php
  122 +Yii::$app->user->can($permissionName);
  123 +```
  124 +$permissionName - может быть как ролью так и правом
  125 +
  126 +##Поведение, динамически проверяющее наличие прав##
  127 +
  128 +Данное поведение позволяет не писать Yii::$app->user->can($permissionName); в каждом action, а проверять права доступа на лету.
  129 +Это удобно для гибкой настройки прав при использовании сторонних модулей.
  130 +
  131 +###Подключение поведения###
  132 +В конфиге того приложения, доступ к которому следует проверять на лету, необходимо подключить поведение
  133 +```php
  134 +use developeruz\db_rbac\behaviors\AccessBehavior;
  135 +
  136 + 'as AccessBehavior' => [
  137 + 'class' => AccessBehavior::className(),
  138 + ]
  139 +```
  140 +С этого момента, после обработки запроса (событие EVENT_AFTER_REQUEST) проверяются права текущего пользователя (Yii::$app->user) на выполнение запрашиваемого действия (Yii::$app->user->can())
  141 +Действие считается разрешенным, если:
  142 + - пользователю разрешен доступ к конкретному action (правило записано как: module/controller/action)
  143 + - пользователю разрешен доступ к любым action данного контроллера (правило записано как: module/controller)
  144 + - пользователю разрешен доступ к любым action данного модуля (правило записано как: module)
  145 +
  146 +###Настройка прав доступа по умолчанию###
  147 +После подключения поведения, доступ становится возможен только авторизованному пользователю, имеющему некие права.
  148 +Для исключений из этого правила можно прописать доступы по умолчанию в том же формате AccessControl, что и в контроллере:
  149 +```php
  150 + 'as AccessBehavior' => [
  151 + 'class' => AccessBehavior::className(),
  152 + 'rules' =>
  153 + ['site' =>
  154 + [
  155 + [
  156 + 'actions' => ['login', 'index'],
  157 + 'allow' => true,
  158 + ],
  159 + [
  160 + 'actions' => ['about'],
  161 + 'allow' => true,
  162 + 'roles' => ['admin'],
  163 + ],
  164 + ]
  165 + ]
  166 + ]
  167 +```
  168 +В приведенном выше примере разрешен доступ любому пользователю к site/login и site/index и доступ пользователя с ролью admin к site/about
  169 +Правила прописанные в конфиге имеют приоритет над динамически настраиваемыми правилами.
0 170 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/Yii2DbRbac.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Yii2DbRbac for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package Yii2DbRbac for Yii2
  8 + *
  9 + */
  10 +namespace common\components\developeruz\db_rbac;
  11 +
  12 +use Yii;
  13 +
  14 +class Yii2DbRbac extends \yii\base\Module
  15 +{
  16 + public $controllerNamespace = 'common\components\developeruz\db_rbac\controllers';
  17 + public $userClass;
  18 +
  19 + public function init()
  20 + {
  21 + parent::init();
  22 + $this->registerTranslations();
  23 + }
  24 +
  25 + public function registerTranslations()
  26 + {
  27 + Yii::$app->i18n->translations['db_rbac'] = [
  28 + 'class' => 'yii\i18n\PhpMessageSource',
  29 + 'sourceLanguage' => 'ru-Ru',
  30 + 'basePath' => '@developeruz/db_rbac/messages',
  31 + ];
  32 + }
  33 +
  34 + public static function t($category, $message, $params = [], $language = null)
  35 + {
  36 + return Yii::t('modules/db_rbac/' . $category, $message, $params, $language);
  37 + }
  38 +}
... ...
common/components/developeruz/db_rbac/behaviors/AccessBehavior.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * AccessBehavior for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package AccessBehavior for Yii2
  8 + *
  9 + */
  10 +namespace developeruz\db_rbac\behaviors;
  11 +
  12 +use Yii;
  13 +use yii\behaviors\AttributeBehavior;
  14 +use yii\di\Instance;
  15 +use yii\base\Module;
  16 +use yii\web\Application;
  17 +use yii\web\User;
  18 +use yii\filters\AccessControl;
  19 +use yii\web\ForbiddenHttpException;
  20 +
  21 +class AccessBehavior extends AttributeBehavior {
  22 +
  23 + public $rules=[];
  24 +
  25 + private $_rules = [];
  26 +
  27 + public function events()
  28 + {
  29 + return [
  30 + Module::EVENT_BEFORE_ACTION => 'interception',
  31 + ];
  32 + }
  33 +
  34 + public function interception($event)
  35 + {
  36 + if(!isset( Yii::$app->i18n->translations['db_rbac'])){
  37 + Yii::$app->i18n->translations['db_rbac'] = [
  38 + 'class' => 'yii\i18n\PhpMessageSource',
  39 + 'sourceLanguage' => 'ru-Ru',
  40 + 'basePath' => '@developeruz/db_rbac/messages',
  41 + ];
  42 + }
  43 +
  44 + $route = Yii::$app->getRequest()->resolve();
  45 +
  46 + //Проверяем права по конфигу
  47 + $this->createRule();
  48 + $user = Instance::ensure(Yii::$app->user, User::className());
  49 + $request = Yii::$app->getRequest();
  50 + $action = $event->action;
  51 +
  52 + if(!$this->cheсkByRule($action, $user, $request))
  53 + {
  54 + //И по AuthManager
  55 + if(!$this->checkPermission($route))
  56 + throw new ForbiddenHttpException(Yii::t('db_rbac','Недостаточно прав'));
  57 + }
  58 + }
  59 +
  60 + protected function createRule()
  61 + {
  62 + foreach($this->rules as $controller => $rule)
  63 + {
  64 + foreach ($rule as $singleRule) {
  65 + if (is_array($singleRule)) {
  66 + $option = [
  67 + 'controllers' => [$controller],
  68 + 'class' => 'yii\filters\AccessRule'
  69 + ];
  70 + $this->_rules[] = Yii::createObject(array_merge($option, $singleRule));
  71 + }
  72 + }
  73 + }
  74 + }
  75 +
  76 + protected function cheсkByRule($action, $user, $request)
  77 + {
  78 + foreach ($this->_rules as $rule) {
  79 + if ($rule->allows($action, $user, $request))
  80 + return true;
  81 + }
  82 + return false;
  83 + }
  84 +
  85 + protected function checkPermission($route)
  86 + {
  87 + //$route[0] - is the route, $route[1] - is the associated parameters
  88 +
  89 + $routePathTmp = explode('/', $route[0]);
  90 + $routeVariant = array_shift($routePathTmp);
  91 + if(Yii::$app->user->can($routeVariant, $route[1]))
  92 + return true;
  93 +
  94 + foreach($routePathTmp as $routePart)
  95 + {
  96 + $routeVariant .= '/'.$routePart;
  97 + if(Yii::$app->user->can($routeVariant, $route[1]))
  98 + return true;
  99 + }
  100 +
  101 + return false;
  102 + }
  103 +}
0 104 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/composer.json 0 → 100644
  1 +{
  2 + "name": "developeruz/yii2-db-rbac",
  3 + "description": "Dynamic control of access rights in YII2",
  4 + "keywords": ["yii", "rbac"],
  5 + "type": "yii2-extension",
  6 + "license": "MIT",
  7 + "authors": [
  8 + {
  9 + "name": "Elvira Sheina",
  10 + "email": "elleuz@gmail.com",
  11 + "homepage": "http://developer.uz"
  12 + }
  13 + ],
  14 + "require": {
  15 + "yiisoft/yii2": "*"
  16 + },
  17 + "support": {
  18 + "issues": "https://github.com/developeruz/yii2-db-rbac/issues"
  19 + },
  20 + "autoload": {
  21 + "psr-4": {
  22 + "developeruz\\db_rbac\\": ""
  23 + }
  24 + }
  25 +}
0 26 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/controllers/AccessController.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * AccessController for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package AccessController for Yii2
  8 + *
  9 + */
  10 +namespace common\components\developeruz\db_rbac\controllers;
  11 +
  12 +use Yii;
  13 +use yii\web\Controller;
  14 +use yii\web\BadRequestHttpException;
  15 +use yii\rbac\Role;
  16 +use yii\rbac\Permission;
  17 +use yii\helpers\ArrayHelper;
  18 +use yii\helpers\Url;
  19 +use yii\validators\RegularExpressionValidator;
  20 +
  21 +class AccessController extends Controller
  22 +{
  23 + protected $error;
  24 + protected $pattern4Role = '/^[a-zA-Z0-9_-]+$/';
  25 + protected $pattern4Permission = '/^[a-zA-Z0-9_\/-]+$/';
  26 +
  27 + public function actions()
  28 + {
  29 + return [
  30 + 'error' => [
  31 + 'class' => 'yii\web\ErrorAction',
  32 + ],
  33 + ];
  34 + }
  35 +
  36 + public function actionRole()
  37 + {
  38 + return $this->render('role');
  39 + }
  40 +
  41 + public function actionAddRole()
  42 + {
  43 + if (Yii::$app->request->post('name')
  44 + && $this->validate(Yii::$app->request->post('name'), $this->pattern4Role)
  45 + && $this->isUnique(Yii::$app->request->post('name'), 'role')
  46 + ) {
  47 + $role = Yii::$app->authManager->createRole(Yii::$app->request->post('name'));
  48 + $role->description = Yii::$app->request->post('description');
  49 + Yii::$app->authManager->add($role);
  50 + $this->setPermissions(Yii::$app->request->post('permissions', []), $role);
  51 + return $this->redirect(Url::toRoute([
  52 + 'update-role',
  53 + 'name' => $role->name
  54 + ]));
  55 + }
  56 +
  57 + $permissions = ArrayHelper::map(Yii::$app->authManager->getPermissions(), 'name', 'description');
  58 + return $this->render(
  59 + 'addRole',
  60 + [
  61 + 'permissions' => $permissions,
  62 + 'error' => $this->error
  63 + ]
  64 + );
  65 + }
  66 +
  67 + public function actionUpdateRole($name)
  68 + {
  69 + $role = Yii::$app->authManager->getRole($name);
  70 +
  71 + $permissions = ArrayHelper::map(Yii::$app->authManager->getPermissions(), 'name', 'description');
  72 + $role_permit = array_keys(Yii::$app->authManager->getPermissionsByRole($name));
  73 +
  74 + if ($role instanceof Role) {
  75 + if (Yii::$app->request->post('name')
  76 + && $this->validate(Yii::$app->request->post('name'), $this->pattern4Role)
  77 + ) {
  78 + if (Yii::$app->request->post('name') != $name && !$this->isUnique(Yii::$app->request->post('name'), 'role')) {
  79 + return $this->render(
  80 + 'updateRole',
  81 + [
  82 + 'role' => $role,
  83 + 'permissions' => $permissions,
  84 + 'role_permit' => $role_permit,
  85 + 'error' => $this->error
  86 + ]
  87 + );
  88 + }
  89 + $role = $this->setAttribute($role, Yii::$app->request->post());
  90 + Yii::$app->authManager->update($name, $role);
  91 + Yii::$app->authManager->removeChildren($role);
  92 + $this->setPermissions(Yii::$app->request->post('permissions', []), $role);
  93 + return $this->redirect(Url::toRoute([
  94 + 'update-role',
  95 + 'name' => $role->name
  96 + ]));
  97 + }
  98 +
  99 + return $this->render(
  100 + 'updateRole',
  101 + [
  102 + 'role' => $role,
  103 + 'permissions' => $permissions,
  104 + 'role_permit' => $role_permit,
  105 + 'error' => $this->error
  106 + ]
  107 + );
  108 + } else {
  109 + throw new BadRequestHttpException(Yii::t('db_rbac', 'Страница не найдена'));
  110 + }
  111 + }
  112 +
  113 + public function actionDeleteRole($name)
  114 + {
  115 + $role = Yii::$app->authManager->getRole($name);
  116 + if ($role) {
  117 + Yii::$app->authManager->removeChildren($role);
  118 + Yii::$app->authManager->remove($role);
  119 + }
  120 + return $this->redirect(Url::toRoute(['role']));
  121 + }
  122 +
  123 +
  124 + public function actionPermission()
  125 + {
  126 + return $this->render('permission');
  127 + }
  128 +
  129 + public function actionAddPermission()
  130 + {
  131 + $permission = $this->clear(Yii::$app->request->post('name'));
  132 + if ($permission
  133 + && $this->validate($permission, $this->pattern4Permission)
  134 + && $this->isUnique($permission, 'permission')
  135 + ) {
  136 + $permit = Yii::$app->authManager->createPermission($permission);
  137 + $permit->description = Yii::$app->request->post('description', '');
  138 + Yii::$app->authManager->add($permit);
  139 + return $this->redirect(Url::toRoute([
  140 + 'update-permission',
  141 + 'name' => $permit->name
  142 + ]));
  143 + }
  144 +
  145 + return $this->render('addPermission', ['error' => $this->error]);
  146 + }
  147 +
  148 + public function actionUpdatePermission($name)
  149 + {
  150 + $permit = Yii::$app->authManager->getPermission($name);
  151 + if ($permit instanceof Permission) {
  152 + $permission = $this->clear(Yii::$app->request->post('name'));
  153 + if ($permission && $this->validate($permission, $this->pattern4Permission)
  154 + ) {
  155 + if($permission!= $name && !$this->isUnique($permission, 'permission'))
  156 + {
  157 + return $this->render('updatePermission', [
  158 + 'permit' => $permit,
  159 + 'error' => $this->error
  160 + ]);
  161 + }
  162 +
  163 + $permit->name = $permission;
  164 + $permit->description = Yii::$app->request->post('description', '');
  165 + Yii::$app->authManager->update($name, $permit);
  166 + return $this->redirect(Url::toRoute([
  167 + 'update-permission',
  168 + 'name' => $permit->name
  169 + ]));
  170 + }
  171 +
  172 + return $this->render('updatePermission', [
  173 + 'permit' => $permit,
  174 + 'error' => $this->error
  175 + ]);
  176 + } else throw new BadRequestHttpException(Yii::t('db_rbac', 'Страница не найдена'));
  177 + }
  178 +
  179 + public function actionDeletePermission($name)
  180 + {
  181 + $permit = Yii::$app->authManager->getPermission($name);
  182 + if ($permit)
  183 + Yii::$app->authManager->remove($permit);
  184 + return $this->redirect(Url::toRoute(['permission']));
  185 + }
  186 +
  187 + protected function setAttribute($object, $data)
  188 + {
  189 + $object->name = $data['name'];
  190 + $object->description = $data['description'];
  191 + return $object;
  192 + }
  193 +
  194 + protected function setPermissions($permissions, $role)
  195 + {
  196 + foreach ($permissions as $permit) {
  197 + $new_permit = Yii::$app->authManager->getPermission($permit);
  198 + Yii::$app->authManager->addChild($role, $new_permit);
  199 + }
  200 + }
  201 +
  202 + protected function validate($field, $regex)
  203 + {
  204 + $validator = new RegularExpressionValidator(['pattern' => $regex]);
  205 + if ($validator->validate($field, $error))
  206 + return true;
  207 + else {
  208 + $this->error[] = Yii::t('db_rbac', 'Значение "{field}" содержит не допустимые символы', ['field' => $field]);
  209 + return false;
  210 + }
  211 + }
  212 +
  213 + protected function isUnique($name, $type)
  214 + {
  215 + if ($type == 'role') {
  216 + $role = Yii::$app->authManager->getRole($name);
  217 + if ($role instanceof Role) {
  218 + $this->error[] = Yii::t('db_rbac', 'Роль с таким именем уже существует: ') . $name;
  219 + return false;
  220 + } else return true;
  221 + } elseif ($type == 'permission') {
  222 + $permission = Yii::$app->authManager->getPermission($name);
  223 + if ($permission instanceof Permission) {
  224 + $this->error[] = Yii::t('db_rbac', 'Правило с таким именем уже существует: ') . $name;
  225 + return false;
  226 + } else return true;
  227 + }
  228 + }
  229 +
  230 + protected function clear($value)
  231 + {
  232 + if (!empty($value)) {
  233 + $value = trim($value, "/ \t\n\r\0\x0B");
  234 + }
  235 +
  236 + return $value;
  237 + }
  238 +}
0 239 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/controllers/UserController.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Controller to attache role for user for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package UserController for Yii2
  8 + *
  9 + */
  10 +namespace common\components\developeruz\db_rbac\controllers;
  11 +
  12 +use Yii;
  13 +use yii\filters\VerbFilter;
  14 +use yii\helpers\ArrayHelper;
  15 +use yii\helpers\Url;
  16 +use yii\web\Controller;
  17 +use yii\web\BadRequestHttpException;
  18 +use developeruz\db_rbac\interfaces\UserRbacInterface;
  19 +use yii\web\NotFoundHttpException;
  20 +
  21 +class UserController extends Controller
  22 +{
  23 + public $moduleName = 'permit';
  24 +
  25 + public function beforeAction($action)
  26 + {
  27 + if(empty(Yii::$app->controller->module->params['userClass'])){
  28 + throw new BadRequestHttpException(Yii::t('db_rbac','Необходимо указать класс User в настройках модуля'));
  29 + }
  30 +
  31 + $user = new Yii::$app->controller->module->params['userClass']();
  32 +
  33 + if(! $user instanceof UserRbacInterface)
  34 + {
  35 + throw new BadRequestHttpException(Yii::t('db_rbac', 'UserClass должен реализовывать интерфейс developeruz\db_rbac\UserRbacInterface'));
  36 + }
  37 +
  38 + return parent::beforeAction($action);
  39 + }
  40 +
  41 + public function actions()
  42 + {
  43 + return [
  44 + 'error' => [
  45 + 'class' => 'yii\web\ErrorAction',
  46 + ],
  47 + ];
  48 + }
  49 +
  50 + public function behaviors()
  51 + {
  52 + return [
  53 + 'verbs' => [
  54 + 'class' => VerbFilter::className(),
  55 + 'actions' => [
  56 + 'update' => ['post'],
  57 + '*' => ['get'],
  58 + ],
  59 + ],
  60 + ];
  61 + }
  62 +
  63 + public function actionView($id)
  64 + {
  65 + $roles = ArrayHelper::map(Yii::$app->authManager->getRoles(), 'name', 'description');
  66 + $user_permit = array_keys(Yii::$app->authManager->getRolesByUser($id));
  67 + $user = $this->findUser($id);
  68 + return $this->render('view', [
  69 + 'user' => $user,
  70 + 'roles' => $roles,
  71 + 'user_permit' => $user_permit,
  72 + 'moduleName' => Yii::$app->controller->module->id
  73 + ]);
  74 + }
  75 +
  76 + public function actionUpdate($id)
  77 + {
  78 + $user = $this->findUser($id);
  79 + Yii::$app->authManager->revokeAll($user->getId());
  80 + if(Yii::$app->request->post('roles')){
  81 + foreach(Yii::$app->request->post('roles') as $role)
  82 + {
  83 + $new_role = Yii::$app->authManager->getRole($role);
  84 + Yii::$app->authManager->assign($new_role, $user->getId());
  85 + }
  86 + }
  87 + return $this->redirect(Url::to(["/".Yii::$app->controller->module->id."/user/view", 'id' => $user->getId()]));
  88 + }
  89 +
  90 + private function findUser($id)
  91 + {
  92 + $class = new Yii::$app->controller->module->params['userClass']();
  93 + $user = $class::findIdentity($id);
  94 + if(empty($user)){
  95 + throw new NotFoundHttpException(Yii::t('db_rbac', 'Пользователь не найден'));
  96 + } else {
  97 + return $user;
  98 + }
  99 + }
  100 +}
0 101 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/interfaces/UserRbacInterface.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\interfaces;
  3 +
  4 +
  5 +interface UserRbacInterface {
  6 +
  7 + public function getId();
  8 + public function getUserName();
  9 + public static function findIdentity($id);
  10 +}
0 11 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/messages/en/db_rbac.php 0 → 100644
  1 +<?php
  2 +return [
  3 + 'Правило с таким именем уже существует: ' => 'Permission with the same name already exists: ',
  4 + 'Роль с таким именем уже существует: ' => 'Role with the same name already exists: ',
  5 + 'Значение "{field}" содержит недопустимые символы' => '"{field}" value contains invalid characters',
  6 + 'Страница не найдена' => 'Page not found',
  7 + 'Недостаточно прав' => 'You not allow to access',
  8 + 'Необходимо указать класс User в настройках модуля' => 'UserClass params must be set in config file',
  9 + 'UserClass должен реализовывать интерфейс developeruz\db_rbac\UserRbacInterface' => 'UserClass must implements developeruz\db_rbac\UserRbacInterface',
  10 + 'Пользователь не найден' => 'User not found'
  11 +];
... ...
common/components/developeruz/db_rbac/views/access/addPermission.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $model common\models\Links */
  10 +/* @var $form yii\widgets\ActiveForm */
  11 +$this->title = Yii::t('db_rbac', 'Новое правило');
  12 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Правила доступа'), 'url' => ['permission']];
  13 +$this->params['breadcrumbs'][] = Yii::t('db_rbac', 'Новое правило');
  14 +?>
  15 +<div class="news-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <div class="links-form">
  20 + <?php
  21 + if (!empty($error)) {
  22 + ?>
  23 + <div class="error-summary">
  24 + <?php
  25 + echo implode('<br>', $error);
  26 + ?>
  27 + </div>
  28 + <?php
  29 + }
  30 + ?>
  31 +
  32 + <?php $form = ActiveForm::begin(); ?>
  33 +
  34 + <div class="form-group">
  35 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  36 + <?= Html::textInput('description'); ?>
  37 + </div>
  38 +
  39 + <div class="form-group">
  40 + <?= Html::label(Yii::t('db_rbac', 'Разрешенный доступ')); ?>
  41 + <?= Html::textInput('name'); ?>
  42 + <?=Yii::t('db_rbac', '
  43 + * Формат module/controller/action<br>
  44 + site/article - доступ к странице site/article<br>
  45 + site - доступ к любым action контроллера site');?>
  46 + </div>
  47 +
  48 + <div class="form-group">
  49 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  50 + </div>
  51 +
  52 + <?php ActiveForm::end(); ?>
  53 +
  54 + </div>
  55 +</div>
... ...
common/components/developeruz/db_rbac/views/access/addRole.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $model common\models\Links */
  10 +/* @var $form yii\widgets\ActiveForm */
  11 +
  12 +$this->title = Yii::t('db_rbac', 'Новая роль');
  13 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Управление ролями'), 'url' => ['role']];
  14 +$this->params['breadcrumbs'][] = 'Новая роль';
  15 +?>
  16 +<div class="news-index">
  17 +
  18 + <h1><?= Html::encode($this->title) ?></h1>
  19 +
  20 + <div class="links-form">
  21 + <?php
  22 + if (!empty($error)) {
  23 + ?>
  24 + <div class="error-summary">
  25 + <?php
  26 + echo implode('<br>', $error);
  27 + ?>
  28 + </div>
  29 + <?php
  30 + }
  31 + ?>
  32 + <?php $form = ActiveForm::begin(); ?>
  33 +
  34 + <div class="form-group">
  35 + <?= Html::label(Yii::t('db_rbac', 'Название роли')); ?>
  36 + <?= Html::textInput('name'); ?>
  37 + * только латинские буквы, цифры и _ -
  38 + </div>
  39 +
  40 + <div class="form-group">
  41 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  42 + <?= Html::textInput('description'); ?>
  43 + </div>
  44 +
  45 + <div class="form-group">
  46 + <?= Html::label(Yii::t('db_rbac', 'Разрешенные доступы')); ?>
  47 + <?= Html::checkboxList('permissions', null, $permissions, ['separator' => '<br>']); ?>
  48 + </div>
  49 +
  50 + <div class="form-group">
  51 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  52 + </div>
  53 +
  54 + <?php ActiveForm::end(); ?>
  55 +
  56 + </div>
  57 +</div>
0 58 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/permission.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\data\ArrayDataProvider;
  6 +use yii\grid\GridView;
  7 +use yii\grid\DataColumn;
  8 +use yii\helpers\Url;
  9 +use yii\helpers\Html;
  10 +
  11 +$this->title = Yii::t('db_rbac', 'Правила доступа');
  12 +$this->params['breadcrumbs'][] = $this->title;
  13 +?>
  14 +<div class="news-index">
  15 +
  16 + <h1><?= Html::encode($this->title) ?></h1>
  17 +
  18 + <p>
  19 + <?= Html::a(Yii::t('db_rbac', 'Добавить новое правило'), ['add-permission'], ['class' => 'btn btn-success']) ?>
  20 + </p>
  21 +<?php
  22 +$dataProvider = new ArrayDataProvider([
  23 + 'allModels' => Yii::$app->authManager->getPermissions(),
  24 + 'sort' => [
  25 + 'attributes' => ['name', 'description'],
  26 + ],
  27 + 'pagination' => [
  28 + 'pageSize' => 10,
  29 + ],
  30 + ]);
  31 +?>
  32 +
  33 +<?=GridView::widget([
  34 + 'dataProvider' => $dataProvider,
  35 + 'columns' => [
  36 + ['class' => 'yii\grid\SerialColumn'],
  37 + [
  38 + 'class' => DataColumn::className(),
  39 + 'attribute' => 'name',
  40 + 'label' => Yii::t('db_rbac', 'Правило')
  41 + ],
  42 + [
  43 + 'class' => DataColumn::className(),
  44 + 'attribute' => 'description',
  45 + 'label' => Yii::t('db_rbac', 'Описание')
  46 + ],
  47 + ['class' => 'yii\grid\ActionColumn',
  48 + 'template' => '{update} {delete}',
  49 + 'buttons' =>
  50 + [
  51 + 'update' => function ($url, $model) {
  52 + return Html::a('<span class="glyphicon glyphicon-pencil"></span>', Url::toRoute(['update-permission', 'name' => $model->name]), [
  53 + 'title' => Yii::t('yii', 'Update'),
  54 + 'data-pjax' => '0',
  55 + ]); },
  56 + 'delete' => function ($url, $model) {
  57 + return Html::a('<span class="glyphicon glyphicon-trash"></span>', Url::toRoute(['delete-permission','name' => $model->name]), [
  58 + 'title' => Yii::t('yii', 'Delete'),
  59 + 'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
  60 + 'data-method' => 'post',
  61 + 'data-pjax' => '0',
  62 + ]);
  63 + }
  64 + ]
  65 + ],
  66 + ]
  67 + ]);
  68 +?>
  69 +</div>
0 70 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/role.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\data\ArrayDataProvider;
  6 +use yii\grid\GridView;
  7 +use yii\grid\DataColumn;
  8 +use yii\helpers\Url;
  9 +use yii\helpers\Html;
  10 +use yii\helpers\ArrayHelper;
  11 +
  12 +$this->title = Yii::t('db_rbac', 'Управление ролями');
  13 +$this->params['breadcrumbs'][] = $this->title;
  14 +?>
  15 +<div class="news-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <p>
  20 + <?= Html::a(Yii::t('db_rbac', 'Добавить роль'), ['add-role'], ['class' => 'btn btn-success']) ?>
  21 + </p>
  22 +<?php
  23 +$dataProvider = new ArrayDataProvider([
  24 + 'allModels' => Yii::$app->authManager->getRoles(),
  25 + 'sort' => [
  26 + 'attributes' => ['name', 'description'],
  27 + ],
  28 + 'pagination' => [
  29 + 'pageSize' => 10,
  30 + ],
  31 + ]);
  32 +?>
  33 +
  34 +<?=GridView::widget([
  35 + 'dataProvider' => $dataProvider,
  36 + 'columns' => [
  37 + ['class' => 'yii\grid\SerialColumn'],
  38 + [
  39 + 'class' => DataColumn::className(),
  40 + 'attribute' => 'name',
  41 + 'label' => Yii::t('db_rbac', 'Роль')
  42 + ],
  43 + [
  44 + 'class' => DataColumn::className(),
  45 + 'attribute' => 'description',
  46 + 'label' => Yii::t('db_rbac', 'Описание')
  47 + ],
  48 + [
  49 + 'class' => DataColumn::className(),
  50 + 'label' => Yii::t('db_rbac', 'Разрешенные доступы'),
  51 + 'format' => ['html'],
  52 + 'value' => function($data) { return implode('<br>',array_keys(ArrayHelper::map(Yii::$app->authManager->getPermissionsByRole($data->name), 'description', 'description')));}
  53 + ],
  54 + ['class' => 'yii\grid\ActionColumn',
  55 + 'template' => '{update} {delete}',
  56 + 'buttons' =>
  57 + [
  58 + 'update' => function ($url, $model) {
  59 + return Html::a('<span class="glyphicon glyphicon-pencil"></span>', Url::toRoute(['update-role', 'name' => $model->name]), [
  60 + 'title' => Yii::t('yii', 'Update'),
  61 + 'data-pjax' => '0',
  62 + ]); },
  63 + 'delete' => function ($url, $model) {
  64 + return Html::a('<span class="glyphicon glyphicon-trash"></span>', Url::toRoute(['delete-role','name' => $model->name]), [
  65 + 'title' => Yii::t('yii', 'Delete'),
  66 + 'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
  67 + 'data-method' => 'post',
  68 + 'data-pjax' => '0',
  69 + ]);
  70 + }
  71 + ]
  72 + ],
  73 + ]
  74 + ]);
  75 +?>
  76 +</div>
0 77 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/updatePermission.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $model common\models\Links */
  10 +/* @var $form yii\widgets\ActiveForm */
  11 +
  12 +$this->title = Yii::t('db_rbac', 'Редактирование правила: ') . ' ' . $permit->description;
  13 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Правила доступа'), 'url' => ['permission']];
  14 +$this->params['breadcrumbs'][] = Yii::t('db_rbac', 'Редактирование правила');
  15 +?>
  16 +<div class="news-index">
  17 +
  18 + <h1><?= Html::encode($this->title) ?></h1>
  19 +
  20 + <div class="links-form">
  21 +
  22 + <?php
  23 + if (!empty($error)) {
  24 + ?>
  25 + <div class="error-summary">
  26 + <?php
  27 + echo implode('<br>', $error);
  28 + ?>
  29 + </div>
  30 + <?php
  31 + }
  32 + ?>
  33 +
  34 + <?php $form = ActiveForm::begin(); ?>
  35 +
  36 + <div class="form-group">
  37 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  38 + <?= Html::textInput('description', $permit->description); ?>
  39 + </div>
  40 +
  41 + <div class="form-group">
  42 + <?= Html::label(Yii::t('db_rbac', 'Разрешенный доступ')); ?>
  43 + <?= Html::textInput('name', $permit->name); ?>
  44 + </div>
  45 +
  46 + <div class="form-group">
  47 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  48 + </div>
  49 +
  50 + <?php ActiveForm::end(); ?>
  51 +
  52 + </div>
  53 +</div>
0 54 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/updateRole.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +$this->title = Yii::t('db_rbac', 'Редактирование роли: ') . ' ' . $role->name;
  9 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Управление ролями'), 'url' => ['role']];
  10 +$this->params['breadcrumbs'][] = Yii::t('db_rbac', 'Редактирование');
  11 +?>
  12 +<div class="news-index">
  13 +
  14 + <h1><?= Html::encode($this->title) ?></h1>
  15 +
  16 + <div class="links-form">
  17 +
  18 + <?php
  19 + if (!empty($error)) {
  20 + ?>
  21 + <div class="error-summary">
  22 + <?php
  23 + echo implode('<br>', $error);
  24 + ?>
  25 + </div>
  26 + <?php
  27 + }
  28 + ?>
  29 +
  30 + <?php $form = ActiveForm::begin(); ?>
  31 +
  32 + <div class="form-group">
  33 + <?= Html::label(Yii::t('db_rbac', 'Название роли')); ?>
  34 + <?= Html::textInput('name', $role->name); ?>
  35 + </div>
  36 +
  37 + <div class="form-group">
  38 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  39 + <?= Html::textInput('description', $role->description); ?>
  40 + </div>
  41 +
  42 + <div class="form-group">
  43 + <?= Html::label(Yii::t('db_rbac', 'Разрешенные доступы')); ?>
  44 + <?= Html::checkboxList('permissions', $role_permit, $permissions, ['separator' => '<br>']); ?>
  45 + </div>
  46 +
  47 + <div class="form-group">
  48 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  49 + </div>
  50 +
  51 + <?php ActiveForm::end(); ?>
  52 +
  53 + </div>
  54 +</div>
... ...
common/components/developeruz/db_rbac/views/user/view.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\user;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +?>
  9 +<h3><?=Yii::t('db_rbac', 'Управление ролями пользователя');?> <?= $user->getUserName(); ?></h3>
  10 +<?php $form = ActiveForm::begin(['action' => ["/{$moduleName}/user/update", 'id' => $user->getId()]]); ?>
  11 +
  12 +<?= Html::checkboxList('roles', $user_permit, $roles, ['separator' => '<br>']); ?>
  13 +
  14 +<div class="form-group">
  15 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  16 +</div>
  17 +
  18 +<?php ActiveForm::end(); ?>
  19 +
... ...
common/components/nodge/eauth/.gitignore 0 → 100644
  1 +vendor
  2 +composer.lock
  3 +composer.phar
0 4 \ No newline at end of file
... ...
common/components/nodge/eauth/CHANGELOG.md 0 → 100644
  1 +Yii2 EAuth Change Log
  2 +=====================
  3 +
  4 +### 2.3.0 (17.10.2015)
  5 +* Added InstagramOAuth2Service (#61)
  6 +* Fixed default token lifetime (#53)
  7 +* Replace array() with [] (#54)
  8 +* Remove deprecated Google OpenID service (#56)
  9 +* Remove deprecated Yandex OpenID service
  10 +
  11 +### 2.2.4 (27.07.2015)
  12 +* Fixed typo in `oauth2/Service.php` (#34)
  13 +* Added German translation
  14 +* Added `email` attribute to `LinkedinOAuth2Service.php`
  15 +
  16 +### 2.2.3 (15.07.2014)
  17 +* Added ability to call public api methods (without access token) (#28)
  18 +
  19 +### 2.2.2 (15.07.2014)
  20 +* Fixed wrong redirect_uri when popup is used
  21 +
  22 +### 2.2.1 (25.04.2014)
  23 +* Fix missing query params in callback urls (#26)
  24 +* Follow Yii2 code style
  25 +
  26 +### 2.2.0 (19.04.2014)
  27 +* Support for PHPoAuthLib v0.3 (#22)
  28 +* Support for Yii2 beta
  29 +* Internal state implementation replaced to PHPoAuthLib storage
  30 +
  31 +### 2.1.5 (24.03.2014)
  32 +* Fixed Yii2 refactor (#17)
  33 +* PSR-4
  34 +
  35 +### 2.1.4 (11.03.2014)
  36 +* Fixed wrong callbackUrl in oauth\ServiceBase when UrlManager uses prettyUrl=false and showScript=false (#12)
  37 +* Fixed Yii::t() calls according to Yii2 i18n Named Placeholders (#14)
  38 +* Fixed Yii2 refactor #2630 (#15)
  39 +
  40 +### 2.1.3 (30.01.2014)
  41 +* Yii2 update (Request methods has been refactored).
  42 +
  43 +### 2.1.2 (17.01.2014)
  44 +* Fixed typo in oauth2\ServiceProxy
  45 +
  46 +### 2.1.1 (07.01.2014)
  47 +* Fixed scope validation for OAuth services.
  48 +
  49 +### 2.1.0 (22.12.2013)
  50 +* Reorganize project with new namespace.
  51 +* Assets bundle has been moved.
  52 +* Fixed typo in HttpClient (#8).
  53 +* Added default User-Agent header to HttpClient.
  54 +* Disabled CSRF validation for OpenID callbacks.
  55 +* Optimized icons file.
  56 +* Added SteamOpenIDService.
  57 +* Improved redirect widget.
  58 +
  59 +### 2.0.3 (26.10.2013)
  60 +* Fixed redirect_uri when not using url rule (#2).
  61 +* Fixed hasValidAccessToken() method for OAuth1 services (#3).
  62 +* Fixed auto login cookie (#4).
  63 +
  64 +### 2.0.2 (12.10.2013)
  65 +* Fixed ServiceProxy constructor to match its interface (#1).
  66 +* Added HttpClient with logging support and curl/streams fallback.
  67 +* TokenStorage and HttpClient are configurable now.
  68 +
  69 +### 2.0.1 (08.09.2013)
  70 +* Fixed package versions in the composer.json.
  71 +* Fixed directories names.
  72 +* Added support for custom scope separator in OAuth2 services.
  73 +* Added support for additional headers for OAuth2 requests.
  74 +* Added method to get error from access token response.
  75 +* Added GitHubOAuth2Service.
  76 +* Added LinkedinOAuth2Service.
  77 +* Added MailruOAuth2Service.
  78 +* Added OdnoklassnikiOAuth2Service.
  79 +* Added LiveOAuth2Service.
  80 +* Added YahooOpenIDService.
  81 +
  82 +### Version 2.0.0 (03.09.2013)
  83 +* Use curl for http requests by default.
  84 +* getIsAuthenticated() function now looks up for existing access token for all OAuth services.
  85 +* Added support for oauth_expires_in to OAuth1 services.
  86 +* Added error handlers to OAuth1 services.
  87 +* Added support for refresh tokens to OAuth2 ServiceProxy.
  88 +* Added an option to disable OAuth2 state validation.
  89 +
  90 +### 31.08.2013
  91 +* Reorganize directories. Separate root directory by service type.
  92 +* Fixed OAuthService::getCallbackUrl(). Now returns url without GET arguments.
  93 +* Fixed typos in OAuth services.
  94 +* Fixed OpenID loadAttributes functions.
  95 +* OAuth2 display mode handling moved to the base class.
  96 +* Added OAuthService::getAccessTokenData() method to access to valid access_token and related data.
  97 +* Added token default lifetime setting.
  98 +* Added "state" argument handling for OAuth2 services to improve security.
  99 +* Updated OpenID library. Fixed error with stream requests.
  100 +* Added VKontakteOAuth2Service.
  101 +* Added GoogleOAuth2Service.
  102 +* Added GoogleOAuth2Service.
  103 +* Added YandexOAuth2Service.
  104 +* Added session token storage using Yii session.
  105 +
  106 +### 30.08.2013
  107 +* Initial release for Yii2.
... ...
common/components/nodge/eauth/LICENSE 0 → 100644
  1 +Copyright (c) 2011, Maxim Zemskov
  2 +All rights reserved.
  3 +
  4 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  5 +
  6 +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  7 +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  8 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 9 \ No newline at end of file
... ...
common/components/nodge/eauth/README.md 0 → 100644
  1 +Yii2 EAuth extension
  2 +====================
  3 +
  4 +EAuth extension allows to authenticate users with accounts on other websites.
  5 +Supported protocols: OpenID, OAuth 1.0 and OAuth 2.0.
  6 +
  7 +EAuth is an extension to provide a unified (does not depend on the selected service) method to authenticate the user. The extension itself does not perform login, does not register the user and does not bind the user accounts from different providers.
  8 +
  9 +* [Demo](http://nodge.ru/yii-eauth/demo2/)
  10 +* [Demo project](https://github.com/Nodge/yii2-eauth-demo/)
  11 +* [Installation](#installation)
  12 +* [Version for yii 1.1](https://github.com/Nodge/yii-eauth/)
  13 +
  14 +### Why own extension and not a third-party service?
  15 +The implementation of the authorization on your own server has several advantages:
  16 +
  17 +* Full control over the process: What will be written in the authorization window, what data we get, etc.
  18 +* Ability to change the appearance of the widget.
  19 +* When logging in via OAuth, it is possible to invoke methods on the API.
  20 +* Fewer dependencies on third-party services - more reliable application.
  21 +
  22 +
  23 +### The extension allows you to:
  24 +
  25 +* Ignore the nuances of authorization through the different types of services and use the class based adapters for each service.
  26 +* Get a unique user ID that can be used to register the user in your application.
  27 +* Extend the standard authorization classes to obtain additional data about the user.
  28 +* Work with the API of social networks by extending the authorization classes.
  29 +* Set up a list of supported services, customize the appearance of the widget, use the popup window without closing your application.
  30 +
  31 +
  32 +### Extension includes:
  33 +
  34 +* The component that contains utility functions.
  35 +* A widget that displays a list of services in the form of icons and allowing authorization in the popup window.
  36 +* Base classes to create your own services.
  37 +* Ready to authenticate via Google, Twitter, Facebook and other providers.
  38 +
  39 +
  40 +### Included services:
  41 +
  42 +* OpenID:
  43 + * Yahoo
  44 + * Steam
  45 +* OAuth1:
  46 + * Twitter
  47 + * LinkedIn
  48 +* OAuth2:
  49 + * Google
  50 + * Facebook
  51 + * Live
  52 + * GitHub
  53 + * LinkedIn
  54 + * Instagram
  55 + * Yandex (ru)
  56 + * VKontake (ru)
  57 + * Mail.ru (ru)
  58 + * Odnoklassniki (ru)
  59 +
  60 +
  61 +### Resources
  62 +
  63 +* [Yii EAuth](https://github.com/Nodge/yii2-eauth)
  64 +* [Demo](http://nodge.ru/yii-eauth/demo2/)
  65 +* [Demo project](https://github.com/Nodge/yii2-eauth-demo/)
  66 +* [Yii Framework](http://yiiframework.com/)
  67 +* [OpenID](http://openid.net/)
  68 +* [OAuth](http://oauth.net/)
  69 +* [OAuth 2.0](http://oauth.net/2/)
  70 +* [LightOpenID](https://github.com/iignatov/LightOpenID)
  71 +* [PHPoAuthLib](https://github.com/Lusitanian/PHPoAuthLib)
  72 +
  73 +
  74 +### Requirements
  75 +
  76 +* Yii 2.0 or above
  77 +* curl php extension
  78 +* LightOpenId
  79 +* PHPoAuthLib
  80 +
  81 +
  82 +# Installation
  83 +
  84 +This library can be found on [Packagist](https://packagist.org/packages/nodge/yii2-eauth).
  85 +The recommended way to install this is through [composer](http://getcomposer.org).
  86 +
  87 +Edit your `composer.json` and add:
  88 +
  89 +```json
  90 +{
  91 + "require": {
  92 + "nodge/yii2-eauth": "~2.0"
  93 + }
  94 +}
  95 +```
  96 +
  97 +And install dependencies:
  98 +
  99 +```bash
  100 +$ curl -sS https://getcomposer.org/installer | php
  101 +$ php composer.phar install
  102 +```
  103 +
  104 +
  105 +# Usage
  106 +
  107 +## Demo project
  108 +
  109 +The source code of the [demo](http://nodge.ru/yii-eauth/demo2/) is available [here](https://github.com/Nodge/yii2-eauth-demo/).
  110 +
  111 +
  112 +## Basic setup
  113 +
  114 +### Configuration
  115 +
  116 +Add the following in your config:
  117 +
  118 +```php
  119 +<?php
  120 +...
  121 + 'components' => [
  122 + 'eauth' => [
  123 + 'class' => 'nodge\eauth\EAuth',
  124 + 'popup' => true, // Use the popup window instead of redirecting.
  125 + 'cache' => false, // Cache component name or false to disable cache. Defaults to 'cache' on production environments.
  126 + 'cacheExpire' => 0, // Cache lifetime. Defaults to 0 - means unlimited.
  127 + 'httpClient' => [
  128 + // uncomment this to use streams in safe_mode
  129 + //'useStreamsFallback' => true,
  130 + ],
  131 + 'services' => [ // You can change the providers and their classes.
  132 + 'google' => [
  133 + // register your app here: https://code.google.com/apis/console/
  134 + 'class' => 'nodge\eauth\services\GoogleOAuth2Service',
  135 + 'clientId' => '...',
  136 + 'clientSecret' => '...',
  137 + 'title' => 'Google',
  138 + ],
  139 + 'twitter' => [
  140 + // register your app here: https://dev.twitter.com/apps/new
  141 + 'class' => 'nodge\eauth\services\TwitterOAuth1Service',
  142 + 'key' => '...',
  143 + 'secret' => '...',
  144 + ],
  145 + 'yandex' => [
  146 + // register your app here: https://oauth.yandex.ru/client/my
  147 + 'class' => 'nodge\eauth\services\YandexOAuth2Service',
  148 + 'clientId' => '...',
  149 + 'clientSecret' => '...',
  150 + 'title' => 'Yandex',
  151 + ],
  152 + 'facebook' => [
  153 + // register your app here: https://developers.facebook.com/apps/
  154 + 'class' => 'nodge\eauth\services\FacebookOAuth2Service',
  155 + 'clientId' => '...',
  156 + 'clientSecret' => '...',
  157 + ],
  158 + 'yahoo' => [
  159 + 'class' => 'nodge\eauth\services\YahooOpenIDService',
  160 + //'realm' => '*.example.org', // your domain, can be with wildcard to authenticate on subdomains.
  161 + ],
  162 + 'linkedin' => [
  163 + // register your app here: https://www.linkedin.com/secure/developer
  164 + 'class' => 'nodge\eauth\services\LinkedinOAuth1Service',
  165 + 'key' => '...',
  166 + 'secret' => '...',
  167 + 'title' => 'LinkedIn (OAuth1)',
  168 + ],
  169 + 'linkedin_oauth2' => [
  170 + // register your app here: https://www.linkedin.com/secure/developer
  171 + 'class' => 'nodge\eauth\services\LinkedinOAuth2Service',
  172 + 'clientId' => '...',
  173 + 'clientSecret' => '...',
  174 + 'title' => 'LinkedIn (OAuth2)',
  175 + ],
  176 + 'github' => [
  177 + // register your app here: https://github.com/settings/applications
  178 + 'class' => 'nodge\eauth\services\GitHubOAuth2Service',
  179 + 'clientId' => '...',
  180 + 'clientSecret' => '...',
  181 + ],
  182 + 'live' => [
  183 + // register your app here: https://account.live.com/developers/applications/index
  184 + 'class' => 'nodge\eauth\services\LiveOAuth2Service',
  185 + 'clientId' => '...',
  186 + 'clientSecret' => '...',
  187 + ],
  188 + 'steam' => [
  189 + 'class' => 'nodge\eauth\services\SteamOpenIDService',
  190 + //'realm' => '*.example.org', // your domain, can be with wildcard to authenticate on subdomains.
  191 + ],
  192 + 'instagram' => [
  193 + // register your app here: https://instagram.com/developer/register/
  194 + 'class' => 'nodge\eauth\services\InstagramOAuth2Service',
  195 + 'clientId' => '...',
  196 + 'clientSecret' => '...',
  197 + ],
  198 + 'vkontakte' => [
  199 + // register your app here: https://vk.com/editapp?act=create&site=1
  200 + 'class' => 'nodge\eauth\services\VKontakteOAuth2Service',
  201 + 'clientId' => '...',
  202 + 'clientSecret' => '...',
  203 + ],
  204 + 'mailru' => [
  205 + // register your app here: http://api.mail.ru/sites/my/add
  206 + 'class' => 'nodge\eauth\services\MailruOAuth2Service',
  207 + 'clientId' => '...',
  208 + 'clientSecret' => '...',
  209 + ],
  210 + 'odnoklassniki' => [
  211 + // register your app here: http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=13992188
  212 + // ... or here: http://www.odnoklassniki.ru/dk?st.cmd=appsInfoMyDevList&st._aid=Apps_Info_MyDev
  213 + 'class' => 'nodge\eauth\services\OdnoklassnikiOAuth2Service',
  214 + 'clientId' => '...',
  215 + 'clientSecret' => '...',
  216 + 'clientPublic' => '...',
  217 + 'title' => 'Odnoklas.',
  218 + ],
  219 + ],
  220 + ],
  221 +
  222 + 'i18n' => [
  223 + 'translations' => [
  224 + 'eauth' => [
  225 + 'class' => 'yii\i18n\PhpMessageSource',
  226 + 'basePath' => '@eauth/messages',
  227 + ],
  228 + ],
  229 + ],
  230 +
  231 + // (optionally) you can configure pretty urls
  232 + 'urlManager' => [
  233 + 'enablePrettyUrl' => true,
  234 + 'showScriptName' => false,
  235 + 'rules' => [
  236 + 'login/<service:google|facebook|etc>' => 'site/login',
  237 + ],
  238 + ],
  239 +
  240 + // (optionally) you can configure logging
  241 + 'log' => [
  242 + 'targets' => [
  243 + [
  244 + 'class' => 'yii\log\FileTarget',
  245 + 'logFile' => '@app/runtime/logs/eauth.log',
  246 + 'categories' => ['nodge\eauth\*'],
  247 + 'logVars' => [],
  248 + ],
  249 + ],
  250 + ],
  251 + ...
  252 + ],
  253 +...
  254 +```
  255 +
  256 +### User model
  257 +
  258 +You need to modify your User model to login with EAuth services.
  259 +Example from demo project:
  260 +
  261 +```php
  262 +<?php
  263 +...
  264 + /**
  265 + * @var array EAuth attributes
  266 + */
  267 + public $profile;
  268 +
  269 + public static function findIdentity($id) {
  270 + if (Yii::$app->getSession()->has('user-'.$id)) {
  271 + return new self(Yii::$app->getSession()->get('user-'.$id));
  272 + }
  273 + else {
  274 + return isset(self::$users[$id]) ? new self(self::$users[$id]) : null;
  275 + }
  276 + }
  277 +
  278 + /**
  279 + * @param \nodge\eauth\ServiceBase $service
  280 + * @return User
  281 + * @throws ErrorException
  282 + */
  283 + public static function findByEAuth($service) {
  284 + if (!$service->getIsAuthenticated()) {
  285 + throw new ErrorException('EAuth user should be authenticated before creating identity.');
  286 + }
  287 +
  288 + $id = $service->getServiceName().'-'.$service->getId();
  289 + $attributes = [
  290 + 'id' => $id,
  291 + 'username' => $service->getAttribute('name'),
  292 + 'authKey' => md5($id),
  293 + 'profile' => $service->getAttributes(),
  294 + ];
  295 + $attributes['profile']['service'] = $service->getServiceName();
  296 + Yii::$app->getSession()->set('user-'.$id, $attributes);
  297 + return new self($attributes);
  298 + }
  299 +...
  300 +```
  301 +
  302 +Then you can access to EAuth attributes through:
  303 +
  304 +```php
  305 +<?php
  306 + $identity = Yii::$app->getUser()->getIdentity();
  307 + if (isset($identity->profile)) {
  308 + VarDumper::dump($identity->profile, 10, true);
  309 + }
  310 +```
  311 +
  312 +### Controller
  313 +
  314 +Attach OpenID Controller behavior to disable CSRF validation for OpenID callbacks.
  315 +Or you can disable CSRF validation by yourself.
  316 +
  317 +```php
  318 +<?php
  319 +...
  320 + public function behaviors() {
  321 + return [
  322 + 'eauth' => [
  323 + // required to disable csrf validation on OpenID requests
  324 + 'class' => \nodge\eauth\openid\ControllerBehavior::className(),
  325 + 'only' => ['login'],
  326 + ],
  327 + ];
  328 + }
  329 +...
  330 +```
  331 +
  332 +Add the following to your Login action:
  333 +
  334 +```php
  335 +<?php
  336 +...
  337 + public function actionLogin() {
  338 + $serviceName = Yii::$app->getRequest()->getQueryParam('service');
  339 + if (isset($serviceName)) {
  340 + /** @var $eauth \nodge\eauth\ServiceBase */
  341 + $eauth = Yii::$app->get('eauth')->getIdentity($serviceName);
  342 + $eauth->setRedirectUrl(Yii::$app->getUser()->getReturnUrl());
  343 + $eauth->setCancelUrl(Yii::$app->getUrlManager()->createAbsoluteUrl('site/login'));
  344 +
  345 + try {
  346 + if ($eauth->authenticate()) {
  347 +// var_dump($eauth->getIsAuthenticated(), $eauth->getAttributes()); exit;
  348 +
  349 + $identity = User::findByEAuth($eauth);
  350 + Yii::$app->getUser()->login($identity);
  351 +
  352 + // special redirect with closing popup window
  353 + $eauth->redirect();
  354 + }
  355 + else {
  356 + // close popup window and redirect to cancelUrl
  357 + $eauth->cancel();
  358 + }
  359 + }
  360 + catch (\nodge\eauth\ErrorException $e) {
  361 + // save error to show it later
  362 + Yii::$app->getSession()->setFlash('error', 'EAuthException: '.$e->getMessage());
  363 +
  364 + // close popup window and redirect to cancelUrl
  365 +// $eauth->cancel();
  366 + $eauth->redirect($eauth->getCancelUrl());
  367 + }
  368 + }
  369 +
  370 + // default authorization code through login/password ..
  371 + }
  372 +...
  373 +```
  374 +
  375 +### View
  376 +
  377 +```php
  378 +...
  379 +<?php
  380 + if (Yii::$app->getSession()->hasFlash('error')) {
  381 + echo '<div class="alert alert-danger">'.Yii::$app->getSession()->getFlash('error').'</div>';
  382 + }
  383 +?>
  384 +...
  385 +<p class="lead">Do you already have an account on one of these sites? Click the logo to log in with it here:</p>
  386 +<?php echo \nodge\eauth\Widget::widget(['action' => 'site/login']); ?>
  387 +...
  388 +```
  389 +
  390 +
  391 +## Extending
  392 +
  393 +To receive all the necessary data to your application, you can override the base class of any provider.
  394 +Base classes are stored in `@eauth/src/services`.
  395 +Examples of extended classes can be found in `@eauth/src/services/extended/`.
  396 +
  397 +After overriding the base class, you need to update your configuration file with a new class name.
  398 +
  399 +
  400 +## Working with OAuth API
  401 +
  402 +You can extend base classes with necessary methods and then write something like this:
  403 +
  404 +```php
  405 +<?php
  406 + /** @var $eauth EAuthServiceBase */
  407 + $eauth = Yii::$app->eauth->getIdentity('facebook');
  408 +
  409 + // to get protected resources user should be authenticated:
  410 + if ($eauth->getIsAuthenticated()) {
  411 + $eauth->callProtectedApiMethod();
  412 + $eauth->callAnotherProtectedApiMethod();
  413 + }
  414 +
  415 + // or you can get public resources at any time:
  416 + $eauth->callPublicApiMethod();
  417 + $eauth->callAnotherPublicApiMethod();
  418 +```
  419 +
  420 +Example of an API call method:
  421 +
  422 +```php
  423 +<?php
  424 + class FacebookOAuth2Service extends \nodge\eauth\services\FacebookOAuth2Service
  425 + {
  426 + public function fooApiMethod($bar) {
  427 + $api_method = 'me'; // ex. for Facebook this results to https://graph.facebook.com/me
  428 +
  429 + // get protected resource
  430 + $response = $this->makeSignedRequest($api_method, [
  431 + 'query' => [ 'foo' => 'bar' ], // GET arguments
  432 + 'data' => [ 'foo' => 'bar' ], // POST arguments
  433 + 'headers' => [ 'X-Foo' => 'bar' ], // Extra HTTP headers
  434 + ]);
  435 +
  436 + // you can get public resources with the same API:
  437 + //$response = $this->makeRequest($api_method, $options);
  438 +
  439 + // process $response
  440 + $data = process($response);
  441 +
  442 + // return results
  443 + return $data;
  444 + }
  445 + }
  446 +```
  447 +
  448 +API calls are performed if the current user has a valid access token (saved during the authentication).
  449 +You can save access_token to your database by using custom token storage in your config:
  450 +
  451 +```php
  452 +<?php
  453 +...
  454 + 'components' => [
  455 + 'eauth' => [
  456 + 'class' => 'nodge\eauth\EAuth',
  457 + 'tokenStorage' => [
  458 + 'class' => '@app\eauth\DatabaseTokenStorage',
  459 + ],
  460 + ],
  461 + ...
  462 + ],
  463 +...
  464 +```
  465 +
  466 +
  467 +## Translation
  468 +
  469 +To use translations, add the following in your config:
  470 +
  471 +```php
  472 +<?php
  473 +...
  474 + 'components' => [
  475 + 'i18n' => [
  476 + 'translations' => [
  477 + 'eauth' => [
  478 + 'class' => 'yii\i18n\PhpMessageSource',
  479 + 'basePath' => '@eauth/messages',
  480 + ],
  481 + ],
  482 + ],
  483 + ...
  484 + ],
  485 +...
  486 +```
  487 +
  488 +Available translations can be found in `@eauth/src/messages`.
  489 +
  490 +
  491 +# License
  492 +
  493 +The extension was released under the [New BSD License](http://www.opensource.org/licenses/bsd-license.php), so you'll find the latest version on [GitHub](https://github.com/Nodge/yii2-eauth).
... ...
common/components/nodge/eauth/composer.json 0 → 100644
  1 +{
  2 + "name": "nodge/yii2-eauth",
  3 + "description": "Yii2 EAuth Extension. EAuth allows to authenticate users with accounts on other websites (Google, Facebook, Twitter, etc).",
  4 + "keywords": ["yii2", "extension", "eauth", "openid", "oauth", "authentication"],
  5 + "homepage": "https://github.com/Nodge/yii2-eauth",
  6 + "type": "yii2-extension",
  7 + "license": "New BSD License",
  8 + "authors": [
  9 + {
  10 + "name": "Maxim Zemskov",
  11 + "email": "nodge@yandex.ru",
  12 + "homepage": "http://nodge.ru/"
  13 + }
  14 + ],
  15 + "support": {
  16 + "source": "https://github.com/nodge/yii2-eauth"
  17 + },
  18 + "autoload": {
  19 + "psr-4": {
  20 + "common\modules\nodge\\eauth\\": "src/"
  21 + }
  22 + },
  23 + "require": {
  24 + "php": ">=5.4.0",
  25 + "lib-curl": "*",
  26 + "yiisoft/yii2": "*",
  27 + "lusitanian/oauth": "~0.3.0",
  28 + "nodge/lightopenid": "~1.1.0"
  29 + },
  30 + "extra": {
  31 + "bootstrap": "common\modules\nodge\\eauth\\Bootstrap"
  32 + }
  33 +}
0 34 \ No newline at end of file
... ...
common/components/nodge/eauth/src/Bootstrap.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Extension class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\modules\nodge\eauth\src\eauth;
  11 +
  12 +use Yii;
  13 +use yii\base\Application;
  14 +use yii\base\BootstrapInterface;
  15 +
  16 +/**
  17 + * This is the bootstrap class for the yii2-eauth extension.
  18 + */
  19 +class Bootstrap implements BootstrapInterface
  20 +{
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public function bootstrap($app)
  25 + {
  26 + Yii::setAlias('@eauth', __DIR__);
  27 + }
  28 +}
0 29 \ No newline at end of file
... ...
common/components/nodge/eauth/src/EAuth.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * EAuth class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\components\nodge\eauth\src;
  11 +
  12 +use Yii;
  13 +use yii\base\Object;
  14 +use yii\helpers\ArrayHelper;
  15 +use yii\helpers\Url;
  16 +
  17 +/**
  18 + * The EAuth class provides simple authentication via OpenID and OAuth providers.
  19 + *
  20 + * @package application.extensions.eauth
  21 + */
  22 +class EAuth extends Object
  23 +{
  24 +
  25 + /**
  26 + * @var array Authorization services and their settings.
  27 + */
  28 + protected $services = [];
  29 +
  30 + /**
  31 + * @var boolean Whether to use popup window for the authorization dialog.
  32 + */
  33 + protected $popup = true;
  34 +
  35 + /**
  36 + * @var string|bool Cache component name to use. False to disable cache.
  37 + */
  38 + public $cache = null;
  39 +
  40 + /**
  41 + * @var integer the number of seconds in which the cached value will expire. 0 means never expire.
  42 + */
  43 + public $cacheExpire = 0;
  44 +
  45 + /**
  46 + * @var string popup redirect view with custom js code
  47 + */
  48 + protected $redirectWidget = '\\nodge\\eauth\\RedirectWidget';
  49 +
  50 + /**
  51 + * @var array TokenStorage class.
  52 + */
  53 + protected $tokenStorage = [
  54 + 'class' => 'nodge\eauth\oauth\SessionTokenStorage',
  55 + ];
  56 +
  57 + /**
  58 + * @var array HttpClient class.
  59 + */
  60 + protected $httpClient = [
  61 + 'class' => 'nodge\eauth\oauth\HttpClient',
  62 +// 'useStreamsFallback' => false,
  63 + ];
  64 +
  65 + /**
  66 + * Initialize the component.
  67 + */
  68 + public function init()
  69 + {
  70 + parent::init();
  71 +
  72 + // set default cache on production environments
  73 + if (!isset($this->cache) && YII_ENV_PROD) {
  74 + $this->cache = 'cache';
  75 + }
  76 + }
  77 +
  78 + /**
  79 + * @param array $services
  80 + */
  81 + public function setServices($services)
  82 + {
  83 + $this->services = $services;
  84 + }
  85 +
  86 + /**
  87 + * Returns services settings declared in the authorization classes.
  88 + * For perfomance reasons it uses cache to store settings array.
  89 + *
  90 + * @return \stdClass[] services settings.
  91 + */
  92 + public function getServices()
  93 + {
  94 + $services = false;
  95 + if (!empty($this->cache) && Yii::$app->has($this->cache)) {
  96 + /** @var $cache \yii\caching\Cache */
  97 + $cache = Yii::$app->get($this->cache);
  98 + $services = $cache->get('EAuth.services');
  99 + }
  100 +
  101 + if (false === $services || !is_array($services)) {
  102 + $services = [];
  103 + foreach ($this->services as $service => $options) {
  104 + /** @var $class ServiceBase */
  105 + $class = $this->getIdentity($service);
  106 + $services[$service] = (object)[
  107 + 'id' => $class->getServiceName(),
  108 + 'title' => $class->getServiceTitle(),
  109 + 'type' => $class->getServiceType(),
  110 + 'jsArguments' => $class->getJsArguments(),
  111 + ];
  112 + }
  113 + if (isset($cache)) {
  114 + $cache->set('EAuth.services', $services, $this->cacheExpire);
  115 + }
  116 + }
  117 + return $services;
  118 + }
  119 +
  120 + /**
  121 + * @param bool $usePopup
  122 + */
  123 + public function setPopup($usePopup)
  124 + {
  125 + $this->popup = $usePopup;
  126 + }
  127 +
  128 + /**
  129 + * @return bool
  130 + */
  131 + public function getPopup()
  132 + {
  133 + return $this->popup;
  134 + }
  135 +
  136 + /**
  137 + * @param string|bool $cache
  138 + */
  139 + public function setCache($cache)
  140 + {
  141 + $this->cache = $cache;
  142 + }
  143 +
  144 + /**
  145 + * @return string|bool
  146 + */
  147 + public function getCache()
  148 + {
  149 + return $this->cache;
  150 + }
  151 +
  152 + /**
  153 + * @param int $cacheExpire
  154 + */
  155 + public function setCacheExpire($cacheExpire)
  156 + {
  157 + $this->cacheExpire = $cacheExpire;
  158 + }
  159 +
  160 + /**
  161 + * @return int
  162 + */
  163 + public function getCacheExpire()
  164 + {
  165 + return $this->cacheExpire;
  166 + }
  167 +
  168 + /**
  169 + * @param string $redirectWidget
  170 + */
  171 + public function setRedirectWidget($redirectWidget)
  172 + {
  173 + $this->redirectWidget = $redirectWidget;
  174 + }
  175 +
  176 + /**
  177 + * @return string
  178 + */
  179 + public function getRedirectWidget()
  180 + {
  181 + return $this->redirectWidget;
  182 + }
  183 +
  184 + /**
  185 + * @param array $config
  186 + */
  187 + public function setTokenStorage(array $config)
  188 + {
  189 + $this->tokenStorage = ArrayHelper::merge($this->tokenStorage, $config);
  190 + }
  191 +
  192 + /**
  193 + * @return array
  194 + */
  195 + public function getTokenStorage()
  196 + {
  197 + return $this->tokenStorage;
  198 + }
  199 +
  200 + /**
  201 + * @param array $config
  202 + */
  203 + public function setHttpClient(array $config)
  204 + {
  205 + $this->httpClient = ArrayHelper::merge($this->httpClient, $config);
  206 + }
  207 +
  208 + /**
  209 + * @return array
  210 + */
  211 + public function getHttpClient()
  212 + {
  213 + return $this->httpClient;
  214 + }
  215 +
  216 + /**
  217 + * Returns the settings of the service.
  218 + *
  219 + * @param string $service the service name.
  220 + * @return \stdClass the service settings.
  221 + * @throws ErrorException
  222 + */
  223 + protected function getService($service)
  224 + {
  225 + $service = strtolower($service);
  226 + $services = $this->getServices();
  227 + if (!isset($services[$service])) {
  228 + throw new ErrorException(Yii::t('eauth', 'Undefined service name: {service}.', ['service' => $service]), 500);
  229 + }
  230 + return $services[$service];
  231 + }
  232 +
  233 + /**
  234 + * Returns the type of the service.
  235 + *
  236 + * @param string $service the service name.
  237 + * @return string the service type.
  238 + */
  239 + public function getServiceType($service)
  240 + {
  241 + $service = $this->getService($service);
  242 + return $service->type;
  243 + }
  244 +
  245 + /**
  246 + * Returns the service identity class.
  247 + *
  248 + * @param string $service the service name.
  249 + * @return IAuthService the identity class.
  250 + * @throws ErrorException
  251 + */
  252 + public function getIdentity($service)
  253 + {
  254 + $service = strtolower($service);
  255 + if (!isset($this->services[$service])) {
  256 + throw new ErrorException(Yii::t('eauth', 'Undefined service name: {service}.', ['service' => $service]), 500);
  257 + }
  258 + $service = $this->services[$service];
  259 +
  260 + $service['component'] = $this;
  261 +
  262 + /** @var $identity IAuthService */
  263 + $identity = Yii::createObject($service);
  264 + return $identity;
  265 + }
  266 +
  267 + /**
  268 + * Redirects to url. If the authorization dialog opened in the popup window,
  269 + * it will be closed instead of redirect. Set $jsRedirect=true if you want
  270 + * to redirect anyway.
  271 + *
  272 + * @param mixed $url url to redirect. Can be route or normal url. See {@link CHtml::normalizeUrl}.
  273 + * @param boolean $jsRedirect whether to use redirect while popup window is used. Defaults to true.
  274 + * @param array $params
  275 + */
  276 + public function redirect($url, $jsRedirect = true, $params = [])
  277 + {
  278 + /** @var RedirectWidget $widget */
  279 + $widget = Yii::createObject([
  280 + 'class' => $this->redirectWidget,
  281 + 'url' => Url::to($url),
  282 + 'redirect' => $jsRedirect,
  283 + 'params' => $params
  284 + ]);
  285 + ob_start();
  286 + $widget->run();
  287 + $output = ob_get_clean();
  288 + $response = Yii::$app->getResponse();
  289 + $response->content = $output;
  290 + $response->send();
  291 + exit();
  292 + }
  293 +
  294 + /**
  295 + * Serialize the identity class.
  296 + *
  297 + * @param ServiceBase $identity the class instance.
  298 + * @return string serialized value.
  299 + */
  300 + public function toString($identity)
  301 + {
  302 + return serialize($identity);
  303 + }
  304 +
  305 + /**
  306 + * Serialize the identity class.
  307 + *
  308 + * @param string $identity serialized value.
  309 + * @return ServiceBase the class instance.
  310 + */
  311 + public function fromString($identity)
  312 + {
  313 + return unserialize($identity);
  314 + }
  315 +
  316 +}
... ...
common/components/nodge/eauth/src/ErrorException.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * ErrorException class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\modules\nodge\eauth\src\eauth;
  11 +
  12 +class ErrorException extends \yii\base\ErrorException
  13 +{
  14 +
  15 +}
0 16 \ No newline at end of file
... ...
common/components/nodge/eauth/src/IAuthService.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * IAuthService interface file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\modules\nodge\eauth\src\eauth;
  11 +
  12 +/**
  13 + * IAuthService is the interface for all service types and providers.
  14 + *
  15 + * @package application.extensions.eauth
  16 + */
  17 +interface IAuthService
  18 +{
  19 +
  20 + /**
  21 + * Returns service name(id).
  22 + */
  23 + public function getServiceName();
  24 +
  25 + /**
  26 + * Returns service title.
  27 + */
  28 + public function getServiceTitle();
  29 +
  30 + /**
  31 + * Returns service type (e.g. OpenID, OAuth).
  32 + */
  33 + public function getServiceType();
  34 +
  35 + /**
  36 + * Returns arguments for the jQuery.eauth() javascript function.
  37 + */
  38 + public function getJsArguments();
  39 +
  40 +
  41 + /**
  42 + * Sets {@link EAuth} application component
  43 + *
  44 + * @param EAuth $component the application auth component.
  45 + */
  46 + public function setComponent($component);
  47 +
  48 + /**
  49 + * Returns the {@link EAuth} application component.
  50 + */
  51 + public function getComponent();
  52 +
  53 +
  54 + /**
  55 + * Sets redirect url after successful authorization.
  56 + *
  57 + * @param string $url url to redirect.
  58 + */
  59 + public function setRedirectUrl($url);
  60 +
  61 + /**
  62 + * Returns the redirect url after successful authorization.
  63 + */
  64 + public function getRedirectUrl();
  65 +
  66 +
  67 + /**
  68 + * Sets redirect url after unsuccessful authorization (e.g. user canceled).
  69 + *
  70 + * @param string $url url to redirect.
  71 + */
  72 + public function setCancelUrl($url);
  73 +
  74 + /**
  75 + * Returns the redirect url after unsuccessful authorization (e.g. user canceled).
  76 + */
  77 + public function getCancelUrl();
  78 +
  79 +
  80 + /**
  81 + * Authenticate the user.
  82 + */
  83 + public function authenticate();
  84 +
  85 + /**
  86 + * Whether user was successfuly authenticated.
  87 + */
  88 + public function getIsAuthenticated();
  89 +
  90 +
  91 + /**
  92 + * Redirect to the url. If url is null, {@link redirectUrl} will be used.
  93 + *
  94 + * @param string $url url to redirect.
  95 + */
  96 + public function redirect($url = null);
  97 +
  98 + /**
  99 + * Redirect to the {@link cancelUrl} or simply close the popup window.
  100 + */
  101 + public function cancel();
  102 +
  103 +
  104 + /**
  105 + * Returns the user unique id.
  106 + */
  107 + public function getId();
  108 +
  109 + /**
  110 + * Returns the array that contains all available authorization attributes.
  111 + */
  112 + public function getAttributes();
  113 +
  114 + /**
  115 + * Returns the authorization attribute value.
  116 + *
  117 + * @param string $key the attribute name.
  118 + * @param mixed $default the default value.
  119 + */
  120 + public function getAttribute($key, $default = null);
  121 +
  122 + /**
  123 + * Whether the authorization attribute exists.
  124 + *
  125 + * @param string $key the attribute name.
  126 + */
  127 + public function hasAttribute($key);
  128 +
  129 +}
0 130 \ No newline at end of file
... ...
common/components/nodge/eauth/src/RedirectWidget.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * AuthRedirectWidget class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\modules\nodge\eauth\src\eauth;
  11 +
  12 +use \Yii;
  13 +use yii\helpers\ArrayHelper;
  14 +
  15 +/**
  16 + * The EAuthRedirectWidget widget displays the redirect page after returning from provider.
  17 + *
  18 + * @package application.extensions.eauth
  19 + */
  20 +class RedirectWidget extends Widget
  21 +{
  22 +
  23 + /**
  24 + * @var mixed the widget mode. Default to "login".
  25 + */
  26 + public $url = null;
  27 +
  28 + /**
  29 + * @var boolean whether to use redirect inside the popup window.
  30 + */
  31 + public $redirect = true;
  32 +
  33 + /**
  34 + * @var string
  35 + */
  36 + public $view = 'redirect';
  37 +
  38 + /**
  39 + * @var array
  40 + */
  41 + public $params = [];
  42 +
  43 + /**
  44 + * Executes the widget.
  45 + */
  46 + public function run()
  47 + {
  48 + echo $this->render($this->view,
  49 + ArrayHelper::merge([
  50 + 'id' => $this->getId(),
  51 + 'url' => $this->url,
  52 + 'redirect' => $this->redirect,
  53 + ], $this->params)
  54 + );
  55 + }
  56 +}
... ...
common/components/nodge/eauth/src/ServiceBase.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * ServiceBase class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\modules\nodge\eauth\src\eauth;
  11 +
  12 +use Yii;
  13 +use yii\base\Object;
  14 +use yii\helpers\Url;
  15 +
  16 +/**
  17 + * EAuthServiceBase is a base class for providers.
  18 + *
  19 + * @package application.extensions.eauth
  20 + */
  21 +abstract class ServiceBase extends Object implements IAuthService
  22 +{
  23 +
  24 + /**
  25 + * @var string the service name.
  26 + */
  27 + protected $name;
  28 +
  29 + /**
  30 + *
  31 + * @var string the service title to display in views.
  32 + */
  33 + protected $title;
  34 +
  35 + /**
  36 + * @var string the service type (e.g. OpenID, OAuth).
  37 + */
  38 + protected $type;
  39 +
  40 + /**
  41 + * @var array arguments for the jQuery.eauth() javascript function.
  42 + */
  43 + protected $jsArguments = [];
  44 +
  45 + /**
  46 + * @var array authorization attributes.
  47 + * @see getAttribute
  48 + * @see getItem
  49 + */
  50 + protected $attributes = [];
  51 +
  52 + /**
  53 + * @var boolean whether user was successfuly authenticated.
  54 + * @see getIsAuthenticated
  55 + */
  56 + protected $authenticated = false;
  57 +
  58 + /**
  59 + * @var boolean whether is attributes was fetched.
  60 + */
  61 + private $fetched = false;
  62 +
  63 + /**
  64 + * @var EAuth the {@link EAuth} application component.
  65 + */
  66 + private $component;
  67 +
  68 + /**
  69 + * @var string the redirect url after successful authorization.
  70 + */
  71 + private $redirectUrl = '';
  72 +
  73 + /**
  74 + * @var string the redirect url after unsuccessful authorization (e.g. user canceled).
  75 + */
  76 + private $cancelUrl = '';
  77 +
  78 + /**
  79 + * PHP getter magic method.
  80 + * This method is overridden so that service attributes can be accessed like properties.
  81 + *
  82 + * @param string $name property name.
  83 + * @return mixed property value.
  84 + * @see getAttribute
  85 + */
  86 + public function __get($name)
  87 + {
  88 + if ($this->hasAttribute($name)) {
  89 + return $this->getAttribute($name);
  90 + } else {
  91 + return parent::__get($name);
  92 + }
  93 + }
  94 +
  95 + /**
  96 + * Checks if a attribute value is null.
  97 + * This method overrides the parent implementation by checking
  98 + * if the attribute is null or not.
  99 + *
  100 + * @param string $name the attribute name.
  101 + * @return boolean whether the attribute value is null.
  102 + */
  103 + public function __isset($name)
  104 + {
  105 + if ($this->hasAttribute($name)) {
  106 + return true;
  107 + } else {
  108 + return parent::__isset($name);
  109 + }
  110 + }
  111 +
  112 + /**
  113 + * Initialize the component.
  114 + * Sets the default {@link redirectUrl} and {@link cancelUrl}.
  115 + */
  116 + public function init()
  117 + {
  118 + parent::init();
  119 +
  120 + $this->setRedirectUrl(Yii::$app->getUser()->getReturnUrl());
  121 +
  122 + $service = Yii::$app->getRequest()->getQueryParam('service');
  123 + $cancelUrl = Url::to(['', 'service' => $service], true);
  124 +
  125 + $this->setCancelUrl($cancelUrl);
  126 + }
  127 +
  128 + /**
  129 + * Returns service name(id).
  130 + *
  131 + * @return string the service name(id).
  132 + */
  133 + public function getServiceName()
  134 + {
  135 + return $this->name;
  136 + }
  137 +
  138 + /**
  139 + * Returns service title.
  140 + *
  141 + * @return string the service title.
  142 + */
  143 + public function getServiceTitle()
  144 + {
  145 + return Yii::t('eauth', $this->title);
  146 + }
  147 +
  148 + /**
  149 + * Returns service type (e.g. OpenID, OAuth).
  150 + *
  151 + * @return string the service type (e.g. OpenID, OAuth).
  152 + */
  153 + public function getServiceType()
  154 + {
  155 + return $this->type;
  156 + }
  157 +
  158 + /**
  159 + * Returns arguments for the jQuery.eauth() javascript function.
  160 + *
  161 + * @return array the arguments for the jQuery.eauth() javascript function.
  162 + */
  163 + public function getJsArguments()
  164 + {
  165 + return $this->jsArguments;
  166 + }
  167 +
  168 + /**
  169 + * Sets {@link EAuth} application component
  170 + *
  171 + * @param EAuth $component the application auth component.
  172 + */
  173 + public function setComponent($component)
  174 + {
  175 + $this->component = $component;
  176 + }
  177 +
  178 + /**
  179 + * Returns the {@link EAuth} application component.
  180 + *
  181 + * @return EAuth the {@link EAuth} application component.
  182 + */
  183 + public function getComponent()
  184 + {
  185 + return $this->component;
  186 + }
  187 +
  188 + /**
  189 + * Sets redirect url after successful authorization.
  190 + *
  191 + * @param string $url to redirect.
  192 + */
  193 + public function setRedirectUrl($url)
  194 + {
  195 + $this->redirectUrl = $url;
  196 + }
  197 +
  198 + /**
  199 + * @return string the redirect url after successful authorization.
  200 + */
  201 + public function getRedirectUrl()
  202 + {
  203 + return $this->redirectUrl;
  204 + }
  205 +
  206 + /**
  207 + * Sets redirect url after unsuccessful authorization (e.g. user canceled).
  208 + *
  209 + * @param string $url
  210 + */
  211 + public function setCancelUrl($url)
  212 + {
  213 + $this->cancelUrl = $url;
  214 + }
  215 +
  216 + /**
  217 + * @return string the redirect url after unsuccessful authorization (e.g. user canceled).
  218 + */
  219 + public function getCancelUrl()
  220 + {
  221 + return $this->cancelUrl;
  222 + }
  223 +
  224 + /**
  225 + * @param string $title
  226 + */
  227 + public function setTitle($title)
  228 + {
  229 + $this->title = $title;
  230 + }
  231 +
  232 + /**
  233 + * Authenticate the user.
  234 + *
  235 + * @return boolean whether user was successfuly authenticated.
  236 + */
  237 + public function authenticate()
  238 + {
  239 + return $this->getIsAuthenticated();
  240 + }
  241 +
  242 + /**
  243 + * Whether user was successfuly authenticated.
  244 + *
  245 + * @return boolean whether user was successfuly authenticated.
  246 + */
  247 + public function getIsAuthenticated()
  248 + {
  249 + return $this->authenticated;
  250 + }
  251 +
  252 + /**
  253 + * Redirect to the url. If url is null, {@link redirectUrl} will be used.
  254 + *
  255 + * @param string $url url to redirect.
  256 + * @param array $params
  257 + */
  258 + public function redirect($url = null, $params = [])
  259 + {
  260 + $this->component->redirect(isset($url) ? $url : $this->redirectUrl, true, $params);
  261 + }
  262 +
  263 + /**
  264 + * Redirect to the {@link cancelUrl} or simply close the popup window.
  265 + */
  266 + public function cancel($url = null)
  267 + {
  268 + $this->component->redirect(isset($url) ? $url : $this->cancelUrl, !$this->component->popup);
  269 + }
  270 +
  271 + /**
  272 + * Fetch attributes array.
  273 + *
  274 + * @return boolean whether the attributes was successfully fetched.
  275 + */
  276 + protected function fetchAttributes()
  277 + {
  278 + return true;
  279 + }
  280 +
  281 + /**
  282 + * Fetch attributes array.
  283 + * This function is internally used to handle fetched state.
  284 + */
  285 + protected function _fetchAttributes()
  286 + {
  287 + if (!$this->fetched) {
  288 + $this->fetched = true;
  289 + $result = $this->fetchAttributes();
  290 + if (isset($result)) {
  291 + $this->fetched = $result;
  292 + }
  293 + }
  294 + }
  295 +
  296 + /**
  297 + * Returns the user unique id.
  298 + *
  299 + * @return mixed the user id.
  300 + */
  301 + public function getId()
  302 + {
  303 + $this->_fetchAttributes();
  304 + return $this->attributes['id'];
  305 + }
  306 +
  307 + /**
  308 + * Returns the array that contains all available authorization attributes.
  309 + *
  310 + * @return array the attributes.
  311 + */
  312 + public function getAttributes()
  313 + {
  314 + $this->_fetchAttributes();
  315 + $attributes = [];
  316 + foreach ($this->attributes as $key => $val) {
  317 + $attributes[$key] = $this->getAttribute($key);
  318 + }
  319 + return $attributes;
  320 + }
  321 +
  322 + /**
  323 + * Returns the authorization attribute value.
  324 + *
  325 + * @param string $key the attribute name.
  326 + * @param mixed $default the default value.
  327 + * @return mixed the attribute value.
  328 + */
  329 + public function getAttribute($key, $default = null)
  330 + {
  331 + $this->_fetchAttributes();
  332 + $getter = 'get' . $key;
  333 + if (method_exists($this, $getter)) {
  334 + return $this->$getter();
  335 + } else {
  336 + return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
  337 + }
  338 + }
  339 +
  340 + /**
  341 + * Whether the authorization attribute exists.
  342 + *
  343 + * @param string $key the attribute name.
  344 + * @return boolean true if attribute exists, false otherwise.
  345 + */
  346 + public function hasAttribute($key)
  347 + {
  348 + $this->_fetchAttributes();
  349 + return isset($this->attributes[$key]);
  350 + }
  351 +
  352 + /**
  353 + * @return bool
  354 + */
  355 + public function getIsInsidePopup()
  356 + {
  357 + return isset($_GET['js']);
  358 + }
  359 +}
... ...
common/components/nodge/eauth/src/Widget.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Widget class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\modules\nodge\eauth\src\eauth;
  11 +
  12 +use Yii;
  13 +
  14 +/**
  15 + * The EAuthWidget widget prints buttons to authenticate user with OpenID and OAuth providers.
  16 + *
  17 + * @package application.extensions.eauth
  18 + */
  19 +class Widget extends \yii\base\Widget
  20 +{
  21 +
  22 + /**
  23 + * @var string EAuth component name.
  24 + */
  25 + public $component = 'eauth';
  26 +
  27 + /**
  28 + * @var array the services.
  29 + * @see EAuth::getServices()
  30 + */
  31 + public $services = null;
  32 +
  33 + /**
  34 + * @var array predefined services. If null then use all services. Default is null.
  35 + */
  36 + public $predefinedServices = null;
  37 +
  38 + /**
  39 + * @var boolean whether to use popup window for authorization dialog. Javascript required.
  40 + */
  41 + public $popup = null;
  42 +
  43 + /**
  44 + * @var string the action to use for dialog destination. Default: the current route.
  45 + */
  46 + public $action = null;
  47 +
  48 + /**
  49 + * @var boolean include the CSS file. Default is true.
  50 + * If this is set false, you are responsible to explicitly include the necessary CSS file in your page.
  51 + */
  52 + public $assetBundle = 'nodge\\eauth\\assets\\WidgetAssetBundle';
  53 +
  54 + /**
  55 + * Initializes the widget.
  56 + * This method is called by {@link CBaseController::createWidget}
  57 + * and {@link CBaseController::beginWidget} after the widget's
  58 + * properties have been initialized.
  59 + */
  60 + public function init()
  61 + {
  62 + parent::init();
  63 +
  64 + // EAuth component
  65 + /** @var $component \nodge\eauth\EAuth */
  66 + $component = Yii::$app->get($this->component);
  67 +
  68 + // Some default properties from component configuration
  69 + if (!isset($this->services)) {
  70 + $this->services = $component->getServices();
  71 + }
  72 +
  73 + if (is_array($this->predefinedServices)) {
  74 + $_services = [];
  75 + foreach ($this->predefinedServices as $_serviceName) {
  76 + if (isset($this->services[$_serviceName])) {
  77 + $_services[$_serviceName] = $this->services[$_serviceName];
  78 + }
  79 + }
  80 + $this->services = $_services;
  81 + }
  82 +
  83 + if (!isset($this->popup)) {
  84 + $this->popup = $component->popup;
  85 + }
  86 +
  87 + // Set the current route, if it is not set.
  88 + if (!isset($this->action)) {
  89 + $this->action = '/' . Yii::$app->requestedRoute;
  90 + }
  91 + }
  92 +
  93 + /**
  94 + * Executes the widget.
  95 + * This method is called by {@link CBaseController::endWidget}.
  96 + */
  97 + public function run()
  98 + {
  99 + parent::run();
  100 + echo $this->render('widget', [
  101 + 'id' => $this->getId(),
  102 + 'services' => $this->services,
  103 + 'action' => $this->action,
  104 + 'popup' => $this->popup,
  105 + 'assetBundle' => $this->assetBundle,
  106 + ]);
  107 + }
  108 +}
... ...
common/components/nodge/eauth/src/assets/WidgetAssetBundle.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * @link http://www.yiiframework.com/
  4 + * @copyright Copyright (c) 2008 Yii Software LLC
  5 + * @license http://www.yiiframework.com/license/
  6 + */
  7 +
  8 +namespace nodge\eauth\assets;
  9 +
  10 +use yii\web\AssetBundle;
  11 +
  12 +/**
  13 + * @author Qiang Xue <qiang.xue@gmail.com>
  14 + * @since 2.0
  15 + */
  16 +class WidgetAssetBundle extends AssetBundle
  17 +{
  18 + public $sourcePath = '@eauth/assets';
  19 + public $css = [
  20 + 'css/eauth.css',
  21 + ];
  22 + public $js = [
  23 + 'js/eauth.js',
  24 + ];
  25 + public $depends = [
  26 + 'yii\web\JqueryAsset',
  27 + ];
  28 +}
... ...
common/components/nodge/eauth/src/assets/css/eauth.css 0 → 100644
  1 +
  2 +.eauth {
  3 + overflow: hidden;
  4 +}
  5 +
  6 +.eauth-list {
  7 + margin: -1em 0 0;
  8 + padding: 0;
  9 + list-style: none;
  10 +}
  11 +
  12 +.eauth-service {
  13 + display: inline-block;
  14 + vertical-align: top;
  15 + margin: 1em 1em 0 0;
  16 +}
  17 +
  18 +.eauth-service-link {
  19 + position: relative;
  20 + display: block;
  21 + width: 60px;
  22 + padding-top: 34px;
  23 + text-align: center;
  24 +}
  25 +
  26 +.eauth-service-link:before,
  27 +.eauth-service-link:after {
  28 + content: '';
  29 + position: absolute;
  30 + top: 0;
  31 + left: 50%;
  32 + width: 32px;
  33 + height: 32px;
  34 + margin-left: -16px;
  35 + background: url("../images/auth.png") 0 0 no-repeat;
  36 +}
  37 +
  38 +.eauth-service-link:after {
  39 + display: none;
  40 +}
  41 +
  42 +.eauth-service-link:hover:after {
  43 + display: block;
  44 +}
  45 +
  46 +/* --- Services --- */
  47 +
  48 +.eauth-service-id-google_oauth .eauth-service-link:before {
  49 + background-position: 0 -34px;
  50 +}
  51 +
  52 +.eauth-service-id-yandex_oauth .eauth-service-link:before {
  53 + background-position: 0 -102px;
  54 +}
  55 +
  56 +.eauth-service-id-twitter .eauth-service-link:before {
  57 + background-position: 0 -68px;
  58 +}
  59 +
  60 +.eauth-service-id-vkontakte .eauth-service-link:before {
  61 + background-position: 0 -136px;
  62 +}
  63 +
  64 +.eauth-service-id-facebook .eauth-service-link:before {
  65 + background-position: 0 -170px;
  66 +}
  67 +
  68 +.eauth-service-id-mailru .eauth-service-link:before {
  69 + background-position: 0 -204px;
  70 +}
  71 +
  72 +.eauth-service-id-moikrug .eauth-service-link:before {
  73 + background-position: 0 -238px;
  74 +}
  75 +
  76 +.eauth-service-id-odnoklassniki .eauth-service-link:before {
  77 + background-position: 0 -272px;
  78 +}
  79 +
  80 +.eauth-service-id-linkedin .eauth-service-link:before,
  81 +.eauth-service-id-linkedin_oauth2 .eauth-service-link:before {
  82 + background-position: 0 -306px;
  83 +}
  84 +
  85 +.eauth-service-id-github .eauth-service-link:before {
  86 + background-position: 0 -340px;
  87 +}
  88 +
  89 +.eauth-service-id-live .eauth-service-link:before {
  90 + background-position: 0 -372px;
  91 +}
  92 +
  93 +.eauth-service-id-yahoo .eauth-service-link:before {
  94 + background-position: 0 -406px;
  95 +}
  96 +
  97 +.eauth-service-id-steam .eauth-service-link:before {
  98 + background-position: 0 -440px;
  99 +}
  100 +
  101 +.eauth-service-id-instagram .eauth-service-link:before {
  102 + background-position: 0 -474px;
  103 +}
0 104 \ No newline at end of file
... ...
common/components/nodge/eauth/src/assets/images/auth-src.png 0 → 100644

19 KB

common/components/nodge/eauth/src/assets/images/auth.png 0 → 100644

6.18 KB

common/components/nodge/eauth/src/assets/js/eauth.js 0 → 100644
  1 +/*
  2 + * Yii EAuth extension.
  3 + * @author Maxim Zemskov
  4 + * @link http://github.com/Nodge/yii2-eauth/
  5 + * @license http://www.opensource.org/licenses/bsd-license.php
  6 + */
  7 +(function ($) {
  8 + var popup,
  9 + defaults = {
  10 + popup: {
  11 + width: 450,
  12 + height: 380
  13 + }
  14 + };
  15 +
  16 + function openPopup(options) {
  17 + if (popup != null)
  18 + popup.close();
  19 +
  20 + var redirect_uri,
  21 + url = redirect_uri = options.url;
  22 +
  23 + url += url.indexOf('?') >= 0 ? '&' : '?';
  24 + if (url.indexOf('redirect_uri=') === -1)
  25 + url += 'redirect_uri=' + encodeURIComponent(redirect_uri) + '&';
  26 + url += 'js=';
  27 +
  28 + var centerWidth = (window.screen.width - options.popup.width) / 2,
  29 + centerHeight = (window.screen.height - options.popup.height) / 2;
  30 +
  31 + popup = window.open(url, "yii_eauth_popup", "width=" + options.popup.width + ",height=" + options.popup.height + ",left=" + centerWidth + ",top=" + centerHeight + ",resizable=yes,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=yes");
  32 + popup.focus();
  33 + }
  34 +
  35 + $.fn.eauth = function (services) {
  36 + $(this).on('click', '[data-eauth-service]', function (e) {
  37 + e.preventDefault();
  38 +
  39 + var service = $(this).data('eauthService'),
  40 + options = $.extend({
  41 + url: this.href
  42 + }, defaults, services[service]);
  43 +
  44 + openPopup(options);
  45 + });
  46 + };
  47 +})(jQuery);
... ...
common/components/nodge/eauth/src/messages/blank/eauth.php 0 → 100644
  1 +<?php
  2 +
  3 +return [
  4 + 'Undefined service name: {service}.' => '{service}',
  5 + 'Invalid response http code: {code}.' => '{code}',
  6 + 'Invalid response format.' => '',
  7 + 'Unable to complete the authentication because the required data was not received.' => '{provider}',
  8 + 'Unable to complete the request because the user was not authenticated.' => '',
  9 +
  10 + 'Redirecting back to the application...' => '',
  11 + 'Click here to return to the application.' => '',
  12 +
  13 + 'Google' => 'Google',
  14 + 'Twitter' => 'Twitter',
  15 + 'Yandex' => 'Yandex',
  16 + 'VK.com' => 'VK.com',
  17 + 'Facebook' => 'Facebook',
  18 + 'Mail.ru' => 'Mail.ru',
  19 + 'Moikrug.ru' => 'Moikrug.ru',
  20 + 'Odnoklassniki' => 'Odnoklassniki',
  21 + 'LinkedIn' => 'LinkedIn',
  22 + 'GitHub' => 'GitHub',
  23 +];
0 24 \ No newline at end of file
... ...
common/components/nodge/eauth/src/messages/de/eauth.php 0 → 100644
  1 +<?php
  2 +
  3 +return [
  4 + 'Undefined service name: {service}.' => 'Undefinierter Servicename: {service}',
  5 + 'Invalid response http code: {code}.' => 'Ungültiger HTTP Code: {code}',
  6 + 'Invalid response format.' => 'Ungültiges Antwortformat.',
  7 + 'Unable to complete the authentication because the required data was not received.' => 'Die Authentifizierung konnte nicht durchgeführt werden, da keine Daten empfangen wurden.',
  8 + 'Unable to complete the request because the user was not authenticated.' => 'Die Anfrage konnte nicht durchgeführt werden, da der Nutzer nicht authentifiziert war.',
  9 +
  10 + 'Redirecting back to the application...' => 'Weiterleitung zur Applikation...',
  11 + 'Click here to return to the application.' => 'Klicke hier um zur Applikation zurückzukehren',
  12 +
  13 + 'Google' => 'Google',
  14 + 'Twitter' => 'Twitter',
  15 + 'Yandex' => 'Yandex',
  16 + 'VK.com' => 'VK.com',
  17 + 'Facebook' => 'Facebook',
  18 + 'Mail.ru' => 'Mail.ru',
  19 + 'Moikrug.ru' => 'Moikrug.ru',
  20 + 'Odnoklassniki' => 'Odnoklassniki',
  21 + 'LinkedIn' => 'LinkedIn',
  22 + 'GitHub' => 'GitHub',
  23 +];
0 24 \ No newline at end of file
... ...
common/components/nodge/eauth/src/messages/en/eauth.php 0 → 100644
  1 +<?php
  2 +
  3 +return [
  4 + 'Undefined service name: {service}.' => 'Undefined service name: {service}.',
  5 + 'Invalid response http code: {code}.' => 'Invalid response http code: {code}.',
  6 + 'Invalid response format.' => 'Invalid response format.',
  7 + 'Unable to complete the authentication because the required data was not received.' => 'Unable to complete the authentication because the required data was not received.',
  8 + 'Unable to complete the request because the user was not authenticated.' => 'Unable to complete the request because the user was not authenticated.',
  9 +
  10 + 'Redirecting back to the application...' => 'Redirecting back to the application...',
  11 + 'Click here to return to the application.' => 'Click here to return to the application.',
  12 +
  13 + 'Google' => 'Google',
  14 + 'Twitter' => 'Twitter',
  15 + 'Yandex' => 'Yandex',
  16 + 'VK.com' => 'VK.com',
  17 + 'Facebook' => 'Facebook',
  18 + 'Mail.ru' => 'Mail.ru',
  19 + 'Moikrug.ru' => 'Moikrug.ru',
  20 + 'Odnoklassniki' => 'Odnoklassniki',
  21 + 'LinkedIn' => 'LinkedIn',
  22 + 'GitHub' => 'GitHub',
  23 +];
0 24 \ No newline at end of file
... ...
common/components/nodge/eauth/src/messages/ru/eauth.php 0 → 100644
  1 +<?php
  2 +
  3 +return [
  4 + 'Undefined service name: {service}.' => 'Авторизация с помощью {service} не поддерживается.',
  5 + 'Invalid response http code: {code}.' => 'Неверный ответ от сервера авторизации: {code}.',
  6 + 'Invalid response format.' => 'Сервер авторизации вернул данные в неправильном формате.',
  7 + 'Unable to complete the authentication because the required data was not received.' => 'Невозможно завершить авторизацию пользователя, потому что {provider} не передает необходимую информацию.',
  8 + 'Unable to complete the request because the user was not authenticated.' => 'Невозможно выполнить защищенный запрос, потому что пользователь не был авторизован.',
  9 +
  10 + 'Redirecting back to the application...' => 'Перенаправление обратно в приложение...',
  11 + 'Click here to return to the application.' => 'Нажмите сюда чтобы вернуться обратно в приложение.',
  12 +
  13 + 'Google' => 'Google',
  14 + 'Twitter' => 'Twitter',
  15 + 'Yandex' => 'Яндекс',
  16 + 'VK.com' => 'ВКонтакте',
  17 + 'Facebook' => 'Facebook',
  18 + 'Mail.ru' => 'Mail.ru',
  19 + 'Moikrug.ru' => 'Мой круг',
  20 + 'Odnoklassniki' => 'Одноклассники',
  21 + 'LinkedIn' => 'LinkedIn',
  22 + 'GitHub' => 'GitHub',
  23 +];
0 24 \ No newline at end of file
... ...
common/components/nodge/eauth/src/messages/uk/eauth.php 0 → 100644
  1 +<?php
  2 +
  3 +return [
  4 + 'Undefined service name: {service}.' => 'Авторизація за допомогою {service} не підтримується.',
  5 + 'Invalid response http code: {code}.' => 'Невірна відповідь від сервера авторизації: {code}.',
  6 + 'Invalid response format.' => 'Сервер авторизації повернув данні в невірному форматі.',
  7 + 'Unable to complete the authentication because the required data was not received.' => 'Неможливо завершити авторизацію користувача, так як {provider} не передає необхідну інформацію.',
  8 + 'Unable to complete the request because the user was not authenticated.' => 'Неможливо виконати захищений запит, так як користувач не був авторизований.',
  9 +
  10 + 'Redirecting back to the application...' => 'Redirecting back to the application...',
  11 + 'Click here to return to the application.' => 'Click here to return to the application.',
  12 +
  13 + 'Google' => 'Google',
  14 + 'Twitter' => 'Twitter',
  15 + 'Yandex' => 'Яндекс',
  16 + 'VK.com' => 'ВКонтакте',
  17 + 'Facebook' => 'Facebook',
  18 + 'Mail.ru' => 'Mail.ru',
  19 + 'Moikrug.ru' => 'Мой круг',
  20 + 'Odnoklassniki' => 'Одноклассники',
  21 + 'LinkedIn' => 'LinkedIn',
  22 + 'GitHub' => 'GitHub',
  23 +];
... ...
common/components/nodge/eauth/src/oauth/HttpClient.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * HttpClient class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth;
  11 +
  12 +use Yii;
  13 +use OAuth\Common\Http\Client\AbstractClient;
  14 +use OAuth\Common\Http\Exception\TokenResponseException;
  15 +use OAuth\Common\Http\Uri\UriInterface;
  16 +
  17 +/**
  18 + * Client implementation for cURL
  19 + */
  20 +class HttpClient extends AbstractClient
  21 +{
  22 +
  23 + /**
  24 + * If true, explicitly sets cURL to use SSL version 3. Use this if cURL
  25 + * compiles with GnuTLS SSL.
  26 + *
  27 + * @var bool
  28 + */
  29 + protected $forceSSL3 = false;
  30 +
  31 + /**
  32 + * If true and you are working in safe_mode environment or inside open_basedir
  33 + * it will use streams instead of curl.
  34 + *
  35 + * @var bool
  36 + */
  37 + protected $useStreamsFallback = false;
  38 +
  39 + /**
  40 + * @var UriInterface
  41 + */
  42 + protected $endpoint;
  43 +
  44 + /**
  45 + * @var mixed
  46 + */
  47 + protected $requestBody;
  48 +
  49 + /**
  50 + * @var array
  51 + */
  52 + protected $extraHeaders = [];
  53 +
  54 + /**
  55 + * @var string
  56 + */
  57 + protected $method = 'POST';
  58 +
  59 + /**
  60 + * @param bool $force
  61 + */
  62 + public function setForceSSL3($force)
  63 + {
  64 + $this->forceSSL3 = $force;
  65 + }
  66 +
  67 + /**
  68 + * @return boolean
  69 + */
  70 + public function getForceSSL3()
  71 + {
  72 + return $this->forceSSL3;
  73 + }
  74 +
  75 + /**
  76 + * @param bool $useStreamsFallback
  77 + */
  78 + public function setUseStreamsFallback($useStreamsFallback)
  79 + {
  80 + $this->useStreamsFallback = $useStreamsFallback;
  81 + }
  82 +
  83 + /**
  84 + * @return bool
  85 + */
  86 + public function getUseStreamsFallback()
  87 + {
  88 + return $this->useStreamsFallback;
  89 + }
  90 +
  91 + /**
  92 + * Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
  93 + * They should return, in string form, the response body and throw an exception on error.
  94 + *
  95 + * @param UriInterface $endpoint
  96 + * @param mixed $requestBody
  97 + * @param array $extraHeaders
  98 + * @param string $method
  99 + * @return string
  100 + */
  101 + public function retrieveResponse(UriInterface $endpoint, $requestBody, array $extraHeaders = [], $method = 'POST')
  102 + {
  103 + $this->endpoint = $endpoint;
  104 + $this->requestBody = $requestBody;
  105 + $this->extraHeaders = $extraHeaders;
  106 + $this->method = $method;
  107 +
  108 + if ($this->useStreamsFallback && !$this->allowFollowLocation()) {
  109 + return $this->streams();
  110 + }
  111 +
  112 + return $this->curl();
  113 + }
  114 +
  115 + /**
  116 + * @return bool
  117 + */
  118 + protected function allowFollowLocation()
  119 + {
  120 + return !ini_get('safe_mode') && !ini_get('open_basedir');
  121 + }
  122 +
  123 + /**
  124 + *
  125 + */
  126 + protected function prepareRequest()
  127 + {
  128 + $this->method = strtoupper($this->method);
  129 + $this->normalizeHeaders($this->extraHeaders);
  130 +
  131 + if ($this->method === 'GET' && !empty($this->requestBody)) {
  132 + throw new \InvalidArgumentException('No body expected for "GET" request.');
  133 + }
  134 +
  135 + if (!isset($this->extraHeaders['Content-type']) && $this->method === 'POST' && is_array($this->requestBody)) {
  136 + $this->extraHeaders['Content-type'] = 'Content-type: application/x-www-form-urlencoded';
  137 + }
  138 +
  139 + // Some of services requires User-Agent header (e.g. GitHub)
  140 + if (!isset($this->extraHeaders['User-Agent'])) {
  141 + $this->extraHeaders['User-Agent'] = 'User-Agent: yii2-eauth';
  142 + }
  143 +
  144 + $this->extraHeaders['Host'] = 'Host: ' . $this->endpoint->getHost();
  145 + $this->extraHeaders['Connection'] = 'Connection: close';
  146 +
  147 + if (YII_DEBUG) {
  148 + Yii::trace('EAuth http request: ' . PHP_EOL . var_export([
  149 + 'url' => $this->endpoint->getAbsoluteUri(),
  150 + 'method' => $this->method,
  151 + 'headers' => $this->extraHeaders,
  152 + 'body' => $this->requestBody,
  153 + ], true), __NAMESPACE__);
  154 + }
  155 +
  156 + if (is_array($this->requestBody)) {
  157 + $this->requestBody = http_build_query($this->requestBody, null, '&');
  158 + }
  159 + }
  160 +
  161 + /**
  162 + * @return string
  163 + * @throws TokenResponseException
  164 + */
  165 + protected function curl()
  166 + {
  167 + $this->prepareRequest();
  168 +
  169 + $ch = curl_init();
  170 + curl_setopt($ch, CURLOPT_URL, $this->endpoint->getAbsoluteUri());
  171 + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  172 +
  173 + if ($this->method === 'POST' || $this->method === 'PUT') {
  174 + if ($this->method === 'PUT') {
  175 + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
  176 + } else {
  177 + curl_setopt($ch, CURLOPT_POST, true);
  178 + }
  179 + curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
  180 + } else {
  181 + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method);
  182 + }
  183 +
  184 + if ($this->allowFollowLocation() && $this->maxRedirects > 0) {
  185 + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  186 + curl_setopt($ch, CURLOPT_MAXREDIRS, $this->maxRedirects);
  187 + }
  188 +
  189 + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  190 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  191 + curl_setopt($ch, CURLOPT_HEADER, false);
  192 + curl_setopt($ch, CURLOPT_HTTPHEADER, $this->extraHeaders);
  193 +
  194 + if ($this->forceSSL3) {
  195 + curl_setopt($ch, CURLOPT_SSLVERSION, 3);
  196 + }
  197 +
  198 + $response = curl_exec($ch);
  199 + $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  200 +
  201 + if (YII_DEBUG) {
  202 + Yii::trace('EAuth http response: ' . PHP_EOL . var_export($response, true), __NAMESPACE__);
  203 + }
  204 +
  205 + if (false === $response) {
  206 + $errNo = curl_errno($ch);
  207 + $errStr = curl_error($ch);
  208 + curl_close($ch);
  209 +
  210 + if (empty($errStr)) {
  211 + $errStr = 'Failed to request resource.';
  212 + } else {
  213 + $errStr = 'cURL Error # ' . $errNo . ': ' . $errStr;
  214 + }
  215 +
  216 + Yii::error('EAuth curl error (' . $responseCode . '): ' . $errStr, __NAMESPACE__);
  217 + throw new TokenResponseException($errStr, $responseCode);
  218 + }
  219 +
  220 + curl_close($ch);
  221 +
  222 + return $response;
  223 + }
  224 +
  225 + /**
  226 + * @return string
  227 + * @throws TokenResponseException
  228 + */
  229 + protected function streams()
  230 + {
  231 + $this->prepareRequest();
  232 +
  233 + $context = stream_context_create([
  234 + 'http' => [
  235 + 'method' => $this->method,
  236 + 'header' => array_values($this->extraHeaders),
  237 + 'content' => $this->requestBody,
  238 + 'protocol_version' => '1.1',
  239 + 'user_agent' => 'Yii2 EAuth Client',
  240 + 'max_redirects' => $this->maxRedirects,
  241 + 'timeout' => $this->timeout,
  242 + ],
  243 + ]);
  244 +
  245 + $level = error_reporting(0);
  246 + $response = file_get_contents($this->endpoint->getAbsoluteUri(), false, $context);
  247 + error_reporting($level);
  248 +
  249 + if (YII_DEBUG) {
  250 + Yii::trace('EAuth http response: ' . PHP_EOL . var_export($response, true), __NAMESPACE__);
  251 + }
  252 +
  253 + if (false === $response) {
  254 + $lastError = error_get_last();
  255 +
  256 + if (is_null($lastError)) {
  257 + $errStr = 'Failed to request resource.';
  258 + } else {
  259 + $errStr = $lastError['message'];
  260 + }
  261 +
  262 + Yii::error('EAuth streams error: ' . $errStr, __NAMESPACE__);
  263 + throw new TokenResponseException($errStr);
  264 + }
  265 +
  266 + return $response;
  267 + }
  268 +
  269 +}
... ...
common/components/nodge/eauth/src/oauth/ServiceBase.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OAuthService class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth;
  11 +
  12 +use Yii;
  13 +use OAuth\Common\Http\Uri\Uri;
  14 +use OAuth\Common\Http\Client\ClientInterface;
  15 +use OAuth\Common\Token\TokenInterface;
  16 +use OAuth\Common\Storage\TokenStorageInterface;
  17 +use nodge\eauth\EAuth;
  18 +use nodge\eauth\IAuthService;
  19 +use nodge\eauth\ErrorException;
  20 +use yii\helpers\ArrayHelper;
  21 +use yii\helpers\Url;
  22 +
  23 +/**
  24 + * EOAuthService is a base class for all OAuth providers.
  25 + *
  26 + * @package application.extensions.eauth
  27 + */
  28 +abstract class ServiceBase extends \nodge\eauth\ServiceBase implements IAuthService
  29 +{
  30 +
  31 + /**
  32 + * @var string Base url for API calls.
  33 + */
  34 + protected $baseApiUrl;
  35 +
  36 + /**
  37 + * @var int Default token lifetime. Used when service wont provide expires_in param.
  38 + */
  39 + protected $tokenDefaultLifetime = null;
  40 +
  41 + /**
  42 + * @var array TokenStorage class. Null means default value from EAuth component config.
  43 + */
  44 + protected $tokenStorage;
  45 +
  46 + /**
  47 + * @var array HttpClient class. Null means default value from EAuth component config.
  48 + */
  49 + protected $httpClient;
  50 +
  51 + /**
  52 + * @var TokenStorageInterface
  53 + */
  54 + private $_tokenStorage;
  55 +
  56 + /**
  57 + * @var ClientInterface
  58 + */
  59 + private $_httpClient;
  60 +
  61 + /**
  62 + * Initialize the component.
  63 + *
  64 + * @param EAuth $component the component instance.
  65 + * @param array $options properties initialization.
  66 + */
  67 +// public function init($component, $options = []) {
  68 +// parent::init($component, $options);
  69 +// }
  70 +
  71 + /**
  72 + * For OAuth we can check existing access token.
  73 + * Useful for API calls.
  74 + *
  75 + * @return bool
  76 + * @throws ErrorException
  77 + */
  78 + public function getIsAuthenticated()
  79 + {
  80 + if (!$this->authenticated) {
  81 + try {
  82 + $proxy = $this->getProxy();
  83 + $this->authenticated = $proxy->hasValidAccessToken();
  84 + } catch (\OAuth\Common\Exception\Exception $e) {
  85 + throw new ErrorException($e->getMessage(), $e->getCode(), 1, $e->getFile(), $e->getLine(), $e);
  86 + }
  87 + }
  88 + return parent::getIsAuthenticated();
  89 + }
  90 +
  91 + /**
  92 + * @return \nodge\eauth\oauth1\ServiceProxy|\nodge\eauth\oauth2\ServiceProxy
  93 + */
  94 + abstract protected function getProxy();
  95 +
  96 + /**
  97 + * @return string the current url
  98 + */
  99 + protected function getCallbackUrl()
  100 + {
  101 + return Url::to('', true);
  102 + }
  103 +
  104 + /**
  105 + * @param array $config
  106 + */
  107 + public function setTokenStorage(array $config)
  108 + {
  109 + $this->tokenStorage = ArrayHelper::merge($this->tokenStorage, $config);
  110 + }
  111 +
  112 + /**
  113 + * @return TokenStorageInterface
  114 + */
  115 + protected function getTokenStorage()
  116 + {
  117 + if (!isset($this->_tokenStorage)) {
  118 + $config = $this->tokenStorage;
  119 + if (!isset($config)) {
  120 + $config = $this->getComponent()->getTokenStorage();
  121 + }
  122 + $this->_tokenStorage = Yii::createObject($config);
  123 + }
  124 + return $this->_tokenStorage;
  125 + }
  126 +
  127 + /**
  128 + * @param array $config
  129 + */
  130 + public function setHttpClient(array $config)
  131 + {
  132 + $this->httpClient = ArrayHelper::merge($this->httpClient, $config);
  133 + }
  134 +
  135 + /**
  136 + * @return ClientInterface
  137 + */
  138 + protected function getHttpClient()
  139 + {
  140 + if (!isset($this->_httpClient)) {
  141 + $config = $this->httpClient;
  142 + if (!isset($config)) {
  143 + $config = $this->getComponent()->getHttpClient();
  144 + }
  145 + $this->_httpClient = Yii::createObject($config);
  146 + }
  147 + return $this->_httpClient;
  148 + }
  149 +
  150 + /**
  151 + * @return int
  152 + */
  153 + public function getTokenDefaultLifetime()
  154 + {
  155 + return $this->tokenDefaultLifetime;
  156 + }
  157 +
  158 + /**
  159 + * Returns the protected resource.
  160 + *
  161 + * @param string $url url to request.
  162 + * @param array $options HTTP request options. Keys: query, data, headers.
  163 + * @param boolean $parseResponse Whether to parse response.
  164 + * @return mixed the response.
  165 + * @throws ErrorException
  166 + */
  167 + public function makeSignedRequest($url, $options = [], $parseResponse = true)
  168 + {
  169 + if (!$this->getIsAuthenticated()) {
  170 + throw new ErrorException(Yii::t('eauth', 'Unable to complete the signed request because the user was not authenticated.'), 401);
  171 + }
  172 +
  173 + if (stripos($url, 'http') !== 0) {
  174 + $url = $this->baseApiUrl . $url;
  175 + }
  176 +
  177 + $url = new Uri($url);
  178 + if (isset($options['query'])) {
  179 + foreach ($options['query'] as $key => $value) {
  180 + $url->addToQuery($key, $value);
  181 + }
  182 + }
  183 +
  184 + $data = isset($options['data']) ? $options['data'] : [];
  185 + $method = !empty($data) ? 'POST' : 'GET';
  186 + $headers = isset($options['headers']) ? $options['headers'] : [];
  187 +
  188 + $response = $this->getProxy()->request($url, $method, $data, $headers);
  189 +
  190 + if ($parseResponse) {
  191 + $response = $this->parseResponseInternal($response);
  192 + }
  193 +
  194 + return $response;
  195 + }
  196 +
  197 + /**
  198 + * Returns the public resource.
  199 + *
  200 + * @param string $url url to request.
  201 + * @param array $options HTTP request options. Keys: query, data, headers.
  202 + * @param boolean $parseResponse Whether to parse response.
  203 + * @return mixed the response.
  204 + */
  205 + public function makeRequest($url, $options = [], $parseResponse = true) {
  206 + if (stripos($url, 'http') !== 0) {
  207 + $url = $this->baseApiUrl . $url;
  208 + }
  209 +
  210 + $url = new Uri($url);
  211 + if (isset($options['query'])) {
  212 + foreach ($options['query'] as $key => $value) {
  213 + $url->addToQuery($key, $value);
  214 + }
  215 + }
  216 +
  217 + $data = isset($options['data']) ? $options['data'] : [];
  218 + $method = !empty($data) ? 'POST' : 'GET';
  219 +
  220 + $headers = isset($options['headers']) ? $options['headers'] : [];
  221 + $headers = array_merge($this->getProxy()->getExtraApiHeaders(), $headers);
  222 +
  223 + $response = $this->getHttpClient()->retrieveResponse($url, $data, $headers, $method);
  224 + if ($parseResponse) {
  225 + $response = $this->parseResponseInternal($response);
  226 + }
  227 +
  228 + return $response;
  229 + }
  230 +
  231 + /**
  232 + * Parse response and check for errors.
  233 + *
  234 + * @param string $response
  235 + * @return mixed
  236 + * @throws ErrorException
  237 + */
  238 + protected function parseResponseInternal($response)
  239 + {
  240 + try {
  241 + $result = $this->parseResponse($response);
  242 + if (!isset($result)) {
  243 + throw new ErrorException(Yii::t('eauth', 'Invalid response format.'), 500);
  244 + }
  245 +
  246 + $error = $this->fetchResponseError($result);
  247 + if (isset($error) && !empty($error['message'])) {
  248 + throw new ErrorException($error['message'], $error['code']);
  249 + }
  250 +
  251 + return $result;
  252 + } catch (\Exception $e) {
  253 + throw new ErrorException($e->getMessage(), $e->getCode());
  254 + }
  255 + }
  256 +
  257 + /**
  258 + * @param string $response
  259 + * @return mixed
  260 + */
  261 + protected function parseResponse($response)
  262 + {
  263 + return json_decode($response, true);
  264 + }
  265 +
  266 + /**
  267 + * Returns the error array.
  268 + *
  269 + * @param array $response
  270 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  271 + */
  272 + protected function fetchResponseError($response)
  273 + {
  274 + if (isset($response['error'])) {
  275 + return [
  276 + 'code' => 500,
  277 + 'message' => 'Unknown error occurred.',
  278 + ];
  279 + }
  280 + return null;
  281 + }
  282 +
  283 + /**
  284 + * @return array|null An array with valid access_token information.
  285 + */
  286 + protected function getAccessTokenData()
  287 + {
  288 + if (!$this->getIsAuthenticated()) {
  289 + return null;
  290 + }
  291 +
  292 + $token = $this->getProxy()->getAccessToken();
  293 + if (!isset($token)) {
  294 + return null;
  295 + }
  296 +
  297 + return [
  298 + 'access_token' => $token->getAccessToken(),
  299 + 'refresh_token' => $token->getRefreshToken(),
  300 + 'expires' => $token->getEndOfLife(),
  301 + 'params' => $token->getExtraParams(),
  302 + ];
  303 + }
  304 +
  305 + /**
  306 + * @param array $data
  307 + * @return string|null
  308 + */
  309 + public function getAccessTokenResponseError($data)
  310 + {
  311 + return isset($data['error']) ? $data['error'] : null;
  312 + }
  313 +}
0 314 \ No newline at end of file
... ...
common/components/nodge/eauth/src/oauth/SessionTokenStorage.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * SessionTokenStorage class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth;
  11 +
  12 +use Yii;
  13 +use OAuth\Common\Storage\TokenStorageInterface;
  14 +use OAuth\Common\Token\TokenInterface;
  15 +use OAuth\Common\Storage\Exception\TokenNotFoundException;
  16 +use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
  17 +
  18 +/**
  19 + * Stores a token in a PHP session.
  20 + */
  21 +class SessionTokenStorage implements TokenStorageInterface
  22 +{
  23 +
  24 + const SESSION_TOKEN_PREFIX = 'eauth-token-';
  25 + const SESSION_STATE_PREFIX = 'eauth-state-';
  26 +
  27 + /**
  28 + * @var
  29 + */
  30 + protected $componentName;
  31 +
  32 + /**
  33 + * @param string $componentName
  34 + */
  35 + public function __construct($componentName = 'session')
  36 + {
  37 + $this->componentName = $componentName;
  38 + }
  39 +
  40 + /**
  41 + * @return null|object
  42 + */
  43 + protected function getSession()
  44 + {
  45 + return Yii::$app->get($this->componentName);
  46 + }
  47 +
  48 + /**
  49 + * @param string $service
  50 + * @return TokenInterface
  51 + * @throws TokenNotFoundException
  52 + */
  53 + public function retrieveAccessToken($service)
  54 + {
  55 + if ($this->hasAccessToken($service)) {
  56 + return $this->getSession()->get(self::SESSION_TOKEN_PREFIX . $service);
  57 + }
  58 + throw new TokenNotFoundException('Token not found in session, are you sure you stored it?');
  59 + }
  60 +
  61 + /**
  62 + * @param string $service
  63 + * @param TokenInterface $token
  64 + * @return TokenInterface
  65 + */
  66 + public function storeAccessToken($service, TokenInterface $token)
  67 + {
  68 + $this->getSession()->set(self::SESSION_TOKEN_PREFIX . $service, $token);
  69 + return $token;
  70 + }
  71 +
  72 + /**
  73 + * @param string $service
  74 + * @return bool
  75 + */
  76 + public function hasAccessToken($service)
  77 + {
  78 + return $this->getSession()->has(self::SESSION_TOKEN_PREFIX . $service);
  79 + }
  80 +
  81 + /**
  82 + * Delete the users token. Aka, log out.
  83 + *
  84 + * @param string $service
  85 + * @return TokenStorageInterface
  86 + */
  87 + public function clearToken($service)
  88 + {
  89 + $this->getSession()->remove(self::SESSION_TOKEN_PREFIX . $service);
  90 + return $this;
  91 + }
  92 +
  93 + /**
  94 + * Delete *ALL* user tokens.
  95 + *
  96 + * @return TokenStorageInterface
  97 + */
  98 + public function clearAllTokens()
  99 + {
  100 + $session = $this->getSession();
  101 + foreach ($session as $key => $value) {
  102 + if (strpos($key, self::SESSION_TOKEN_PREFIX) === 0) {
  103 + $session->remove($key);
  104 + }
  105 + }
  106 + return $this;
  107 + }
  108 +
  109 + /**
  110 + * Store the authorization state related to a given service
  111 + *
  112 + * @param string $service
  113 + * @param string $state
  114 + * @return TokenStorageInterface
  115 + */
  116 + public function storeAuthorizationState($service, $state)
  117 + {
  118 + $this->getSession()->set(self::SESSION_STATE_PREFIX . $service, $state);
  119 + return $this;
  120 + }
  121 +
  122 + /**
  123 + * Check if an authorization state for a given service exists
  124 + *
  125 + * @param string $service
  126 + * @return bool
  127 + */
  128 + public function hasAuthorizationState($service)
  129 + {
  130 + return $this->getSession()->has(self::SESSION_STATE_PREFIX . $service);
  131 + }
  132 +
  133 + /**
  134 + * Retrieve the authorization state for a given service
  135 + *
  136 + * @param string $service
  137 + * @return string
  138 + * @throws AuthorizationStateNotFoundException
  139 + */
  140 + public function retrieveAuthorizationState($service)
  141 + {
  142 + if ($this->hasAuthorizationState($service)) {
  143 + return $this->getSession()->get(self::SESSION_STATE_PREFIX . $service);
  144 + }
  145 + throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?');
  146 + }
  147 +
  148 + /**
  149 + * Clear the authorization state of a given service
  150 + *
  151 + * @param string $service
  152 + * @return TokenStorageInterface
  153 + */
  154 + public function clearAuthorizationState($service)
  155 + {
  156 + $this->getSession()->remove(self::SESSION_STATE_PREFIX . $service);
  157 + return $this;
  158 + }
  159 +
  160 + /**
  161 + * Delete *ALL* user authorization states. Use with care. Most of the time you will likely
  162 + * want to use clearAuthorizationState() instead.
  163 + *
  164 + * @return TokenStorageInterface
  165 + */
  166 + public function clearAllAuthorizationStates()
  167 + {
  168 + $session = $this->getSession();
  169 + foreach ($session as $key => $value) {
  170 + if (strpos($key, self::SESSION_STATE_PREFIX) === 0) {
  171 + $session->remove($key);
  172 + }
  173 + }
  174 + return $this;
  175 + }
  176 +
  177 +}
... ...
common/components/nodge/eauth/src/oauth1/Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OAuth1 Service class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth1;
  11 +
  12 +use Yii;
  13 +use OAuth\Common\Exception\Exception as OAuthException;
  14 +use OAuth\Common\Http\Uri\Uri;
  15 +use OAuth\Common\Consumer\Credentials;
  16 +use OAuth\OAuth1\Signature\Signature;
  17 +use nodge\eauth\EAuth;
  18 +use nodge\eauth\ErrorException;
  19 +use nodge\eauth\IAuthService;
  20 +use nodge\eauth\oauth\ServiceBase;
  21 +
  22 +/**
  23 + * EOAuthService is a base class for all OAuth providers.
  24 + *
  25 + * @package application.extensions.eauth
  26 + */
  27 +abstract class Service extends ServiceBase implements IAuthService
  28 +{
  29 +
  30 + /**
  31 + * @var string OAuth2 client id.
  32 + */
  33 + protected $key;
  34 +
  35 + /**
  36 + * @var string OAuth2 client secret key.
  37 + */
  38 + protected $secret;
  39 +
  40 + /**
  41 + * @var array Provider options. Must contain the keys: request, authorize, access.
  42 + */
  43 + protected $providerOptions = [
  44 + 'request' => '',
  45 + 'authorize' => '',
  46 + 'access' => '',
  47 + ];
  48 +
  49 + /**
  50 + * @var ServiceProxy
  51 + */
  52 + private $_proxy;
  53 +
  54 + /**
  55 + * Initialize the component.
  56 + *
  57 + * @param EAuth $component the component instance.
  58 + * @param array $options properties initialization.
  59 + */
  60 +// public function init($component, $options = []) {
  61 +// parent::init($component, $options);
  62 +// }
  63 +
  64 + /**
  65 + * @param string $key
  66 + */
  67 + public function setKey($key)
  68 + {
  69 + $this->key = $key;
  70 + }
  71 +
  72 + /**
  73 + * @param string $secret
  74 + */
  75 + public function setSecret($secret)
  76 + {
  77 + $this->secret = $secret;
  78 + }
  79 +
  80 + /**
  81 + * @return ServiceProxy
  82 + */
  83 + protected function getProxy()
  84 + {
  85 + if (!isset($this->_proxy)) {
  86 + $storage = $this->getTokenStorage();
  87 + $httpClient = $this->getHttpClient();
  88 + $credentials = new Credentials($this->key, $this->secret, $this->getCallbackUrl());
  89 + $signature = new Signature($credentials);
  90 + $this->_proxy = new ServiceProxy($credentials, $httpClient, $storage, $signature, null, $this);
  91 + }
  92 + return $this->_proxy;
  93 + }
  94 +
  95 + /**
  96 + * Authenticate the user.
  97 + *
  98 + * @return boolean whether user was successfuly authenticated.
  99 + * @throws ErrorException
  100 + */
  101 + public function authenticate()
  102 + {
  103 + try {
  104 + $proxy = $this->getProxy();
  105 +
  106 + if (!empty($_GET['oauth_token'])) {
  107 + $token = $proxy->retrieveAccessToken();
  108 +
  109 + // This was a callback request, get the token now
  110 + $proxy->requestAccessToken($_GET['oauth_token'], $_GET['oauth_verifier'], $token->getRequestTokenSecret());
  111 +
  112 + $this->authenticated = true;
  113 + } else if ($proxy->hasValidAccessToken()) {
  114 + $this->authenticated = true;
  115 + } else {
  116 + // extra request needed for oauth1 to request a request token :-)
  117 + $token = $proxy->requestRequestToken();
  118 + /** @var $url Uri */
  119 + $url = $proxy->getAuthorizationUri(['oauth_token' => $token->getRequestToken()]);
  120 + Yii::$app->getResponse()->redirect($url->getAbsoluteUri())->send();
  121 + }
  122 + } catch (OAuthException $e) {
  123 + throw new ErrorException($e->getMessage(), $e->getCode(), 1, $e->getFile(), $e->getLine(), $e);
  124 + }
  125 +
  126 + return $this->getIsAuthenticated();
  127 + }
  128 +
  129 + /**
  130 + * @return string
  131 + */
  132 + public function getRequestTokenEndpoint()
  133 + {
  134 + return $this->providerOptions['request'];
  135 + }
  136 +
  137 + /**
  138 + * @return string
  139 + */
  140 + public function getAuthorizationEndpoint()
  141 + {
  142 + return $this->providerOptions['authorize'];
  143 + }
  144 +
  145 + /**
  146 + * @return string
  147 + */
  148 + public function getAccessTokenEndpoint()
  149 + {
  150 + return $this->providerOptions['access'];
  151 + }
  152 +
  153 + /**
  154 + * @return array
  155 + */
  156 + public function getAccessTokenArgumentNames()
  157 + {
  158 + return [
  159 + 'oauth_token' => 'oauth_token',
  160 + 'oauth_token_secret' => 'oauth_token_secret',
  161 + 'oauth_expires_in' => 'oauth_expires_in',
  162 + ];
  163 + }
  164 +}
0 165 \ No newline at end of file
... ...
common/components/nodge/eauth/src/oauth1/ServiceProxy.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OAuth1 ServiceProxy class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth1;
  11 +
  12 +use OAuth\Common\Consumer\CredentialsInterface;
  13 +use OAuth\Common\Http\Client\ClientInterface;
  14 +use OAuth\Common\Http\Exception\TokenResponseException;
  15 +use OAuth\Common\Http\Uri\Uri;
  16 +use OAuth\Common\Http\Uri\UriInterface;
  17 +use OAuth\Common\Storage\TokenStorageInterface;
  18 +use OAuth\Common\Token\TokenInterface;
  19 +use OAuth\OAuth1\Service\AbstractService;
  20 +use OAuth\OAuth1\Signature\SignatureInterface;
  21 +use OAuth\OAuth1\Token\StdOAuth1Token;
  22 +
  23 +class ServiceProxy extends AbstractService
  24 +{
  25 +
  26 + /**
  27 + * @var Service the currently used service class
  28 + */
  29 + protected $service;
  30 +
  31 + /**
  32 + * {@inheritDoc}
  33 + */
  34 + public function __construct(
  35 + CredentialsInterface $credentials,
  36 + ClientInterface $httpClient,
  37 + TokenStorageInterface $storage,
  38 + SignatureInterface $signature,
  39 + UriInterface $baseApiUri = null,
  40 + Service $service
  41 + )
  42 + {
  43 + $this->service = $service;
  44 + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
  45 + }
  46 +
  47 + /**
  48 + * @return string
  49 + */
  50 + public function service()
  51 + {
  52 + return $this->service->getServiceName();
  53 + }
  54 +
  55 + /**
  56 + * @return StdOAuth1Token
  57 + */
  58 + public function retrieveAccessToken()
  59 + {
  60 + return $this->storage->retrieveAccessToken($this->service());
  61 + }
  62 +
  63 + /**
  64 + *
  65 + */
  66 + public function hasValidAccessToken()
  67 + {
  68 + $serviceName = $this->service();
  69 +
  70 + if (!$this->storage->hasAccessToken($serviceName)) {
  71 + return false;
  72 + }
  73 +
  74 + /** @var $token StdOAuth1Token */
  75 + $token = $this->storage->retrieveAccessToken($serviceName);
  76 +
  77 + $params = $token->getExtraParams();
  78 + if (isset($params['is_request_token'])) {
  79 + return false;
  80 + }
  81 +
  82 + return $this->checkTokenLifetime($token);
  83 + }
  84 +
  85 + /**
  86 + * @param TokenInterface $token
  87 + * @return bool
  88 + */
  89 + protected function checkTokenLifetime($token)
  90 + {
  91 + // assume that we have at least a minute to execute a queries.
  92 + return $token->getEndOfLife() - 60 > time()
  93 + || $token->getEndOfLife() === TokenInterface::EOL_NEVER_EXPIRES
  94 + || $token->getEndOfLife() === TokenInterface::EOL_UNKNOWN;
  95 + }
  96 +
  97 + /**
  98 + * @return null|TokenInterface
  99 + */
  100 + public function getAccessToken()
  101 + {
  102 + if (!$this->hasValidAccessToken()) {
  103 + return null;
  104 + }
  105 +
  106 + $serviceName = $this->service();
  107 + return $this->storage->retrieveAccessToken($serviceName);
  108 + }
  109 +
  110 + /**
  111 + * @return UriInterface
  112 + */
  113 + public function getRequestTokenEndpoint()
  114 + {
  115 + return new Uri($this->service->getRequestTokenEndpoint());
  116 + }
  117 +
  118 + /**
  119 + * @return UriInterface
  120 + */
  121 + public function getAuthorizationEndpoint()
  122 + {
  123 + return new Uri($this->service->getAuthorizationEndpoint());
  124 + }
  125 +
  126 + /**
  127 + * @return UriInterface
  128 + */
  129 + public function getAccessTokenEndpoint()
  130 + {
  131 + return new Uri($this->service->getAccessTokenEndpoint());
  132 + }
  133 +
  134 + /**
  135 + * We need a separate request token parser only to verify the `oauth_callback_confirmed` parameter. For the actual
  136 + * parsing we can just use the default access token parser.
  137 + *
  138 + * @param string $responseBody
  139 + * @return StdOAuth1Token
  140 + * @throws TokenResponseException
  141 + */
  142 + protected function parseRequestTokenResponse($responseBody)
  143 + {
  144 + parse_str($responseBody, $data);
  145 +
  146 + if (!isset($data) || !is_array($data)) {
  147 + throw new TokenResponseException('Unable to parse response.');
  148 + } else if (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] != 'true') {
  149 + throw new TokenResponseException('Error in retrieving token.');
  150 + }
  151 +
  152 + $data['is_request_token'] = true;
  153 + return $this->parseAccessTokenResponse($data);
  154 + }
  155 +
  156 + /**
  157 + * @param string|array $responseBody
  158 + * @return StdOAuth1Token
  159 + * @throws TokenResponseException
  160 + */
  161 + protected function parseAccessTokenResponse($responseBody)
  162 + {
  163 + if (!is_array($responseBody)) {
  164 + parse_str($responseBody, $data);
  165 +
  166 + if (!isset($data) || !is_array($data)) {
  167 + throw new TokenResponseException('Unable to parse response.');
  168 + }
  169 + } else {
  170 + $data = $responseBody;
  171 + }
  172 +
  173 + $error = $this->service->getAccessTokenResponseError($data);
  174 + if (isset($error)) {
  175 + throw new TokenResponseException('Error in retrieving token: "' . $error . '"');
  176 + }
  177 +
  178 + $token = new StdOAuth1Token();
  179 + $names = $this->service->getAccessTokenArgumentNames();
  180 +
  181 + $token->setRequestToken($data[$names['oauth_token']]);
  182 + $token->setRequestTokenSecret($data[$names['oauth_token_secret']]);
  183 + $token->setAccessToken($data[$names['oauth_token']]);
  184 + $token->setAccessTokenSecret($data[$names['oauth_token_secret']]);
  185 + unset($data[$names['oauth_token']], $data[$names['oauth_token_secret']]);
  186 +
  187 + if (isset($data[$names['oauth_expires_in']])) {
  188 + $token->setLifeTime($data[$names['oauth_expires_in']]);
  189 + unset($data[$names['oauth_expires_in']]);
  190 + } else {
  191 + $token->setLifetime($this->service->getTokenDefaultLifetime());
  192 + }
  193 +
  194 + $token->setExtraParams($data);
  195 +
  196 + return $token;
  197 + }
  198 +}
0 199 \ No newline at end of file
... ...
common/components/nodge/eauth/src/oauth2/Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OAuth2 Service class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth2;
  11 +
  12 +use Yii;
  13 +use yii\helpers\Url;
  14 +use OAuth\Common\Exception\Exception as OAuthException;
  15 +use OAuth\Common\Http\Uri\Uri;
  16 +use OAuth\Common\Consumer\Credentials;
  17 +use OAuth\OAuth2\Service\ServiceInterface;
  18 +use nodge\eauth\EAuth;
  19 +use nodge\eauth\ErrorException;
  20 +use nodge\eauth\IAuthService;
  21 +use nodge\eauth\oauth\ServiceBase;
  22 +
  23 +/**
  24 + * EOAuthService is a base class for all OAuth providers.
  25 + *
  26 + * @package application.extensions.eauth
  27 + */
  28 +abstract class Service extends ServiceBase implements IAuthService
  29 +{
  30 +
  31 + /**
  32 + * @var string OAuth2 client id.
  33 + */
  34 + protected $clientId;
  35 +
  36 + /**
  37 + * @var string OAuth2 client secret key.
  38 + */
  39 + protected $clientSecret;
  40 +
  41 + /**
  42 + * @var array OAuth scopes.
  43 + */
  44 + protected $scopes = [];
  45 +
  46 + /**
  47 + * @var string
  48 + */
  49 + protected $scopeSeparator = ' ';
  50 +
  51 + /**
  52 + * @var array Provider options. Must contain the keys: authorize, access_token.
  53 + */
  54 + protected $providerOptions = [
  55 + 'authorize' => '',
  56 + 'access_token' => '',
  57 + ];
  58 +
  59 + /**
  60 + * @var string Error key name in _GET options.
  61 + */
  62 + protected $errorParam = 'error';
  63 +
  64 + /**
  65 + * @var string Error description key name in _GET options.
  66 + */
  67 + protected $errorDescriptionParam = 'error_description';
  68 +
  69 + /**
  70 + * @var string Error code for access_denied response.
  71 + */
  72 + protected $errorAccessDeniedCode = 'access_denied';
  73 +
  74 + /**
  75 + * @var string The display name for popup window. False to disable display mode.
  76 + */
  77 + protected $popupDisplayName = 'popup';
  78 +
  79 + /**
  80 + * @var bool Whether to use the State param to improve security.
  81 + */
  82 + protected $validateState = true;
  83 +
  84 + /**
  85 + * @var ServiceProxy
  86 + */
  87 + private $_proxy;
  88 +
  89 + /**
  90 + * Initialize the component.
  91 + *
  92 + * @param EAuth $component the component instance.
  93 + * @param array $options properties initialization.
  94 + */
  95 +// public function init($component, $options = []) {
  96 +// parent::init($component, $options);
  97 +// }
  98 +
  99 + /**
  100 + * @param string $id
  101 + */
  102 + public function setClientId($id)
  103 + {
  104 + $this->clientId = $id;
  105 + }
  106 +
  107 + /**
  108 + * @param string $secret
  109 + */
  110 + public function setClientSecret($secret)
  111 + {
  112 + $this->clientSecret = $secret;
  113 + }
  114 +
  115 + /**
  116 + * @param string|array $scopes
  117 + */
  118 + public function setScope($scopes)
  119 + {
  120 + if (!is_array($scopes)) {
  121 + $scopes = [$scopes];
  122 + }
  123 +
  124 + $resolvedScopes = [];
  125 + $reflClass = new \ReflectionClass($this);
  126 + $constants = $reflClass->getConstants();
  127 +
  128 + foreach ($scopes as $scope) {
  129 + $key = strtoupper('SCOPE_' . $scope);
  130 +
  131 + // try to find a class constant with this name
  132 + if (array_key_exists($key, $constants)) {
  133 + $resolvedScopes[] = $constants[$key];
  134 + } else {
  135 + $resolvedScopes[] = $scope;
  136 + }
  137 + }
  138 +
  139 + $this->scopes = $resolvedScopes;
  140 + }
  141 +
  142 + /**
  143 + * @param bool $validate
  144 + */
  145 + public function setValidateState($validate)
  146 + {
  147 + $this->validateState = $validate;
  148 + }
  149 +
  150 + /**
  151 + * @return bool
  152 + */
  153 + public function getValidateState()
  154 + {
  155 + return $this->validateState;
  156 + }
  157 +
  158 + /**
  159 + * @return ServiceProxy
  160 + */
  161 + protected function getProxy()
  162 + {
  163 + if (!isset($this->_proxy)) {
  164 + $tokenStorage = $this->getTokenStorage();
  165 + $httpClient = $this->getHttpClient();
  166 + $credentials = new Credentials($this->clientId, $this->clientSecret, $this->getCallbackUrl());
  167 + $this->_proxy = new ServiceProxy($credentials, $httpClient, $tokenStorage, $this->scopes, null, $this);
  168 + }
  169 + return $this->_proxy;
  170 + }
  171 +
  172 + /**
  173 + * @return string the current url
  174 + */
  175 + protected function getCallbackUrl()
  176 + {
  177 + if (isset($_GET['redirect_uri'])) {
  178 + $url = $_GET['redirect_uri'];
  179 + }
  180 + else {
  181 + $route = Yii::$app->getRequest()->getQueryParams();
  182 + array_unshift($route, '');
  183 +
  184 + // Can not use these params in OAuth2 callbacks
  185 + foreach (['code', 'state', 'redirect_uri'] as $param) {
  186 + if (isset($route[$param])) {
  187 + unset($route[$param]);
  188 + }
  189 + }
  190 +
  191 + $url = Url::to($route, true);
  192 + }
  193 +
  194 + return $url;
  195 + }
  196 +
  197 + /**
  198 + * Authenticate the user.
  199 + *
  200 + * @return boolean whether user was successfuly authenticated.
  201 + * @throws ErrorException
  202 + */
  203 + public function authenticate()
  204 + {
  205 + if (!$this->checkError()) {
  206 + return false;
  207 + }
  208 +
  209 + try {
  210 + $proxy = $this->getProxy();
  211 +
  212 + if (!empty($_GET['code'])) {
  213 + // This was a callback request from a service, get the token
  214 + $proxy->requestAccessToken($_GET['code']);
  215 + $this->authenticated = true;
  216 + } else if ($proxy->hasValidAccessToken()) {
  217 + $this->authenticated = true;
  218 + } else {
  219 + /** @var $url Uri */
  220 + $url = $proxy->getAuthorizationUri();
  221 + Yii::$app->getResponse()->redirect($url->getAbsoluteUri())->send();
  222 + }
  223 + } catch (OAuthException $e) {
  224 + throw new ErrorException($e->getMessage(), $e->getCode(), 1, $e->getFile(), $e->getLine(), $e);
  225 + }
  226 +
  227 + return $this->getIsAuthenticated();
  228 + }
  229 +
  230 + /**
  231 + * Check request params for error code and message.
  232 + *
  233 + * @return bool
  234 + * @throws ErrorException
  235 + */
  236 + protected function checkError()
  237 + {
  238 + if (isset($_GET[$this->errorParam])) {
  239 + $error_code = $_GET[$this->errorParam];
  240 + if ($error_code === $this->errorAccessDeniedCode) {
  241 + // access_denied error (user canceled)
  242 + $this->cancel();
  243 + } else {
  244 + $error = $error_code;
  245 + if (isset($_GET[$this->errorDescriptionParam])) {
  246 + $error = $_GET[$this->errorDescriptionParam] . ' (' . $error . ')';
  247 + }
  248 + throw new ErrorException($error);
  249 + }
  250 + return false;
  251 + }
  252 +
  253 + return true;
  254 + }
  255 +
  256 + /**
  257 + * @return string
  258 + */
  259 + public function getAuthorizationEndpoint()
  260 + {
  261 + $url = $this->providerOptions['authorize'];
  262 + if ($this->popupDisplayName !== false && $this->getIsInsidePopup()) {
  263 + $url = new Uri($url);
  264 + $url->addToQuery('display', $this->popupDisplayName);
  265 + $url = $url->getAbsoluteUri();
  266 + }
  267 + return $url;
  268 + }
  269 +
  270 + /**
  271 + * @return string
  272 + */
  273 + public function getAccessTokenEndpoint()
  274 + {
  275 + return $this->providerOptions['access_token'];
  276 + }
  277 +
  278 + /**
  279 + * @param string $response
  280 + * @return array
  281 + */
  282 + public function parseAccessTokenResponse($response)
  283 + {
  284 + return json_decode($response, true);
  285 + }
  286 +
  287 + /**
  288 + * @return array
  289 + */
  290 + public function getAccessTokenArgumentNames()
  291 + {
  292 + return [
  293 + 'access_token' => 'access_token',
  294 + 'expires_in' => 'expires_in',
  295 + 'refresh_token' => 'refresh_token',
  296 + ];
  297 + }
  298 +
  299 + /**
  300 + * Return any additional headers always needed for this service implementation's OAuth calls.
  301 + *
  302 + * @return array
  303 + */
  304 + public function getExtraOAuthHeaders()
  305 + {
  306 + return [];
  307 + }
  308 +
  309 + /**
  310 + * Return any additional headers always needed for this service implementation's API calls.
  311 + *
  312 + * @return array
  313 + */
  314 + public function getExtraApiHeaders()
  315 + {
  316 + return [];
  317 + }
  318 +
  319 + /**
  320 + * Returns a class constant from ServiceInterface defining the authorization method used for the API
  321 + * Header is the sane default.
  322 + *
  323 + * @return int
  324 + */
  325 + public function getAuthorizationMethod()
  326 + {
  327 + return ServiceInterface::AUTHORIZATION_METHOD_HEADER_OAUTH;
  328 + }
  329 +
  330 + /**
  331 + * @return string
  332 + */
  333 + public function getScopeSeparator()
  334 + {
  335 + return $this->scopeSeparator;
  336 + }
  337 +}
0 338 \ No newline at end of file
... ...
common/components/nodge/eauth/src/oauth2/ServiceProxy.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OAuth2 ServiceProxy class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\oauth2;
  11 +
  12 +use OAuth\Common\Consumer\CredentialsInterface;
  13 +use OAuth\Common\Http\Client\ClientInterface;
  14 +use OAuth\Common\Http\Exception\TokenResponseException;
  15 +use OAuth\Common\Http\Uri\Uri;
  16 +use OAuth\Common\Http\Uri\UriInterface;
  17 +use OAuth\Common\Storage\TokenStorageInterface;
  18 +use OAuth\Common\Token\TokenInterface;
  19 +use OAuth\OAuth2\Service\AbstractService;
  20 +use OAuth\OAuth2\Token\StdOAuth2Token;
  21 +
  22 +class ServiceProxy extends AbstractService
  23 +{
  24 +
  25 + /**
  26 + * @var Service the currently used service class
  27 + */
  28 + protected $service;
  29 +
  30 + /**
  31 + * @param CredentialsInterface $credentials
  32 + * @param ClientInterface $httpClient
  33 + * @param TokenStorageInterface $storage
  34 + * @param array $scopes
  35 + * @param UriInterface $baseApiUri
  36 + * @param Service $service
  37 + */
  38 + public function __construct(
  39 + CredentialsInterface $credentials,
  40 + ClientInterface $httpClient,
  41 + TokenStorageInterface $storage,
  42 + $scopes = [],
  43 + UriInterface $baseApiUri = null,
  44 + Service $service
  45 + )
  46 + {
  47 + $this->service = $service;
  48 + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, $service->getValidateState());
  49 + }
  50 +
  51 + /**
  52 + * @return string
  53 + */
  54 + public function service()
  55 + {
  56 + return $this->service->getServiceName();
  57 + }
  58 +
  59 + /**
  60 + * Validate scope
  61 + *
  62 + * @param string $scope
  63 + * @return bool
  64 + */
  65 + public function isValidScope($scope)
  66 + {
  67 + $reflectionClass = new \ReflectionClass(get_class($this->service));
  68 + return in_array($scope, $reflectionClass->getConstants(), true);
  69 + }
  70 +
  71 + /**
  72 + * @return bool
  73 + */
  74 + public function hasValidAccessToken()
  75 + {
  76 + $serviceName = $this->service();
  77 +
  78 + if (!$this->storage->hasAccessToken($serviceName)) {
  79 + return false;
  80 + }
  81 +
  82 + /** @var $token StdOAuth2Token */
  83 + $token = $this->storage->retrieveAccessToken($serviceName);
  84 + $valid = $this->checkTokenLifetime($token);
  85 +
  86 + if (!$valid) {
  87 + $refreshToken = $token->getRefreshToken();
  88 + if (isset($refreshToken)) {
  89 + $token = $this->refreshAccessToken($token);
  90 + return $this->checkTokenLifetime($token);
  91 + }
  92 + }
  93 +
  94 + return $valid;
  95 + }
  96 +
  97 + /**
  98 + * @param TokenInterface $token
  99 + * @return bool
  100 + */
  101 + protected function checkTokenLifetime($token)
  102 + {
  103 + // assume that we have at least a minute to execute a queries.
  104 + return $token->getEndOfLife() - 60 > time()
  105 + || $token->getEndOfLife() === TokenInterface::EOL_NEVER_EXPIRES
  106 + || $token->getEndOfLife() === TokenInterface::EOL_UNKNOWN;
  107 + }
  108 +
  109 + /**
  110 + * @return null|TokenInterface
  111 + */
  112 + public function getAccessToken()
  113 + {
  114 + if (!$this->hasValidAccessToken()) {
  115 + return null;
  116 + }
  117 +
  118 + $serviceName = $this->service();
  119 + return $this->storage->retrieveAccessToken($serviceName);
  120 + }
  121 +
  122 + /**
  123 + * @return UriInterface
  124 + */
  125 + public function getAuthorizationEndpoint()
  126 + {
  127 + return new Uri($this->service->getAuthorizationEndpoint());
  128 + }
  129 +
  130 + /**
  131 + * @return UriInterface
  132 + */
  133 + public function getAccessTokenEndpoint()
  134 + {
  135 + return new Uri($this->service->getAccessTokenEndpoint());
  136 + }
  137 +
  138 + /**
  139 + * @param string $responseBody
  140 + * @return StdOAuth2Token
  141 + * @throws TokenResponseException
  142 + */
  143 + protected function parseAccessTokenResponse($responseBody)
  144 + {
  145 + $data = $this->service->parseAccessTokenResponse($responseBody);
  146 +
  147 + if (!isset($data) || !is_array($data)) {
  148 + throw new TokenResponseException('Unable to parse response.');
  149 + }
  150 +
  151 + $error = $this->service->getAccessTokenResponseError($data);
  152 + if (isset($error)) {
  153 + throw new TokenResponseException('Error in retrieving token: "' . $error . '"');
  154 + }
  155 +
  156 + $token = new StdOAuth2Token();
  157 + $names = $this->service->getAccessTokenArgumentNames();
  158 +
  159 + $token->setAccessToken($data[$names['access_token']]);
  160 + unset($data[$names['access_token']]);
  161 +
  162 + if (isset($data[$names['expires_in']])) {
  163 + $token->setLifeTime($data[$names['expires_in']]);
  164 + unset($data[$names['expires_in']]);
  165 + } else {
  166 + $token->setLifetime($this->service->getTokenDefaultLifetime());
  167 + }
  168 +
  169 + if (isset($data[$names['refresh_token']])) {
  170 + $token->setRefreshToken($data[$names['refresh_token']]);
  171 + unset($data[$names['refresh_token']]);
  172 + }
  173 +
  174 + $token->setExtraParams($data);
  175 +
  176 + return $token;
  177 + }
  178 +
  179 + /**
  180 + * Return any additional headers always needed for this service implementation's OAuth calls.
  181 + *
  182 + * @return array
  183 + */
  184 + protected function getExtraOAuthHeaders()
  185 + {
  186 + return $this->service->getExtraOAuthHeaders();
  187 + }
  188 +
  189 + /**
  190 + * Return any additional headers always needed for this service implementation's API calls.
  191 + *
  192 + * @return array
  193 + */
  194 + protected function getExtraApiHeaders()
  195 + {
  196 + return $this->service->getExtraApiHeaders();
  197 + }
  198 +
  199 + /**
  200 + * Returns a class constant from ServiceInterface defining the authorization method used for the API
  201 + * Header is the sane default.
  202 + *
  203 + * @return int
  204 + */
  205 + protected function getAuthorizationMethod()
  206 + {
  207 + return $this->service->getAuthorizationMethod();
  208 + }
  209 +
  210 + /**
  211 + * Returns the url to redirect to for authorization purposes.
  212 + *
  213 + * @param array $additionalParameters
  214 + * @return Uri
  215 + */
  216 + public function getAuthorizationUri(array $additionalParameters = [])
  217 + {
  218 + $parameters = array_merge($additionalParameters, [
  219 + 'type' => 'web_server',
  220 + 'client_id' => $this->credentials->getConsumerId(),
  221 + 'redirect_uri' => $this->credentials->getCallbackUrl(),
  222 + 'response_type' => 'code',
  223 + ]);
  224 +
  225 + $parameters['scope'] = implode($this->service->getScopeSeparator(), $this->scopes);
  226 +
  227 + if ($this->needsStateParameterInAuthUrl()) {
  228 + if (!isset($parameters['state'])) {
  229 + $parameters['state'] = $this->generateAuthorizationState();
  230 + }
  231 + $this->storeAuthorizationState($parameters['state']);
  232 + }
  233 +
  234 + // Build the url
  235 + $url = clone $this->getAuthorizationEndpoint();
  236 + foreach ($parameters as $key => $val) {
  237 + $url->addToQuery($key, $val);
  238 + }
  239 +
  240 + return $url;
  241 + }
  242 +}
... ...
common/components/nodge/eauth/src/openid/ControllerBehavior.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * ControllerBehavior class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\openid;
  11 +
  12 +use Yii;
  13 +use yii\base\Action;
  14 +use yii\base\ActionFilter;
  15 +
  16 +/**
  17 + * @package application.extensions.eauth
  18 + */
  19 +class ControllerBehavior extends ActionFilter
  20 +{
  21 + /**
  22 + * This method is invoked right before an action is to be executed (after all possible filters.)
  23 + * You may override this method to do last-minute preparation for the action.
  24 + *
  25 + * @param Action $action the action to be executed.
  26 + * @return boolean whether the action should continue to be executed.
  27 + */
  28 + public function beforeAction($action)
  29 + {
  30 + $request = Yii::$app->getRequest();
  31 +
  32 + if (in_array($request->getBodyParam('openid_mode', ''), ['id_res', 'cancel'])) {
  33 + $request->enableCsrfValidation = false;
  34 + }
  35 +
  36 + return parent::beforeAction($action);
  37 + }
  38 +}
... ...
common/components/nodge/eauth/src/openid/Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OpenID Service class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\openid;
  11 +
  12 +use \Yii;
  13 +use \LightOpenID;
  14 +use yii\web\HttpException;
  15 +use nodge\eauth\ServiceBase;
  16 +use nodge\eauth\IAuthService;
  17 +use nodge\eauth\ErrorException;
  18 +
  19 +/**
  20 + * EOpenIDService is a base class for all OpenID providers.
  21 + *
  22 + * @package application.extensions.eauth
  23 + */
  24 +abstract class Service extends ServiceBase implements IAuthService
  25 +{
  26 +
  27 + /**
  28 + * @var string a pattern that represents the part of URL-space for which an OpenID Authentication request is valid.
  29 + * See the spec for more info: http://openid.net/specs/openid-authentication-2_0.html#realms
  30 + * Note: a pattern can be without http(s):// part
  31 + */
  32 + public $realm;
  33 +
  34 + /**
  35 + * @var LightOpenID the openid library instance.
  36 + */
  37 + private $auth;
  38 +
  39 + /**
  40 + * @var string the OpenID authorization url.
  41 + */
  42 + protected $url;
  43 +
  44 + /**
  45 + * @var array the OpenID required attributes.
  46 + */
  47 + protected $requiredAttributes = [];
  48 +
  49 + /**
  50 + * @var array the OpenID optional attributes.
  51 + */
  52 + protected $optionalAttributes = [];
  53 +
  54 +
  55 + /**
  56 + * Initialize the component.
  57 + */
  58 + public function init()
  59 + {
  60 + parent::init();
  61 + $this->auth = new LightOpenID(Yii::$app->getRequest()->getHostInfo());
  62 + }
  63 +
  64 + /**
  65 + * Authenticate the user.
  66 + *
  67 + * @return boolean whether user was successfuly authenticated.
  68 + * @throws ErrorException
  69 + * @throws HttpException
  70 + */
  71 + public function authenticate()
  72 + {
  73 + if (!empty($_REQUEST['openid_mode'])) {
  74 + switch ($_REQUEST['openid_mode']) {
  75 + case 'id_res':
  76 + $this->id_res();
  77 + return true;
  78 + break;
  79 +
  80 + case 'cancel':
  81 + $this->cancel();
  82 + break;
  83 +
  84 + default:
  85 + throw new HttpException(400, Yii::t('yii', 'Your request is invalid.'));
  86 + break;
  87 + }
  88 + } else {
  89 + $this->request();
  90 + }
  91 +
  92 + return false;
  93 + }
  94 +
  95 + /**
  96 + * @throws ErrorException
  97 + */
  98 + protected function id_res()
  99 + {
  100 + try {
  101 + if ($this->auth->validate()) {
  102 + $this->attributes['id'] = $this->auth->identity;
  103 + $this->loadRequiredAttributes();
  104 + $this->loadOptionalAttributes();
  105 + $this->authenticated = true;
  106 + } else {
  107 + throw new ErrorException(Yii::t('eauth', 'Unable to complete the authentication because the required data was not received.', ['provider' => $this->getServiceTitle()]));
  108 + }
  109 + } catch (\Exception $e) {
  110 + throw new ErrorException($e->getMessage(), $e->getCode());
  111 + }
  112 + }
  113 +
  114 + /**
  115 + * @throws ErrorException
  116 + */
  117 + protected function loadOptionalAttributes()
  118 + {
  119 + $attributes = $this->auth->getAttributes();
  120 + foreach ($this->optionalAttributes as $key => $attr) {
  121 + if (isset($attributes[$attr[1]])) {
  122 + $this->attributes[$key] = $attributes[$attr[1]];
  123 + }
  124 + }
  125 + }
  126 +
  127 + /**
  128 + *
  129 + */
  130 + protected function loadRequiredAttributes()
  131 + {
  132 + $attributes = $this->auth->getAttributes();
  133 + foreach ($this->requiredAttributes as $key => $attr) {
  134 + if (isset($attributes[$attr[1]])) {
  135 + $this->attributes[$key] = $attributes[$attr[1]];
  136 + } else {
  137 + throw new ErrorException(Yii::t('eauth', 'Unable to complete the authentication because the required data was not received.', ['provider' => $this->getServiceTitle()]));
  138 + }
  139 + }
  140 + }
  141 +
  142 + /**
  143 + * @throws ErrorException
  144 + */
  145 + protected function request()
  146 + {
  147 + $this->auth->identity = $this->url; //Setting identifier
  148 +
  149 + $this->auth->required = []; //Try to get info from openid provider
  150 + foreach ($this->requiredAttributes as $attribute) {
  151 + $this->auth->required[$attribute[0]] = $attribute[1];
  152 + }
  153 + foreach ($this->optionalAttributes as $attribute) {
  154 + $this->auth->required[$attribute[0]] = $attribute[1];
  155 + }
  156 +
  157 + $this->auth->realm = $this->getRealm();
  158 + $this->auth->returnUrl = Yii::$app->getRequest()->getHostInfo() . Yii::$app->getRequest()->getUrl(); //getting return URL
  159 +
  160 + try {
  161 + $url = $this->auth->authUrl();
  162 + Yii::$app->getResponse()->redirect($url)->send();
  163 + } catch (\Exception $e) {
  164 + throw new ErrorException($e->getMessage(), $e->getCode());
  165 + }
  166 + }
  167 +
  168 + /**
  169 + * @return string
  170 + */
  171 + protected function getRealm()
  172 + {
  173 + if (isset($this->realm)) {
  174 + if (!preg_match('#^[a-z]+\://#', $this->realm)) {
  175 + return 'http' . (Yii::$app->getRequest()->getIsSecureConnection() ? 's' : '') . '://' . $this->realm;
  176 + } else {
  177 + return $this->realm;
  178 + }
  179 + } else {
  180 + return Yii::$app->getRequest()->getHostInfo();
  181 + }
  182 + }
  183 +}
... ...
common/components/nodge/eauth/src/services/FacebookOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * FacebookOAuth2Service class file.
  4 + *
  5 + * Register application: https://developers.facebook.com/apps/
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +namespace common\components\nodge\eauth\src\services;
  12 +use nodge\eauth\oauth2\Service;
  13 +/**
  14 + * Facebook provider class.
  15 + *
  16 + * @package application.extensions.eauth.services
  17 + */
  18 +class FacebookOAuth2Service extends Service
  19 +{
  20 + /**
  21 + * Full list of scopes may be found here:
  22 + * https://developers.facebook.com/docs/authentication/permissions/
  23 + */
  24 + const SCOPE_EMAIL = 'email';
  25 + const SCOPE_USER_BIRTHDAY = 'user_birthday';
  26 + const SCOPE_USER_HOMETOWN = 'user_hometown';
  27 + const SCOPE_USER_LOCATION = 'user_location';
  28 + const SCOPE_USER_PHOTOS = 'user_photos';
  29 + protected $name = 'facebook';
  30 + protected $title = 'Facebook';
  31 + protected $type = 'OAuth2';
  32 + protected $jsArguments = ['popup' => ['width' => 585, 'height' => 290]];
  33 + protected $scopes = [];
  34 + protected $providerOptions = [
  35 + 'authorize' => 'https://www.facebook.com/dialog/oauth',
  36 + 'access_token' => 'https://graph.facebook.com/oauth/access_token',
  37 + ];
  38 + protected $baseApiUrl = 'https://graph.facebook.com/';
  39 + protected $errorParam = 'error_code';
  40 + protected $errorDescriptionParam = 'error_message';
  41 + protected function fetchAttributes()
  42 + {
  43 + $info = $this->makeSignedRequest('me');
  44 + $this->attributes['id'] = $info['id'];
  45 + $this->attributes['name'] = $info['name'];
  46 + $this->attributes['url'] = $info['link'];
  47 + return true;
  48 + }
  49 + /**
  50 + * @return array
  51 + */
  52 + public function getAccessTokenArgumentNames()
  53 + {
  54 + $names = parent::getAccessTokenArgumentNames();
  55 + $names['expires_in'] = 'expires';
  56 + return $names;
  57 + }
  58 + /**
  59 + * @param string $response
  60 + * @return array
  61 + */
  62 + public function parseAccessTokenResponse($response)
  63 + {
  64 + // Facebook gives us a query string or json
  65 + if ($response[0] === '{') {
  66 + return json_decode($response, true);
  67 + }
  68 + else {
  69 + parse_str($response, $data);
  70 + return $data;
  71 + }
  72 + }
  73 + /**
  74 + * Returns the error array.
  75 + *
  76 + * @param array $response
  77 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  78 + */
  79 + protected function fetchResponseError($response)
  80 + {
  81 + if (isset($response['error'])) {
  82 + return [
  83 + 'code' => $response['error']['code'],
  84 + 'message' => $response['error']['message'],
  85 + ];
  86 + } else {
  87 + return null;
  88 + }
  89 + }
  90 + /**
  91 + * @param array $data
  92 + * @return string|null
  93 + */
  94 + public function getAccessTokenResponseError($data)
  95 + {
  96 + $error = $this->fetchResponseError($data);
  97 + if (!$error) {
  98 + return null;
  99 + }
  100 + return $error['code'].': '.$error['message'];
  101 + }
  102 +}
0 103 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/GitHubOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * GithubOAuth2Service class file.
  4 + *
  5 + * Register application: https://github.com/settings/applications
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use OAuth\Common\Token\TokenInterface;
  15 +use OAuth\OAuth2\Service\ServiceInterface;
  16 +use nodge\eauth\oauth2\Service;
  17 +
  18 +/**
  19 + * GitHub provider class.
  20 + *
  21 + * @package application.extensions.eauth.services
  22 + */
  23 +class GitHubOAuth2Service extends Service
  24 +{
  25 +
  26 + /**
  27 + * Defined scopes, see http://developer.github.com/v3/oauth/ for definitions
  28 + */
  29 + const SCOPE_USER = 'user';
  30 + const SCOPE_PUBLIC_REPO = 'public_repo';
  31 + const SCOPE_REPO = 'repo';
  32 + const SCOPE_DELETE_REPO = 'delete_repo';
  33 + const SCOPE_GIST = 'gist';
  34 +
  35 + protected $name = 'github';
  36 + protected $title = 'GitHub';
  37 + protected $type = 'OAuth2';
  38 + protected $jsArguments = ['popup' => ['width' => 600, 'height' => 450]];
  39 +
  40 + protected $scopes = [];
  41 + protected $providerOptions = [
  42 + 'authorize' => 'https://github.com/login/oauth/authorize',
  43 + 'access_token' => 'https://github.com/login/oauth/access_token',
  44 + ];
  45 + protected $baseApiUrl = 'https://api.github.com/';
  46 +
  47 + protected $tokenDefaultLifetime = TokenInterface::EOL_NEVER_EXPIRES;
  48 + protected $errorAccessDeniedCode = 'user_denied';
  49 +
  50 + protected function fetchAttributes()
  51 + {
  52 + $info = $this->makeSignedRequest('user');
  53 +
  54 + $this->attributes['id'] = $info['id'];
  55 + $this->attributes['name'] = $info['login'];
  56 + $this->attributes['url'] = $info['html_url'];
  57 +
  58 + return true;
  59 + }
  60 +
  61 + /**
  62 + * Used to configure response type -- we want JSON from github, default is query string format
  63 + *
  64 + * @return array
  65 + */
  66 + public function getExtraOAuthHeaders()
  67 + {
  68 + return ['Accept' => 'application/json'];
  69 + }
  70 +
  71 + /**
  72 + * Required for GitHub API calls.
  73 + *
  74 + * @return array
  75 + */
  76 + public function getExtraApiHeaders()
  77 + {
  78 + return ['Accept' => 'application/vnd.github.beta+json'];
  79 + }
  80 +
  81 + /**
  82 + * @return int
  83 + */
  84 + public function getAuthorizationMethod()
  85 + {
  86 + return ServiceInterface::AUTHORIZATION_METHOD_QUERY_STRING;
  87 + }
  88 +
  89 + /**
  90 + * Returns the error array.
  91 + *
  92 + * @param array $response
  93 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  94 + */
  95 + protected function fetchResponseError($response)
  96 + {
  97 + if (isset($response['message'])) {
  98 + return [
  99 + 'code' => isset($response['error']) ? $response['code'] : 0,
  100 + 'message' => $response['message'],
  101 + ];
  102 + } else {
  103 + return null;
  104 + }
  105 + }
  106 +
  107 +}
0 108 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/GoogleOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * GoogleOAuth2Service class file.
  4 + *
  5 + * Register application: https://code.google.com/apis/console/
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use nodge\eauth\oauth2\Service;
  15 +
  16 +/**
  17 + * Google provider class.
  18 + *
  19 + * @package application.extensions.eauth.services
  20 + */
  21 +class GoogleOAuth2Service extends Service
  22 +{
  23 +
  24 + /**
  25 + * Defined scopes - More scopes are listed here:
  26 + * https://developers.google.com/oauthplayground/
  27 + */
  28 +
  29 + // Basic
  30 + const SCOPE_EMAIL = 'email';
  31 + const SCOPE_PROFILE = 'profile';
  32 +
  33 + const SCOPE_USERINFO_EMAIL = 'https://www.googleapis.com/auth/userinfo.email';
  34 + const SCOPE_USERINFO_PROFILE = 'https://www.googleapis.com/auth/userinfo.profile';
  35 +
  36 + // Google+
  37 + const SCOPE_GPLUS_ME = 'https://www.googleapis.com/auth/plus.me';
  38 + const SCOPE_GPLUS_LOGIN = 'https://www.googleapis.com/auth/plus.login';
  39 +
  40 + // Google Drive
  41 + const SCOPE_DOCUMENTSLIST = 'https://docs.google.com/feeds/';
  42 + const SCOPE_SPREADSHEETS = 'https://spreadsheets.google.com/feeds/';
  43 + const SCOPE_GOOGLEDRIVE = 'https://www.googleapis.com/auth/drive';
  44 + const SCOPE_DRIVE_APPS = 'https://www.googleapis.com/auth/drive.appdata';
  45 + const SCOPE_DRIVE_APPS_READ_ONLY = 'https://www.googleapis.com/auth/drive.apps.readonly';
  46 + const SCOPE_GOOGLEDRIVE_FILES = 'https://www.googleapis.com/auth/drive.file';
  47 + const SCOPE_DRIVE_METADATA_READ_ONLY = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  48 + const SCOPE_DRIVE_READ_ONLY = 'https://www.googleapis.com/auth/drive.readonly';
  49 + const SCOPE_DRIVE_SCRIPTS = 'https://www.googleapis.com/auth/drive.scripts';
  50 +
  51 + // Adwords
  52 + const SCOPE_ADSENSE = 'https://www.googleapis.com/auth/adsense';
  53 + const SCOPE_ADWORDS = 'https://adwords.google.com/api/adwords/';
  54 + const SCOPE_GAN = 'https://www.googleapis.com/auth/gan'; // google affiliate network...?
  55 +
  56 + // Google Analytics
  57 + const SCOPE_ANALYTICS = 'https://www.googleapis.com/auth/analytics';
  58 + const SCOPE_ANALYTICS_EDIT = 'https://www.googleapis.com/auth/analytics.edit';
  59 + const SCOPE_ANALYTICS_MANAGE_USERS = 'https://www.googleapis.com/auth/analytics.manage.users';
  60 + const SCOPE_ANALYTICS_READ_ONLY = 'https://www.googleapis.com/auth/analytics.readonly';
  61 +
  62 + // Other services
  63 + const SCOPE_BOOKS = 'https://www.googleapis.com/auth/books';
  64 + const SCOPE_BLOGGER = 'https://www.googleapis.com/auth/blogger';
  65 + const SCOPE_CALENDAR = 'https://www.googleapis.com/auth/calendar';
  66 + const SCOPE_CONTACT = 'https://www.google.com/m8/feeds/';
  67 + const SCOPE_CHROMEWEBSTORE = 'https://www.googleapis.com/auth/chromewebstore.readonly';
  68 + const SCOPE_GMAIL = 'https://mail.google.com/mail/feed/atom';
  69 + const SCOPE_PICASAWEB = 'https://picasaweb.google.com/data/';
  70 + const SCOPE_SITES = 'https://sites.google.com/feeds/';
  71 + const SCOPE_URLSHORTENER = 'https://www.googleapis.com/auth/urlshortener';
  72 + const SCOPE_WEBMASTERTOOLS = 'https://www.google.com/webmasters/tools/feeds/';
  73 + const SCOPE_TASKS = 'https://www.googleapis.com/auth/tasks';
  74 +
  75 + // Cloud services
  76 + const SCOPE_CLOUDSTORAGE = 'https://www.googleapis.com/auth/devstorage.read_write';
  77 + const SCOPE_CONTENTFORSHOPPING = 'https://www.googleapis.com/auth/structuredcontent'; // what even is this
  78 + const SCOPE_USER_PROVISIONING = 'https://apps-apis.google.com/a/feeds/user/';
  79 + const SCOPE_GROUPS_PROVISIONING = 'https://apps-apis.google.com/a/feeds/groups/';
  80 + const SCOPE_NICKNAME_PROVISIONING = 'https://apps-apis.google.com/a/feeds/alias/';
  81 +
  82 + // Old
  83 + const SCOPE_ORKUT = 'https://www.googleapis.com/auth/orkut';
  84 + const SCOPE_GOOGLELATITUDE =
  85 + 'https://www.googleapis.com/auth/latitude.all.best https://www.googleapis.com/auth/latitude.all.city';
  86 + const SCOPE_OPENID = 'openid';
  87 +
  88 + // YouTube
  89 + const SCOPE_YOUTUBE_GDATA = 'https://gdata.youtube.com';
  90 + const SCOPE_YOUTUBE_ANALYTICS_MONETARY = 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly';
  91 + const SCOPE_YOUTUBE_ANALYTICS = 'https://www.googleapis.com/auth/yt-analytics.readonly';
  92 + const SCOPE_YOUTUBE = 'https://www.googleapis.com/auth/youtube';
  93 + const SCOPE_YOUTUBE_READ_ONLY = 'https://www.googleapis.com/auth/youtube.readonly';
  94 + const SCOPE_YOUTUBE_UPLOAD = 'https://www.googleapis.com/auth/youtube.upload';
  95 + const SCOPE_YOUTUBE_PATNER = 'https://www.googleapis.com/auth/youtubepartner';
  96 + const SCOPE_YOUTUBE_PARTNER_EDIT = 'https://www.googleapis.com/auth/youtubepartner-channel-edit';
  97 +
  98 + // Google Glass
  99 + const SCOPE_GLASS_TIMELINE = 'https://www.googleapis.com/auth/glass.timeline';
  100 + const SCOPE_GLASS_LOCATION = 'https://www.googleapis.com/auth/glass.location';
  101 +
  102 + protected $name = 'google_oauth';
  103 + protected $title = 'Google';
  104 + protected $type = 'OAuth2';
  105 + protected $jsArguments = ['popup' => ['width' => 500, 'height' => 450]];
  106 +
  107 + protected $scopes = [self::SCOPE_USERINFO_PROFILE];
  108 + protected $providerOptions = [
  109 + 'authorize' => 'https://accounts.google.com/o/oauth2/auth',
  110 + 'access_token' => 'https://accounts.google.com/o/oauth2/token',
  111 + ];
  112 +
  113 + protected function fetchAttributes()
  114 + {
  115 + $info = $this->makeSignedRequest('https://www.googleapis.com/oauth2/v1/userinfo');
  116 +
  117 + $this->attributes['id'] = $info['id'];
  118 + $this->attributes['name'] = $info['name'];
  119 +
  120 + if (!empty($info['link'])) {
  121 + $this->attributes['url'] = $info['link'];
  122 + }
  123 +
  124 + /*if (!empty($info['gender']))
  125 + $this->attributes['gender'] = $info['gender'] == 'male' ? 'M' : 'F';
  126 +
  127 + if (!empty($info['picture']))
  128 + $this->attributes['photo'] = $info['picture'];
  129 +
  130 + $info['given_name']; // first name
  131 + $info['family_name']; // last name
  132 + $info['birthday']; // format: 0000-00-00
  133 + $info['locale']; // format: en*/
  134 + }
  135 +
  136 + /**
  137 + * Returns the protected resource.
  138 + *
  139 + * @param string $url url to request.
  140 + * @param array $options HTTP request options. Keys: query, data, referer.
  141 + * @param boolean $parseResponse Whether to parse response.
  142 + * @return mixed the response.
  143 + */
  144 + public function makeSignedRequest($url, $options = [], $parseResponse = true)
  145 + {
  146 + if (!isset($options['query']['alt'])) {
  147 + $options['query']['alt'] = 'json';
  148 + }
  149 + return parent::makeSignedRequest($url, $options, $parseResponse);
  150 + }
  151 +
  152 + /**
  153 + * Returns the error array.
  154 + *
  155 + * @param array $response
  156 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  157 + */
  158 + protected function fetchResponseError($response)
  159 + {
  160 + if (isset($response['error'])) {
  161 + return [
  162 + 'code' => $response['error']['code'],
  163 + 'message' => $response['error']['message'],
  164 + ];
  165 + } else {
  166 + return null;
  167 + }
  168 + }
  169 +}
0 170 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/InstagramOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * FacebookOAuth2Service class file.
  4 + *
  5 + * Register application: https://instagram.com/developer/register/
  6 + *
  7 + * @author PhucPNT. <mail@phucpnt.com>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use nodge\eauth\oauth2\Service;
  15 +use OAuth\Common\Token\TokenInterface;
  16 +use OAuth\OAuth2\Service\ServiceInterface;
  17 +
  18 +/**
  19 + * Instagram provider class.
  20 + *
  21 + * @package application.extensions.eauth.services
  22 + */
  23 +class InstagramOAuth2Service extends Service
  24 +{
  25 +
  26 + /**
  27 + * Defined scopes
  28 + * @link https://instagram.com/developer/authentication/
  29 + */
  30 + const SCOPE_BASIC = 'basic';
  31 + const SCOPE_COMMENTS = 'comments';
  32 + const SCOPE_RELATIONSHIPS = 'relationships';
  33 + const SCOPE_LIKES = 'likes';
  34 +
  35 + protected $name = 'instagram';
  36 + protected $title = 'Instagram';
  37 + protected $type = 'OAuth2';
  38 + protected $jsArguments = ['popup' => ['width' => 900, 'height' => 550]];
  39 + protected $popupDisplayName = false;
  40 +
  41 + protected $scopes = [self::SCOPE_BASIC];
  42 + protected $providerOptions = [
  43 + 'authorize' => 'https://api.instagram.com/oauth/authorize/',
  44 + 'access_token' => 'https://api.instagram.com/oauth/access_token',
  45 + ];
  46 + protected $baseApiUrl = 'https://api.instagram.com/v1/';
  47 +
  48 + protected $tokenDefaultLifetime = TokenInterface::EOL_NEVER_EXPIRES;
  49 +
  50 + protected function fetchAttributes()
  51 + {
  52 + $info = $this->makeSignedRequest('users/self');
  53 + $data = $info['data'];
  54 +
  55 + $this->attributes = array_merge($this->attributes, [
  56 + 'id' => $data['id'],
  57 + 'username' => $data['username'],
  58 + 'full_name' => $data['full_name'],
  59 + 'profile_picture' => $data['profile_picture'],
  60 + 'bio' => $data['bio'],
  61 + 'website' => $data['website'],
  62 + 'counts' => $data['counts']
  63 + ]);
  64 +
  65 + return true;
  66 + }
  67 +
  68 + /**
  69 + * @return int
  70 + */
  71 + public function getAuthorizationMethod()
  72 + {
  73 + return ServiceInterface::AUTHORIZATION_METHOD_QUERY_STRING;
  74 + }
  75 +
  76 + /**
  77 + * Returns the protected resource.
  78 + *
  79 + * @param string $url url to request.
  80 + * @param array $options HTTP request options. Keys: query, data, referer.
  81 + * @param boolean $parseResponse Whether to parse response.
  82 + * @return mixed the response.
  83 + */
  84 + public function makeSignedRequest($url, $options = [], $parseResponse = true)
  85 + {
  86 + $options['query']['format'] = 'json';
  87 + return parent::makeSignedRequest($url, $options, $parseResponse);
  88 + }
  89 +
  90 +}
0 91 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/LinkedinOAuth1Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * LinkedinOAuthService class file.
  4 + *
  5 + * Register application: https://www.linkedin.com/secure/developer
  6 + * Note: Integration URL should be filled with a valid callback url.
  7 + *
  8 + * @author Maxim Zemskov <nodge@yandex.ru>
  9 + * @link http://github.com/Nodge/yii2-eauth/
  10 + * @license http://www.opensource.org/licenses/bsd-license.php
  11 + */
  12 +
  13 +namespace common\components\nodge\eauth\src\services;
  14 +
  15 +use nodge\eauth\oauth1\Service;
  16 +
  17 +/**
  18 + * LinkedIn provider class.
  19 + *
  20 + * @package application.extensions.eauth.services
  21 + */
  22 +class LinkedinOAuth1Service extends Service
  23 +{
  24 +
  25 + protected $name = 'linkedin';
  26 + protected $title = 'LinkedIn';
  27 + protected $type = 'OAuth1';
  28 + protected $jsArguments = ['popup' => ['width' => 900, 'height' => 550]];
  29 +
  30 + protected $providerOptions = [
  31 + 'request' => 'https://api.linkedin.com/uas/oauth/requestToken',
  32 + 'authorize' => 'https://www.linkedin.com/uas/oauth/authenticate', // https://www.linkedin.com/uas/oauth/authorize
  33 + 'access' => 'https://api.linkedin.com/uas/oauth/accessToken',
  34 + ];
  35 + protected $baseApiUrl = 'http://api.linkedin.com/v1/';
  36 +
  37 + protected function fetchAttributes()
  38 + {
  39 + $info = $this->makeSignedRequest('people/~:(id,first-name,last-name,public-profile-url)', [
  40 + 'query' => [
  41 + 'format' => 'json',
  42 + ],
  43 + ]);
  44 +
  45 + $this->attributes['id'] = $info['id'];
  46 + $this->attributes['name'] = $info['firstName'] . ' ' . $info['lastName'];
  47 + $this->attributes['url'] = $info['publicProfileUrl'];
  48 +
  49 + return true;
  50 + }
  51 +
  52 + /**
  53 + * Returns the error array.
  54 + *
  55 + * @param array $response
  56 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  57 + */
  58 + protected function fetchResponseError($response)
  59 + {
  60 + if (isset($response['error-code'])) {
  61 + return [
  62 + 'code' => $response['error-code'],
  63 + 'message' => $response['message'],
  64 + ];
  65 + } else if (isset($response['errorCode'])) {
  66 + return [
  67 + 'code' => $response['errorCode'],
  68 + 'message' => $response['message'],
  69 + ];
  70 + }
  71 + return null;
  72 + }
  73 +}
0 74 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/LinkedinOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * LinkedinOAuth2Service class file.
  4 + *
  5 + * Register application: https://www.linkedin.com/secure/developer
  6 + * Note: Integration URL should be filled with a valid callback url.
  7 + *
  8 + * @author Maxim Zemskov <nodge@yandex.ru>
  9 + * @link http://github.com/Nodge/yii2-eauth/
  10 + * @license http://www.opensource.org/licenses/bsd-license.php
  11 + */
  12 +
  13 +namespace common\components\nodge\eauth\src\services;
  14 +
  15 +use OAuth\OAuth2\Service\ServiceInterface;
  16 +use nodge\eauth\oauth2\Service;
  17 +
  18 +/**
  19 + * LinkedIn provider class.
  20 + *
  21 + * @package application.extensions.eauth.services
  22 + */
  23 +class LinkedinOAuth2Service extends Service
  24 +{
  25 +
  26 + /**
  27 + * Defined scopes
  28 + *
  29 + * @link http://developer.linkedin.com/documents/authentication#granting
  30 + */
  31 + const SCOPE_R_BASICPROFILE = 'r_basicprofile';
  32 + const SCOPE_R_FULLPROFILE = 'r_fullprofile';
  33 + const SCOPE_R_EMAILADDRESS = 'r_emailaddress';
  34 + const SCOPE_R_NETWORK = 'r_network';
  35 + const SCOPE_R_CONTACTINFO = 'r_contactinfo';
  36 + const SCOPE_RW_NUS = 'rw_nus';
  37 + const SCOPE_RW_GROUPS = 'rw_groups';
  38 + const SCOPE_W_MESSAGES = 'w_messages';
  39 +
  40 + protected $name = 'linkedin_oauth2';
  41 + protected $title = 'LinkedIn';
  42 + protected $type = 'OAuth2';
  43 + protected $jsArguments = ['popup' => ['width' => 900, 'height' => 550]];
  44 +
  45 + protected $scopes = [self::SCOPE_R_BASICPROFILE];
  46 + protected $providerOptions = [
  47 + 'authorize' => 'https://www.linkedin.com/uas/oauth2/authorization',
  48 + 'access_token' => 'https://www.linkedin.com/uas/oauth2/accessToken',
  49 + ];
  50 + protected $baseApiUrl = 'https://api.linkedin.com/v1/';
  51 +
  52 + protected function fetchAttributes()
  53 + {
  54 + $info = $this->makeSignedRequest('people/~:(id,first-name,last-name,public-profile-url)', [
  55 + 'query' => [
  56 + 'format' => 'json',
  57 + ],
  58 + ]);
  59 +
  60 + $this->attributes['id'] = $info['id'];
  61 + $this->attributes['name'] = $info['firstName'] . ' ' . $info['lastName'];
  62 + $this->attributes['url'] = $info['publicProfileUrl'];
  63 + $this->attributes['email'] = $info['emailAddress'];
  64 + return true;
  65 + }
  66 +
  67 + /**
  68 + * @return int
  69 + */
  70 + public function getAuthorizationMethod()
  71 + {
  72 + return ServiceInterface::AUTHORIZATION_METHOD_QUERY_STRING_V2;
  73 + }
  74 +}
... ...
common/components/nodge/eauth/src/services/LiveOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * LiveOAuth2Service class file.
  4 + *
  5 + * Register application: https://account.live.com/developers/applications/index
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use OAuth\OAuth2\Service\ServiceInterface;
  15 +use nodge\eauth\oauth2\Service;
  16 +
  17 +/**
  18 + * Microsoft Live provider class.
  19 + *
  20 + * @package application.extensions.eauth.services
  21 + */
  22 +class LiveOAuth2Service extends Service
  23 +{
  24 +
  25 + const SCOPE_BASIC = 'wl.basic';
  26 + const SCOPE_OFFLINE = 'wl.offline_access';
  27 + const SCOPE_SIGNIN = 'wl.signin';
  28 + const SCOPE_BIRTHDAY = 'wl.birthday';
  29 + const SCOPE_CALENDARS = 'wl.calendars';
  30 + const SCOPE_CALENDARS_UPDATE = 'wl.calendars_update';
  31 + const SCOPE_CONTACTS_BIRTHDAY = 'wl.contacts_birthday';
  32 + const SCOPE_CONTACTS_CREATE = 'wl.contacts_create';
  33 + const SCOPE_CONTACTS_CALENDARS = 'wl.contacts_calendars';
  34 + const SCOPE_CONTACTS_PHOTOS = 'wl.contacts_photos';
  35 + const SCOPE_CONTACTS_SKYDRIVE = 'wl.contacts_skydrive';
  36 + const SCOPE_EMAILS = 'wl.emails';
  37 + const sCOPE_EVENTS_CREATE = 'wl.events_create';
  38 + const SCOPE_MESSENGER = 'wl.messenger';
  39 + const SCOPE_PHONE_NUMBERS = 'wl.phone_numbers';
  40 + const SCOPE_PHOTOS = 'wl.photos';
  41 + const SCOPE_POSTAL_ADDRESSES = 'wl.postal_addresses';
  42 + const SCOPE_SHARE = 'wl.share';
  43 + const SCOPE_SKYDRIVE = 'wl.skydrive';
  44 + const SCOPE_SKYDRIVE_UPDATE = 'wl.skydrive_update';
  45 + const SCOPE_WORK_PROFILE = 'wl.work_profile';
  46 + const SCOPE_APPLICATIONS = 'wl.applications';
  47 + const SCOPE_APPLICATIONS_CREATE = 'wl.applications_create';
  48 +
  49 + protected $name = 'live';
  50 + protected $title = 'Live';
  51 + protected $type = 'OAuth2';
  52 + protected $jsArguments = ['popup' => ['width' => 500, 'height' => 600]];
  53 +
  54 + protected $scopes = [self::SCOPE_BASIC];
  55 + protected $providerOptions = [
  56 + 'authorize' => 'https://login.live.com/oauth20_authorize.srf',
  57 + 'access_token' => 'https://login.live.com/oauth20_token.srf',
  58 + ];
  59 + protected $baseApiUrl = 'https://apis.live.net/v5.0/';
  60 +
  61 + protected function fetchAttributes()
  62 + {
  63 + $info = $this->makeSignedRequest('me');
  64 +
  65 + $this->attributes['id'] = $info['id'];
  66 + $this->attributes['name'] = $info['name'];
  67 + $this->attributes['url'] = 'https://profile.live.com/cid-' . $info['id'] . '/';
  68 +
  69 + $this->attributes['email'] = $info['emails']['account'];
  70 + $this->attributes['first_name'] = $info['first_name'];
  71 + $this->attributes['last_name'] = $info['last_name'];
  72 + $this->attributes['gender'] = $info['gender'];
  73 + $this->attributes['locale'] = $info['locale'];
  74 +
  75 + return true;
  76 + }
  77 +
  78 + /**
  79 + * @return int
  80 + */
  81 + public function getAuthorizationMethod()
  82 + {
  83 + return ServiceInterface::AUTHORIZATION_METHOD_QUERY_STRING;
  84 + }
  85 +}
0 86 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/MailruOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * MailruOAuth2Service class file.
  4 + *
  5 + * Register application: http://api.mail.ru/sites/my/add
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use nodge\eauth\oauth2\Service;
  15 +
  16 +/**
  17 + * Mail.Ru provider class.
  18 + *
  19 + * @package application.extensions.eauth.services
  20 + */
  21 +class MailruOAuth2Service extends Service
  22 +{
  23 +
  24 + protected $name = 'mailru';
  25 + protected $title = 'Mail.ru';
  26 + protected $type = 'OAuth2';
  27 + protected $jsArguments = ['popup' => ['width' => 580, 'height' => 400]];
  28 +
  29 + protected $scopes = [];
  30 + protected $providerOptions = [
  31 + 'authorize' => 'https://connect.mail.ru/oauth/authorize',
  32 + 'access_token' => 'https://connect.mail.ru/oauth/token',
  33 + ];
  34 + protected $baseApiUrl = 'http://www.appsmail.ru/platform/api';
  35 +
  36 + protected function fetchAttributes()
  37 + {
  38 + $tokenData = $this->getAccessTokenData();
  39 +
  40 + $info = $this->makeSignedRequest('/', [
  41 + 'query' => [
  42 + 'uids' => $tokenData['params']['x_mailru_vid'],
  43 + 'method' => 'users.getInfo',
  44 + 'app_id' => $this->clientId,
  45 + ],
  46 + ]);
  47 +
  48 + $info = $info[0];
  49 +
  50 + $this->attributes['id'] = $info['uid'];
  51 + $this->attributes['name'] = $info['first_name'] . ' ' . $info['last_name'];
  52 + $this->attributes['url'] = $info['link'];
  53 +
  54 + return true;
  55 + }
  56 +
  57 + /**
  58 + * Returns the protected resource.
  59 + *
  60 + * @param string $url url to request.
  61 + * @param array $options HTTP request options. Keys: query, data, referer.
  62 + * @param boolean $parseResponse Whether to parse response.
  63 + * @return mixed the response.
  64 + */
  65 + public function makeSignedRequest($url, $options = [], $parseResponse = true)
  66 + {
  67 + $token = $this->getAccessTokenData();
  68 + if (isset($token)) {
  69 + $options['query']['secure'] = 1;
  70 + $options['query']['session_key'] = $token['access_token'];
  71 + $params = '';
  72 + ksort($options['query']);
  73 + foreach ($options['query'] as $k => $v) {
  74 + $params .= $k . '=' . $v;
  75 + }
  76 + $options['query']['sig'] = md5($params . $this->clientSecret);
  77 + }
  78 + return parent::makeSignedRequest($url, $options, $parseResponse);
  79 + }
  80 +
  81 + /**
  82 + * Returns the error array.
  83 + *
  84 + * @param array $response
  85 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  86 + */
  87 + protected function fetchResponseError($response)
  88 + {
  89 + if (isset($response['error'])) {
  90 + return [
  91 + 'code' => $response['error']['error_code'],
  92 + 'message' => $response['error']['error_msg'],
  93 + ];
  94 + } else {
  95 + return null;
  96 + }
  97 + }
  98 +}
0 99 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/OdnoklassnikiOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * OdnoklassnikiOAuthService class file.
  4 + *
  5 + * Register application: http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=13992188
  6 + * Manage your applications: http://www.odnoklassniki.ru/dk?st.cmd=appsInfoMyDevList&st._aid=Apps_Info_MyDev
  7 + * Note: Enabling this service a little more difficult because of the authorization policy of the service.
  8 + *
  9 + * @author Maxim Zemskov <nodge@yandex.ru>
  10 + * @link http://github.com/Nodge/yii2-eauth/
  11 + * @license http://www.opensource.org/licenses/bsd-license.php
  12 + */
  13 +
  14 +namespace common\components\nodge\eauth\src\services;
  15 +
  16 +use nodge\eauth\oauth2\Service;
  17 +
  18 +/**
  19 + * Odnoklassniki.Ru provider class.
  20 + *
  21 + * @package application.extensions.eauth.services
  22 + */
  23 +class OdnoklassnikiOAuth2Service extends Service
  24 +{
  25 +
  26 + const SCOPE_VALUABLE_ACCESS = 'VALUABLE ACCESS';
  27 + const SCOPE_SET_STATUS = 'SET STATUS';
  28 + const SCOPE_PHOTO_CONTENT = 'PHOTO CONTENT';
  29 +
  30 + protected $name = 'odnoklassniki';
  31 + protected $title = 'Odnoklassniki';
  32 + protected $type = 'OAuth2';
  33 + protected $jsArguments = ['popup' => ['width' => 680, 'height' => 500]];
  34 +
  35 + protected $clientPublic;
  36 + protected $scopes = [];
  37 + protected $scopeSeparator = ';';
  38 + protected $providerOptions = [
  39 + 'authorize' => 'http://www.odnoklassniki.ru/oauth/authorize',
  40 + 'access_token' => 'http://api.odnoklassniki.ru/oauth/token.do',
  41 + ];
  42 + protected $baseApiUrl = 'http://api.odnoklassniki.ru/fb.do';
  43 +
  44 + protected $tokenDefaultLifetime = 1500; // about 25 minutes
  45 + protected $validateState = false;
  46 +
  47 + protected function fetchAttributes()
  48 + {
  49 + $info = $this->makeSignedRequest('', [
  50 + 'query' => [
  51 + 'method' => 'users.getCurrentUser',
  52 + 'format' => 'JSON',
  53 + 'application_key' => $this->clientPublic,
  54 + 'client_id' => $this->clientId,
  55 + ],
  56 + ]);
  57 +
  58 + $this->attributes['id'] = $info['uid'];
  59 + $this->attributes['name'] = $info['first_name'] . ' ' . $info['last_name'];
  60 +
  61 + return true;
  62 + }
  63 +
  64 + /**
  65 + * @return string
  66 + */
  67 + public function getClientPublic()
  68 + {
  69 + return $this->clientPublic;
  70 + }
  71 +
  72 + /**
  73 + * @param string $clientPublic
  74 + */
  75 + public function setClientPublic($clientPublic)
  76 + {
  77 + $this->clientPublic = $clientPublic;
  78 + }
  79 +
  80 + /**
  81 + * Returns the protected resource.
  82 + *
  83 + * @param string $url url to request.
  84 + * @param array $options HTTP request options. Keys: query, data, referer.
  85 + * @param boolean $parseResponse Whether to parse response.
  86 + * @return mixed the response.
  87 + */
  88 + public function makeSignedRequest($url, $options = [], $parseResponse = true)
  89 + {
  90 + $token = $this->getAccessTokenData();
  91 + if (isset($token)) {
  92 + $params = '';
  93 + ksort($options['query']);
  94 + foreach ($options['query'] as $k => $v) {
  95 + $params .= $k . '=' . $v;
  96 + }
  97 + $options['query']['sig'] = md5($params . md5($token['access_token'] . $this->clientSecret));
  98 + $options['query']['access_token'] = $token['access_token'];
  99 + }
  100 + return parent::makeSignedRequest($url, $options, $parseResponse);
  101 + }
  102 +
  103 + /**
  104 + * Returns the error array.
  105 + *
  106 + * @param array $response
  107 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  108 + */
  109 + protected function fetchResponseError($response)
  110 + {
  111 + if (isset($response['error_code'])) {
  112 + return [
  113 + 'code' => $response['error_code'],
  114 + 'message' => $response['error_msg'],
  115 + ];
  116 + } else {
  117 + return null;
  118 + }
  119 + }
  120 +
  121 +}
... ...
common/components/nodge/eauth/src/services/SteamOpenIDService.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * SteamOpenIDService class file.
  4 + *
  5 + * @author Dmitry Ananichev <a@qozz.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\components\nodge\eauth\src\services;
  11 +
  12 +use nodge\eauth\openid\Service;
  13 +
  14 +/**
  15 + * Steam provider class.
  16 + *
  17 + * @package application.extensions.eauth.services
  18 + */
  19 +class SteamOpenIDService extends Service
  20 +{
  21 +
  22 + protected $name = 'steam';
  23 + protected $title = 'Steam';
  24 + protected $type = 'OpenID';
  25 + protected $jsArguments = ['popup' => ['width' => 990, 'height' => 615]];
  26 +
  27 + protected $url = 'http://steamcommunity.com/openid/';
  28 +
  29 + protected function fetchAttributes()
  30 + {
  31 + if (isset($this->attributes['id'])) {
  32 + $urlChunks = explode('/', $this->attributes['id']);
  33 + if ($count = count($urlChunks)) {
  34 + $name = $urlChunks[$count - 1];
  35 + $this->attributes['name'] = $name;
  36 + }
  37 + }
  38 + }
  39 +
  40 +}
0 41 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/TwitterOAuth1Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * TwitterOAuthService class file.
  4 + *
  5 + * Register application: https://dev.twitter.com/apps/new
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use OAuth\OAuth1\Token\TokenInterface;
  15 +use nodge\eauth\oauth1\Service;
  16 +
  17 +
  18 +/**
  19 + * Twitter provider class.
  20 + *
  21 + * @package application.extensions.eauth.services
  22 + */
  23 +class TwitterOAuth1Service extends Service
  24 +{
  25 +
  26 + protected $name = 'twitter';
  27 + protected $title = 'Twitter';
  28 + protected $type = 'OAuth1';
  29 + protected $jsArguments = ['popup' => ['width' => 900, 'height' => 550]];
  30 +
  31 + protected $providerOptions = [
  32 + 'request' => 'https://api.twitter.com/oauth/request_token',
  33 + 'authorize' => 'https://api.twitter.com/oauth/authenticate', //https://api.twitter.com/oauth/authorize
  34 + 'access' => 'https://api.twitter.com/oauth/access_token',
  35 + ];
  36 + protected $baseApiUrl = 'https://api.twitter.com/1.1/';
  37 + protected $tokenDefaultLifetime = TokenInterface::EOL_NEVER_EXPIRES;
  38 +
  39 + /**
  40 + * @return bool
  41 + */
  42 + protected function fetchAttributes()
  43 + {
  44 + $info = $this->makeSignedRequest('account/verify_credentials.json');
  45 +
  46 + $this->attributes['id'] = $info['id'];
  47 + $this->attributes['name'] = $info['name'];
  48 + $this->attributes['url'] = 'http://twitter.com/account/redirect_by_id?id=' . $info['id_str'];
  49 +
  50 + $this->attributes['username'] = $info['screen_name'];
  51 + $this->attributes['language'] = $info['lang'];
  52 + $this->attributes['timezone'] = timezone_name_from_abbr('', $info['utc_offset'], date('I'));
  53 + $this->attributes['photo'] = $info['profile_image_url'];
  54 +
  55 + return true;
  56 + }
  57 +
  58 + /**
  59 + * Authenticate the user.
  60 + *
  61 + * @return boolean whether user was successfuly authenticated.
  62 + */
  63 + public function authenticate()
  64 + {
  65 + if (isset($_GET['denied'])) {
  66 + $this->cancel();
  67 + }
  68 +
  69 + return parent::authenticate();
  70 + }
  71 +}
0 72 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/VKontakteOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * VKontakteOAuth2Service class file.
  4 + *
  5 + * Register application: http://vk.com/editapp?act=create&site=1
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use nodge\eauth\oauth2\Service;
  15 +use OAuth\OAuth2\Service\ServiceInterface;
  16 +
  17 +/**
  18 + * VKontakte provider class.
  19 + *
  20 + * @package application.extensions.eauth.services
  21 + */
  22 +class VKontakteOAuth2Service extends Service
  23 +{
  24 +
  25 + const SCOPE_FRIENDS = 'friends';
  26 +
  27 + protected $name = 'vkontakte';
  28 + protected $title = 'VK.com';
  29 + protected $type = 'OAuth2';
  30 + protected $jsArguments = ['popup' => ['width' => 585, 'height' => 350]];
  31 +
  32 + protected $scopes = [self::SCOPE_FRIENDS];
  33 + protected $providerOptions = [
  34 + 'authorize' => 'http://api.vk.com/oauth/authorize',
  35 + 'access_token' => 'https://api.vk.com/oauth/access_token',
  36 + ];
  37 + protected $baseApiUrl = 'https://api.vk.com/method/';
  38 +
  39 + protected function fetchAttributes()
  40 + {
  41 + $tokenData = $this->getAccessTokenData();
  42 + $info = $this->makeSignedRequest('users.get.json', [
  43 + 'query' => [
  44 + 'uids' => $tokenData['params']['user_id'],
  45 + 'fields' => '', // uid, first_name and last_name is always available
  46 + 'fields' => 'nickname, sex, bdate, city, country, timezone, photo, photo_medium, photo_big, photo_rec',
  47 + ],
  48 + ]);
  49 +
  50 + $info = $info['response'][0];
  51 +
  52 + $this->attributes['id'] = $info['uid'];
  53 + $this->attributes['name'] = $info['first_name'] . ' ' . $info['last_name'];
  54 + $this->attributes['url'] = 'http://vk.com/id' . $info['uid'];
  55 +
  56 + if (!empty($info['nickname']))
  57 + $this->attributes['username'] = $info['nickname'];
  58 + else
  59 + $this->attributes['username'] = 'id'.$info['uid'];
  60 +
  61 + $this->attributes['gender'] = $info['sex'] == 1 ? 'F' : 'M';
  62 +
  63 + $this->attributes['city'] = $info['city'];
  64 + $this->attributes['country'] = $info['country'];
  65 +
  66 + $this->attributes['timezone'] = timezone_name_from_abbr('', $info['timezone']*3600, date('I'));;
  67 +
  68 + $this->attributes['photo'] = $info['photo'];
  69 + $this->attributes['photo_medium'] = $info['photo_medium'];
  70 + $this->attributes['photo_big'] = $info['photo_big'];
  71 + $this->attributes['photo_rec'] = $info['photo_rec'];
  72 +
  73 + return true;
  74 + }
  75 +
  76 + /**
  77 + * Returns the error array.
  78 + *
  79 + * @param array $response
  80 + * @return array the error array with 2 keys: code and message. Should be null if no errors.
  81 + */
  82 + protected function fetchResponseError($response)
  83 + {
  84 + if (isset($response['error'])) {
  85 + return [
  86 + 'code' => is_string($response['error']) ? 0 : $response['error']['error_code'],
  87 +// 'message' => is_string($response['error']) ? $response['error'] : $response['error']['error_msg'],
  88 +// 'message' => is_string($response['error']) ? $response['error'] : $response['error']['error_msg'],
  89 + ];
  90 + } else {
  91 + return null;
  92 + }
  93 + }
  94 +
  95 + /**
  96 + * @param array $data
  97 + * @return string|null
  98 + */
  99 + public function getAccessTokenResponseError($data)
  100 + {
  101 + if (!isset($data['error'])) {
  102 + return null;
  103 + }
  104 + $error = $data['error'];
  105 + if (isset($data['error_description'])) {
  106 + $error .= ': ' . $data['error_description'];
  107 + }
  108 + return $error;
  109 + }
  110 +
  111 + /**
  112 + * Returns a class constant from ServiceInterface defining the authorization method used for the API.
  113 + *
  114 + * @return int
  115 + */
  116 + public function getAuthorizationMethod()
  117 + {
  118 + return ServiceInterface::AUTHORIZATION_METHOD_QUERY_STRING;
  119 + }
  120 +
  121 +}
0 122 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/YahooOpenIDService.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * YahooOpenIDService class file.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace common\components\nodge\eauth\src\services;
  11 +
  12 +use nodge\eauth\openid\Service;
  13 +
  14 +/**
  15 + * Yahoo provider class.
  16 + *
  17 + * @package application.extensions.eauth.services
  18 + */
  19 +class YahooOpenIDService extends Service
  20 +{
  21 +
  22 + protected $name = 'yahoo';
  23 + protected $title = 'Yahoo';
  24 + protected $type = 'OpenID';
  25 + protected $jsArguments = ['popup' => ['width' => 880, 'height' => 520]];
  26 +
  27 + protected $url = 'https://me.yahoo.com';
  28 + protected $requiredAttributes = [
  29 + 'name' => ['fullname', 'namePerson'],
  30 + 'login' => ['nickname', 'namePerson/friendly'],
  31 + 'email' => ['email', 'contact/email'],
  32 + ];
  33 + protected $optionalAttributes = [
  34 + 'language' => ['language', 'pref/language'],
  35 + 'gender' => ['gender', 'person/gender'],
  36 + 'timezone' => ['timezone', 'pref/timezone'],
  37 + 'image' => ['image', 'media/image/default'],
  38 + ];
  39 +
  40 + /*protected function fetchAttributes() {
  41 + $this->attributes['fullname'] = $this->attributes['name'].' '.$this->attributes['lastname'];
  42 + return true;
  43 + }*/
  44 +}
0 45 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/YandexOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * YandexOAuth2Service class file.
  4 + *
  5 + * Register application: https://oauth.yandex.ru/client/my
  6 + *
  7 + * @author Maxim Zemskov <nodge@yandex.ru>
  8 + * @link http://github.com/Nodge/yii2-eauth/
  9 + * @license http://www.opensource.org/licenses/bsd-license.php
  10 + */
  11 +
  12 +namespace common\components\nodge\eauth\src\services;
  13 +
  14 +use OAuth\Common\Token\TokenInterface;
  15 +use nodge\eauth\oauth2\Service;
  16 +
  17 +/**
  18 + * Yandex OAuth provider class.
  19 + *
  20 + * @package application.extensions.eauth.services
  21 + */
  22 +class YandexOAuth2Service extends Service
  23 +{
  24 +
  25 + protected $name = 'yandex_oauth';
  26 + protected $title = 'Yandex';
  27 + protected $type = 'OAuth2';
  28 + protected $jsArguments = ['popup' => ['width' => 500, 'height' => 450]];
  29 + protected $tokenDefaultLifetime = TokenInterface::EOL_NEVER_EXPIRES;
  30 +
  31 + protected $scope = [];
  32 + protected $providerOptions = [
  33 + 'authorize' => 'https://oauth.yandex.ru/authorize',
  34 + 'access_token' => 'https://oauth.yandex.ru/token',
  35 + ];
  36 +
  37 + protected function fetchAttributes()
  38 + {
  39 + $info = $this->makeSignedRequest('https://login.yandex.ru/info');
  40 +
  41 + $this->attributes['id'] = $info['id'];
  42 + $this->attributes['name'] = $info['real_name'];
  43 + //$this->attributes['login'] = $info['display_name'];
  44 + //$this->attributes['email'] = $info['emails'][0];
  45 + //$this->attributes['email'] = $info['default_email'];
  46 + $this->attributes['gender'] = ($info['sex'] == 'male') ? 'M' : 'F';
  47 +
  48 + return true;
  49 + }
  50 +
  51 +}
0 52 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/extended/FacebookOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * An example of extending the provider class.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\services\extended;
  11 +
  12 +class FacebookOAuth2Service extends \nodge\eauth\services\FacebookOAuth2Service
  13 +{
  14 +
  15 + protected $scopes = [
  16 + self::SCOPE_EMAIL,
  17 + self::SCOPE_USER_BIRTHDAY,
  18 + self::SCOPE_USER_HOMETOWN,
  19 + self::SCOPE_USER_LOCATION,
  20 + self::SCOPE_USER_PHOTOS,
  21 + ];
  22 +
  23 + /**
  24 + * http://developers.facebook.com/docs/reference/api/user/
  25 + *
  26 + * @see FacebookOAuth2Service::fetchAttributes()
  27 + */
  28 + protected function fetchAttributes()
  29 + {
  30 + $this->attributes = $this->makeSignedRequest('me');
  31 + return true;
  32 + }
  33 +}
... ...
common/components/nodge/eauth/src/services/extended/GitHubOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * An example of extending the provider class.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\services\extended;
  11 +
  12 +class GitHubOAuth2Service extends \nodge\eauth\services\GitHubOAuth2Service
  13 +{
  14 +
  15 + protected function fetchAttributes()
  16 + {
  17 + $info = $this->makeSignedRequest('user');
  18 +
  19 + $this->attributes['id'] = $info['id'];
  20 + $this->attributes['name'] = $info['login'];
  21 + $this->attributes['url'] = $info['html_url'];
  22 +
  23 + $this->attributes['following'] = $info['following'];
  24 + $this->attributes['followers'] = $info['followers'];
  25 + $this->attributes['public_repos'] = $info['public_repos'];
  26 + $this->attributes['public_gists'] = $info['public_gists'];
  27 + $this->attributes['avatar_url'] = $info['avatar_url'];
  28 +
  29 + return true;
  30 + }
  31 +}
0 32 \ No newline at end of file
... ...
common/components/nodge/eauth/src/services/extended/MailruOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * An example of extending the provider class.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\services\extended;
  11 +
  12 +class MailruOAuth2Service extends \nodge\eauth\services\MailruOAuth2Service
  13 +{
  14 +
  15 + protected function fetchAttributes()
  16 + {
  17 + $tokenData = $this->getAccessTokenData();
  18 +
  19 + $info = $this->makeSignedRequest('/', [
  20 + 'query' => [
  21 + 'uids' => $tokenData['params']['x_mailru_vid'],
  22 + 'method' => 'users.getInfo',
  23 + 'app_id' => $this->clientId,
  24 + ],
  25 + ]);
  26 +
  27 + $info = $info[0];
  28 +
  29 + $this->attributes['id'] = $info['uid'];
  30 + $this->attributes['name'] = $info['first_name'] . ' ' . $info['last_name'];
  31 + $this->attributes['first_name'] = $info['first_name'];
  32 + $this->attributes['last_name'] = $info['last_name'];
  33 + $this->attributes['url'] = $info['link'];
  34 + $this->attributes['photo'] = $info['pic'];
  35 +
  36 + return true;
  37 + }
  38 +
  39 +}
... ...
common/components/nodge/eauth/src/services/extended/OdnoklassnikiOAuth2Service.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * An example of extending the provider class.
  4 + *
  5 + * @author Maxim Zemskov <nodge@yandex.ru>
  6 + * @link http://github.com/Nodge/yii2-eauth/
  7 + * @license http://www.opensource.org/licenses/bsd-license.php
  8 + */
  9 +
  10 +namespace nodge\eauth\services\extended;
  11 +
  12 +class OdnoklassnikiOAuth2Service extends \nodge\eauth\services\OdnoklassnikiOAuth2Service
  13 +{
  14 +
  15 + protected $scopes = [self::SCOPE_VALUABLE_ACCESS];
  16 +
  17 + protected function fetchAttributes()
  18 + {
  19 + parent::fetchAttributes();
  20 +
  21 + $info = $this->makeSignedRequest('', [
  22 + 'query' => [
  23 + 'method' => 'users.getInfo',
  24 + 'uids' => $this->attributes['id'],
  25 + 'fields' => 'url_profile',
  26 + 'format' => 'JSON',
  27 + 'application_key' => $this->clientPublic,
  28 + 'client_id' => $this->clientId,
  29 + ],
  30 + ]);
  31 +
  32 + preg_match('/\d+\/{0,1}$/', $info[0]->url_profile, $matches);
  33 + $this->attributes['id'] = (int)$matches[0];
  34 + $this->attributes['url'] = $info[0]->url_profile;
  35 +
  36 + return true;
  37 + }
  38 +
  39 +
  40 + /**
  41 + * @param string $link
  42 + * @param string $message
  43 + * @return array
  44 + */
  45 + public function wallPost($link, $message)
  46 + {
  47 + return $this->makeSignedRequest('', [
  48 + 'query' => [
  49 + 'application_key' => $this->clientPublic,
  50 + 'method' => 'share.addLink',
  51 + 'format' => 'JSON',
  52 + 'linkUrl' => $link,
  53 + 'comment' => $message,
  54 + ],
  55 + ]);
  56 + }
  57 +
  58 +}
... ...