OSDN Git Service

初回コミット(v2.6.17.1)
[magic3/magic3.git] / include / manager / accessManager.php
1 <?php\r
2 /**\r
3  * アクセス制御マネージャー\r
4  *\r
5  * PHP versions 5\r
6  *\r
7  * LICENSE: This source file is licensed under the terms of the GNU General Public License.\r
8  *\r
9  * @package    Magic3 Framework\r
10  * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>\r
11  * @copyright  Copyright 2006-2013 Magic3 Project.\r
12  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License\r
13  * @version    SVN: $Id: accessManager.php 6084 2013-06-06 12:58:33Z fishbone $\r
14  * @link       http://www.magic3.org\r
15  */\r
16 require_once(M3_SYSTEM_INCLUDE_PATH . '/common/core.php');\r
17 \r
18 class AccessManager extends Core\r
19 {\r
20         private $db;                                            // DBオブジェクト\r
21         private $_clientId;                                     // クライアントID(クッキー用)\r
22         private $_oldSessionId;                         // 古いセッションID\r
23         private $_accessLogSerialNo;            // アクセスログのシリアルNo\r
24         private $_useAutoLogin;                         // 自動ログイン機能を使用するかどうか\r
25         const LOG_REQUEST_PARAM_MAX_LENGTH      = 1024;                         // ログに保存するリクエストパラメータの最大長\r
26         const PASSWORD_LENGTH = 8;              // パスワード長\r
27         const SEND_PASSWORD_FORM = 'send_tmp_password';         // 仮パスワード送信用フォーム\r
28         const TMP_PASSWORD_AVAILABLE_HOURS = 24;                                                // 仮パスワード有効時間\r
29         const CF_AUTO_LOGIN = 'auto_login';                     // 自動ログイン機能を使用するかどうか\r
30         const AUTO_LOGIN_EXPIRE_DAYS = 30;                      // 自動ログインの有効期間\r
31         \r
32         /**\r
33          * コンストラクタ\r
34          */\r
35         function __construct()\r
36         {\r
37                 // 親クラスを呼び出す\r
38                 parent::__construct();\r
39                 \r
40                 // システムDBオブジェクト取得\r
41                 $this->db = $this->gInstance->getSytemDbObject();\r
42         }\r
43         /**\r
44          * アクセスログ初期化処理(直接呼出し用)\r
45          *\r
46          * @return なし\r
47          */\r
48         function initAccessLog()\r
49         {\r
50                 if (empty($this->_accessLogSerialNo)) $this->accessLog();\r
51         }\r
52         /**\r
53          * ログイン処理\r
54          *\r
55          * ログイン処理を行う。可能な場合はユーザ情報を読み込む\r
56          *\r
57          * @param RequestManager $request               HTTPリクエスト処理クラス\r
58          * @return bool                                                 true=アクセス可能、false=アクセス不可\r
59          */\r
60         function userLogin($request)\r
61         {\r
62                 // アカウント、パスワード取得\r
63                 $account = $request->trimValueOf('account');\r
64                 $password = $request->trimValueOf('password');\r
65                 return $this->userLoginByAccount($account, $password);\r
66         }\r
67         /**\r
68          * ログイン処理\r
69          *\r
70          * ログイン処理を行う。可能な場合はユーザ情報を読み込む\r
71          *\r
72          * @param string $account               アカウント\r
73          * @param string $password              パスワード\r
74          * @param bool $checkUser               ユーザのアクセス権をチェックするかどうか\r
75          * @return bool                                 true=アクセス可能、false=アクセス不可\r
76          */\r
77         function userLoginByAccount($account, $password, $checkUser=true)\r
78         {\r
79                 // 初期化\r
80                 $retValue = false;\r
81                 \r
82                 // アカウントが空のときはアクセス不可\r
83                 if (empty($account)) return false;\r
84                 \r
85                 // ユーザ情報取得\r
86                 if ($this->db->getLoginUserRecord($account, $row)){\r
87                         // ******** ユーザのログインチェック             ********\r
88                         // ******** ログインのチェックを行うのはここだけ ********\r
89                         $checkLogin = false;            // ログインが通ったかどうか\r
90                         $pass  = $row['lu_password'];\r
91                         \r
92                         if ($pass == $password){\r
93                                 $checkLogin = true;                     // パスワード一致\r
94                         } else {\r
95                                 // 仮パスワードが設定されている場合は仮パスワードをチェック\r
96                                 $tmpPass = $row['lu_tmp_password'];                             // 仮パスワード\r
97                                 $tmpPassDt = $row['lu_tmp_pwd_dt'];                     // 仮パスワード変更日時\r
98                                 if (!empty($tmpPass) && $tmpPass == $password && $tmpPassDt != $this->gEnv->getInitValueOfTimestamp() && \r
99                                         strtotime('-' . self::TMP_PASSWORD_AVAILABLE_HOURS . ' hours') <= strtotime($tmpPassDt)){       // 仮パスワード有効のとき\r
100                                         \r
101                                         // 仮パスワード初期化\r
102                                         $fieldArray = array();\r
103                                         $fieldArray['lu_tmp_password'] = '';                            // 仮パスワード\r
104                                         $fieldArray['lu_tmp_pwd_dt'] = $this->gEnv->getInitValueOfTimestamp();                  // 仮パスワード変更日時\r
105                                         $ret = $this->db->updateLoginUserByField($row['lu_id'], $fieldArray, $newSerial);\r
106                                         \r
107                                         $checkLogin = true;                     // パスワード一致\r
108                                 }\r
109                         }\r
110                         \r
111                         if ($checkLogin){                       // パスワード一致のとき\r
112                                 // ユーザ情報を読み込み\r
113                                 $retValue = $this->_loadUserInfo($row, $checkUser);\r
114                         }\r
115                 }\r
116                 // ログインのログを残す\r
117                 if ($retValue){\r
118                         // ユーザログインログを残す\r
119                         $this->gOpeLog->writeUserInfo(__METHOD__, 'ユーザがログインしました。アカウント: ' . $account, 2300,\r
120                                                                                         'account=' . $account . ', passward=' . $password . ', userid=' . $this->gEnv->getCurrentUserId(), 'account=' . $account/*検索補助データ*/);\r
121                 } else {\r
122                         // ユーザエラーログを残す\r
123                         $this->gOpeLog->writeUserError(__METHOD__, 'ユーザがログインに失敗しました。アカウント: ' . $account, 2310,\r
124                                                                                         'account=' . $account . ', passward=' . $password, 'account=' . $account/*検索補助データ*/);\r
125                         \r
126                         // 入力アカウントを保存\r
127                         //$this->db->addErrorLoginLog($account, $accessIp, $this->_accessLogSerialNo);\r
128                 }\r
129                 return $retValue;\r
130         }\r
131         /**\r
132          * ユーザ情報を読み込み\r
133          *\r
134          * @param array $row            ユーザのログインユーザ情報レコード\r
135          * @param bool $checkUser       ユーザのアクセス権のチェックを行うかどうか\r
136          * @return bool                         true=成功、false=失敗\r
137          */\r
138         function _loadUserInfo($row, $checkUser = true)\r
139         {\r
140                 global $gInstanceManager;\r
141                 global $gRequestManager;\r
142                 \r
143                 $now = date("Y/m/d H:i:s");     // 現在日時\r
144                 $accessIp = $gRequestManager->trimServerValueOf('REMOTE_ADDR');         // アクセスIP\r
145                                 \r
146                 // ユーザチェックが必要な場合は承認済みユーザのみ許可する\r
147                 if (($checkUser && $row['lu_user_type'] >= 0 && $row['lu_enable_login'] &&\r
148                         $this->_isActive($row['lu_active_start_dt'], $row['lu_active_end_dt'], $now)) || // 承認済みユーザ、ログイン可能\r
149                         !$checkUser){                   // ユーザのアクセス権をチェックしない場合\r
150                         \r
151                         // ログインした場合はセッションIDを変更する\r
152                         $this->setOldSessionId(session_id());           // 古いセッションIDを保存\r
153                         session_regenerate_id(true);\r
154         \r
155                         // ユーザ情報オブジェクトを作成\r
156                         $userInfo = new UserInfo();\r
157                         $userInfo->userId       = $row['lu_id'];                // ユーザID\r
158                         $userInfo->account      = $row['lu_account'];   // ユーザアカウント\r
159                         $userInfo->name         = $row['lu_name'];              // ユーザ名\r
160                         $userInfo->email        = $row['lu_email'];             // Eメール\r
161                         $userInfo->userType     = $row['lu_user_type']; // ユーザタイプ\r
162                         $userInfo->userTypeOption = $row['lu_user_type_option'];                        // ユーザタイプオプション\r
163                         $userInfo->_recordSerial = $row['lu_serial'];   // レコードシリアル番号\r
164                 \r
165                         // アクセス可能ウィジェット(システム運用者の場合)\r
166                         $userInfo->adminWidget = array();\r
167                         if ($userInfo->userType == UserInfo::USER_TYPE_MANAGER){        // システム運用可能ユーザのとき\r
168                                 $adminWidget = trim($row['lu_admin_widget']);\r
169                                 if (!empty($adminWidget)) $userInfo->adminWidget = explode(',', $adminWidget);\r
170                         }\r
171                         \r
172                         // システム運用可能ユーザの場合は、管理者キーを発行(2011/9/16 修正)\r
173                         if ($userInfo->userType >= UserInfo::USER_TYPE_MANAGER){        // システム運用可能ユーザのとき\r
174                                 $adminKey = $this->createAdminKey();\r
175                                 if ($this->db->addAdminKey($adminKey, $accessIp)) $userInfo->_adminKey = $adminKey;\r
176                         } else {\r
177                                 $userInfo->_adminKey = '';\r
178                         }\r
179                 \r
180                         // インスタンスマネージャーとセッションに保存\r
181                         $gInstanceManager->setUserInfo($userInfo);\r
182                         $gRequestManager->setSessionValueWithSerialize(M3_SESSION_USER_INFO, $userInfo);\r
183                 \r
184                         // ログインのログを残す\r
185                         $this->db->updateLoginLog($userInfo->userId, $this->_accessLogSerialNo);\r
186                         return true;\r
187                 } else {\r
188                         return false;\r
189                 }\r
190         }\r
191         /**\r
192          * 自動ログイン開始処理\r
193          *\r
194          * @return bool                                 true=ログイン成功、false=ログイン不可\r
195          */\r
196         function startAutoLogin()\r
197         {\r
198                 global $gSystemManager;\r
199                 global $gRequestManager;\r
200                 \r
201                 // 自動ログイン機能を使用するかどうか\r
202                 $value = $gSystemManager->getSystemConfig(self::CF_AUTO_LOGIN);\r
203                 $this->_useAutoLogin = isset($value) ? $value : '0';\r
204                 if (!$this->_useAutoLogin) return false;\r
205                 \r
206                 // ログイン中でない場合のみ自動ログイン処理を行う\r
207                 $userId = $this->gEnv->getCurrentUserId();\r
208                 if ($userId > 0) return false;\r
209 \r
210                 // 自動ログイン処理。自動ログイン情報がある場合は自動ログインクッキーも存在する\r
211                 $loginKey = $gRequestManager->getCookieValue(M3_COOKIE_AUTO_LOGIN);             // 自動ログインキー\r
212                 $clientId = $this->getClientId();               // クライアントID\r
213                 if (empty($loginKey) || empty($clientId)) return false;                 // 空の場合は問題なし\r
214                 $ret = $this->db->getAutoLogin($loginKey, $clientId, $row);\r
215                 if (!$ret){             // 自動ログイン情報がない場合は終了\r
216                         // 自動ログイン情報を削除\r
217                         $this->_removeAutoLogin($loginKey);\r
218                         \r
219                         // ユーザエラーログを残す\r
220                         $errMsg = '不正な自動ログインを検出しました。ログインキー: ' . $loginKey;\r
221                         $msgDetail = 'クライアントID=' . $clientId;\r
222                         $this->gOpeLog->writeUserError(__METHOD__, $errMsg, 2310, $msgDetail);\r
223                         return false;\r
224                 }\r
225                 // 自動ログインの有効期間をチェック\r
226                 $expireDt = $row['ag_expire_dt'];\r
227                 $now = date("Y/m/d H:i:s");     // 現在日時\r
228                 if ($expireDt == $this->gEnv->getInitValueOfTimestamp() || strtotime($expireDt) < strtotime($now)){             // 期限切れのとき\r
229                         // 自動ログイン情報を削除\r
230                         $this->_removeAutoLogin($loginKey);\r
231                         return false;\r
232                 }\r
233 \r
234                 // ユーザ情報を取得\r
235                 $ret = $this->db->getLoginUserRecordById($row['ag_user_id'], $userInfoRow);\r
236                 if (!$ret){\r
237                         // 自動ログイン情報を削除\r
238                         $this->_removeAutoLogin($loginKey);\r
239                         \r
240                         $errMsg = '自動ログインエラー(要因=ユーザ情報取得失敗)';\r
241                         $msgDetail = 'ユーザID=' . $row['ag_user_id'];\r
242                         $this->gOpeLog->writeError(__METHOD__, $errMsg, 1100, $msgDetail);\r
243                         return false;\r
244                 }\r
245                 \r
246                 // ユーザレベルをチェック。システム運用可能ユーザは自動ログイン不可。\r
247                 // アクセスパスをチェック?\r
248                 if ($userInfoRow['lu_user_type'] >= UserInfo::USER_TYPE_MANAGER) return false;  // システム運用可能ユーザのとき\r
249                 \r
250                 // ユーザ情報を読み込む\r
251                 $ret = $this->_loadUserInfo($userInfoRow);\r
252                 $userId = $userInfoRow['lu_id'];                // ユーザID再取得\r
253                 $account = $userInfoRow['lu_account'];\r
254                 if ($ret){// ログイン成功\r
255                         // ユーザログインログを残す\r
256                         $errMsg = 'ユーザが自動ログインしました。アカウント: ' . $account;\r
257                         $msgDetail = 'ログインキー=' . $loginKey . ', クライアントID=' . $clientId;\r
258                         $this->gOpeLog->writeUserInfo(__METHOD__, $errMsg, 2302/*自動ログイン*/, $msgDetail, 'account=' . $account/*検索補助データ*/);\r
259                 } else {\r
260                         // 自動ログイン情報を削除\r
261                         $this->_removeAutoLogin($loginKey);\r
262                         \r
263                         // ユーザエラーログを残す\r
264                         $errMsg = 'ユーザが自動ログインに失敗しました。アカウント: ' . $account;\r
265                         $msgDetail = 'ログインキー=' . $loginKey . ', クライアントID=' . $clientId;\r
266                         $this->gOpeLog->writeUserError(__METHOD__, $errMsg, 2310, $msgDetail, 'account=' . $account/*検索補助データ*/);\r
267                         return false;\r
268                 }\r
269                 // 新規のログインキーを作成\r
270                 $newLoginKey = md5($account . $clientId . time());\r
271                 $ret = $this->_createAutoLogin($newLoginKey, $userId, $clientId);\r
272                 if (!$ret){\r
273                         $errMsg = '自動ログインエラー(要因=自動ログイン情報作成失敗)';\r
274                         $msgDetail = 'ログインキー=' . $newLoginKey . ',ユーザID=' . $userId . ',クライアントID=' . $clientId;\r
275                         $this->gOpeLog->writeError(__METHOD__, $errMsg, 1100, $msgDetail);\r
276                 }\r
277                 return true;\r
278         }\r
279         /**\r
280          * 自動ログイン終了処理\r
281          *\r
282          * @return bool                                 true=成功、false=失敗\r
283          */\r
284         function endAutoLogin()\r
285         {\r
286                 if (!$this->_useAutoLogin) return;\r
287         }\r
288         /**\r
289          * 自動ログイン処理\r
290          *\r
291          * @param int $userId                   ユーザID\r
292          * @param bool $isAutoLogin             true=自動ログイン開始、false=自動ログイン終了\r
293          * @return bool                                 true=自動ログイン完了、false=自動ログイン失敗\r
294          */\r
295         function userAutoLogin($userId, $isAutoLogin)\r
296         {\r
297                 // 自動ログイン行わない場合は終了\r
298                 if (!$this->_useAutoLogin) return false;\r
299                 \r
300                 $clientId = $this->getClientId();               // クライアントID\r
301 \r
302                 if ($isAutoLogin){\r
303                         // 引数エラーチェック\r
304                         if ($userId <= 0) return false;\r
305                         if (empty($clientId)) return false;\r
306                 \r
307                         // ユーザ情報取得\r
308                         $userInfo = $this->gEnv->getCurrentUserInfo();\r
309 \r
310                         // ユーザレベルをチェック。システム運用可能ユーザは自動ログイン不可。\r
311                         if ($userInfo->userType >= UserInfo::USER_TYPE_MANAGER) return false;   // システム運用可能ユーザのとき\r
312                         \r
313                         // 新規のログインキーを作成\r
314                         $newLoginKey = md5($userInfo->account . $clientId . time());\r
315                         $ret = $this->_createAutoLogin($newLoginKey, $userId, $clientId);\r
316                         if (!$ret){\r
317                                 $errMsg = '自動ログインエラー(要因=自動ログイン情報作成失敗)';\r
318                                 $msgDetail = 'ログインキー=' . $newLoginKey . ',ユーザID=' . $userId . ',クライアントID=' . $clientId;\r
319                                 $this->gOpeLog->writeError(__METHOD__, $errMsg, 1100, $msgDetail);\r
320                         }\r
321                 } else {\r
322                         // クッキー削除は必ず行うため引数エラーチェックはしない\r
323                         // 自動ログイン情報を削除\r
324                         $loginKey = $this->db->getAutoLoginKey($userId, $clientId);\r
325                         $ret = $this->_removeAutoLogin($loginKey);\r
326                 }\r
327                 return $ret;\r
328         }\r
329         /**\r
330          * 自動ログイン情報作成\r
331          *\r
332          * @param string $loginKey      ログインキー\r
333          * @param int    $userId        ユーザID\r
334          * @param string $clientId      クライアントID\r
335          * @return bool                         true=成功、false=失敗\r
336          */\r
337         function _createAutoLogin($loginKey, $userId, $clientId)\r
338         {\r
339                 global $gRequestManager;\r
340                 \r
341                 // クッキーを作成\r
342                 //$gRequestManager->setCookieValue(M3_COOKIE_AUTO_LOGIN, '', -1);               // 一旦削除\r
343                 $gRequestManager->setCookieValue(M3_COOKIE_AUTO_LOGIN, $loginKey, self::AUTO_LOGIN_EXPIRE_DAYS);\r
344                 \r
345                 // 自動ログイン情報を更新\r
346                 $accessPath = $this->gEnv->getAccessPath();\r
347                 $expireDt = date("Y/m/d H:i:s", strtotime(self::AUTO_LOGIN_EXPIRE_DAYS . ' day'));\r
348                 $ret = $this->db->updateAutoLogin($userId, $loginKey, $clientId, $accessPath, $expireDt);\r
349                 return $ret;\r
350         }\r
351         /**\r
352          * 自動ログイン情報削除\r
353          *\r
354          * @param string $loginKey      ログインキー\r
355          * @return bool                         true=成功、false=失敗\r
356          */\r
357         function _removeAutoLogin($loginKey)\r
358         {\r
359                 global $gRequestManager;\r
360                 \r
361                 // クッキーを削除\r
362                 $gRequestManager->setCookieValue(M3_COOKIE_AUTO_LOGIN, '', -1);\r
363                 \r
364                 // 自動ログイン情報削除\r
365                 $ret = $this->db->delAutoLogin($loginKey);\r
366                 return $ret;\r
367         }\r
368         /**\r
369          * 期間から公開可能かチェック\r
370          *\r
371          * @param timestamp     $startDt                公開開始日時\r
372          * @param timestamp     $endDt                  公開終了日時\r
373          * @param timestamp     $now                    基準日時\r
374          * @return bool                                         true=公開可能、false=公開不可\r
375          */\r
376         function _isActive($startDt, $endDt, $now)\r
377         {\r
378                 $isActive = false;              // 公開状態\r
379 \r
380                 if ($startDt == $this->gEnv->getInitValueOfTimestamp() && $endDt == $this->gEnv->getInitValueOfTimestamp()){\r
381                         $isActive = true;               // 公開状態\r
382                 } else if ($startDt == $this->gEnv->getInitValueOfTimestamp()){\r
383                         if (strtotime($now) < strtotime($endDt)) $isActive = true;              // 公開状態\r
384                 } else if ($endDt == $this->gEnv->getInitValueOfTimestamp()){\r
385                         if (strtotime($now) >= strtotime($startDt)) $isActive = true;           // 公開状態\r
386                 } else {\r
387                         if (strtotime($startDt) <= strtotime($now) && strtotime($now) < strtotime($endDt)) $isActive = true;            // 公開状態\r
388                 }\r
389                 return $isActive;\r
390         }\r
391         /**\r
392          * ユーザログアウト処理\r
393          *\r
394          * @param bool $delSession              セッションを削除するかどうか\r
395          */\r
396         function userLogout($delSession = false)\r
397         {\r
398                 // ユーザ情報取得\r
399                 $userInfo = $this->gEnv->getCurrentUserInfo();\r
400                 \r
401                 // ##### 自動ログイン情報を削除 #####\r
402                 $this->userAutoLogin($userInfo->userId, false/*自動ログイン情報削除*/);\r
403                 \r
404                 // ログアウトログを残す\r
405                 if (!is_null($userInfo)){\r
406                         $this->gOpeLog->writeUserInfo(__METHOD__, 'ユーザがログアウトしました。アカウント: ' . $userInfo->account, 2301,\r
407                                                                                         'account=' . $userInfo->account . ', userid=' . $userInfo->userId, 'account=' . $userInfo->account/*検索補助データ*/);\r
408                 }\r
409                 \r
410                 // ログアウトしたとき、管理者のセッション値は削除。一般ユーザの場合はログアウトしても残しておくセッション値があるので(テンプレート等)ユーザ情報のみ削除。\r
411                 // セッション終了\r
412                 if ($delSession){\r
413 //                      session_start();\r
414                         session_destroy();\r
415                 }\r
416                         \r
417                 // ユーザ情報を削除\r
418                 $this->gInstance->setUserInfo(null);\r
419         }\r
420         /**\r
421          * アクセスログの記録\r
422          *\r
423          * アクセスログを記録する\r
424          *\r
425          * @return なし\r
426          */\r
427         function accessLog()\r
428         {\r
429                 global $gRequestManager;\r
430                 global $gEnvManager;\r
431                 global $gAccessManager;\r
432                 global $gInstanceManager;\r
433                 \r
434                 // ユーザ情報が存在しているときは、ユーザIDを登録する\r
435                 $userId = 0;\r
436                 $userInfo = $gEnvManager->getCurrentUserInfo();\r
437                 if (!is_null($userInfo)){               // ユーザ情報がある場合\r
438                         $userId = $userInfo->userId;\r
439                 }\r
440                 $cookieVal      = isset($this->_clientId) ? $this->_clientId : '';                      // アクセス管理用クッキー\r
441                 $session        = session_id();                         // セッションID\r
442                 //$ip                   = $gRequestManager->trimServerValueOf('REMOTE_ADDR');           // クライアントIP\r
443                 $ip                     = $this->_getClientIp($gRequestManager);                // クライアントIP\r
444                 $method         = $gRequestManager->trimServerValueOf('REQUEST_METHOD');        // アクセスメソッド\r
445                 $uri            = $gRequestManager->trimServerValueOf('REQUEST_URI');\r
446                 $referer        = $gRequestManager->trimServerValueOf('HTTP_REFERER');\r
447                 $agent          = $gRequestManager->trimServerValueOf('HTTP_USER_AGENT');               // クライアントアプリケーション\r
448                 $language       = $gRequestManager->trimServerValueOf('HTTP_ACCEPT_LANGUAGE');  // クライアント認識可能言語\r
449                 \r
450                 $request = '';\r
451                 foreach ($_REQUEST as $strKey => $strValue ) {\r
452                         $request .= sprintf("%s=%s" . M3_TB, $strKey, $strValue);               // タブ区切り\r
453                 }\r
454                 $request = rtrim($request, M3_TB);              // 最後のタブを消去\r
455                 $request = substr($request, 0, self::LOG_REQUEST_PARAM_MAX_LENGTH);     // 格納長を制限\r
456                 \r
457                 // アクセスパスを取得\r
458                 $path = $gEnvManager->getAccessPath();\r
459                 \r
460                 // アクセスの種別を取得\r
461                 $isCookie = !empty($_COOKIE);                   // クッキーがあるかどうか\r
462                 $isCrawler = false;                             // クローラかどうか\r
463                 \r
464                 // アクセスログのシリアルNoを保存\r
465                 $this->_accessLogSerialNo = $this->db->accessLog($userId, $cookieVal, $session, $ip, $method, $uri, $referer, $request, $agent, $language, $path, $isCookie, $isCrawler);\r
466                 \r
467                 // 即時アクセス解析\r
468                 if (M3_SYSTEM_REALTIME_ANALYTICS) $gInstanceManager->getAnalyzeManager()->realtimeAnalytics($this->_accessLogSerialNo, $cookieVal);\r
469         }\r
470         /**\r
471          * アクセス元のIPを取得\r
472          *\r
473          * @param RequestManager $request               HTTPリクエスト処理クラス\r
474          * @return string                                               IPアドレス\r
475          */\r
476         function _getClientIp($request)\r
477         {\r
478                 $remoteIp               = $request->trimServerValueOf('REMOTE_ADDR');\r
479                 $forwardedStr   = $request->trimServerValueOf('HTTP_X_FORWARDED_FOR');\r
480                 if (empty($forwardedStr)) return $remoteIp;\r
481                 \r
482                 $candidateIpArray = array_reverse(explode(',', str_replace(' ', '', $forwardedStr) . ',' . $remoteIp));\r
483                 foreach ($candidateIpArray as $ip){\r
484                         if (!empty($ip) && !preg_match("/^(172\.(1[6-9]|2[0-9]|30|31)|192\.168|10|127)\./", $ip)) return $ip;\r
485                 }\r
486                 return $remoteIp;\r
487         }\r
488         /**\r
489          * アクセスログユーザの記録\r
490          *\r
491          * アクセスログユーザを記録する\r
492          *\r
493          * @return なし\r
494          */\r
495         function accessLogUser()\r
496         {\r
497                 global $gEnvManager;\r
498                                 \r
499                 $userId = 0;\r
500                 $userInfo = $gEnvManager->getCurrentUserInfo();\r
501                 if (!is_null($userInfo)){               // ユーザ情報がある場合\r
502                         $userId = $userInfo->userId;\r
503                 }\r
504                 // ユーザ情報が存在しているときは、ユーザIDを登録する\r
505                 if ($userId != 0) $this->db->updateAccessLogUser($this->_accessLogSerialNo, $userId);\r
506         }\r
507         /**\r
508          * クッキーに保存するクライアントIDを生成\r
509          */\r
510         function createClientId()\r
511         {\r
512                 global $gRequestManager;\r
513                         \r
514                 // アクセスログの最大シリアルNoを取得\r
515                 $max = $this->db->getMaxSerialOfAccessLog();\r
516                 $this->_clientId = md5(time() . $gRequestManager->trimServerValueOf('REMOTE_ADDR') . ($max + 1));\r
517                 return $this->_clientId;                                // クライアントID(クッキー用)\r
518         }\r
519         /**\r
520          * クッキーから取得したクライアントIDを設定\r
521          *\r
522          * @param string $clientId              クライアントID\r
523          */\r
524         function setClientId($clientId)\r
525         {\r
526                 $this->_clientId = $clientId;                           // クライアントID(クッキー用)\r
527         }\r
528         /**\r
529          * クッキーから取得したクライアントIDを取得\r
530          *\r
531          * @return string               クライアントID\r
532          */\r
533         function getClientId()\r
534         {\r
535                 return $this->_clientId;                                // クライアントID(クッキー用)\r
536         }\r
537         /**\r
538          * 管理者用一時キーを作成\r
539          */\r
540         function createAdminKey()\r
541         {\r
542                 global $gRequestManager;\r
543                         \r
544                 return md5($gRequestManager->trimServerValueOf('REMOTE_ADDR') . time());\r
545         }\r
546         /**\r
547          * 変更前のセッションIDを設定\r
548          *\r
549          * @param string $sessionId             セッションID\r
550          */\r
551         function setOldSessionId($sessionId)\r
552         {\r
553                 $this->_oldSessionId = $sessionId;\r
554         }\r
555         \r
556         /**\r
557          * アクセスログのシリアルNoを取得\r
558          *\r
559          * @return int          シリアルNo\r
560          */\r
561         function getAccessLogSerialNo()\r
562         {\r
563                 return $this->_accessLogSerialNo;\r
564         }\r
565         /**\r
566          * システム管理者の認証が完了しているかどうか判断(フレームワーク以外のアクセス制御用)\r
567          *\r
568          * @return bool         true=完了、false=未完了\r
569          */\r
570         function loginedByAdmin()\r
571         {\r
572                 global $gRequestManager;\r
573                 global $gSystemManager;\r
574                 \r
575                 // セッション変数を取得可能にする\r
576                 session_cache_limiter('none');          // IE対策(暫定対応20070703)\r
577                 session_start();\r
578                 \r
579                 // セッションを再生成する(セキュリティ対策)\r
580                 if ($gSystemManager->regenerateSessionId()){\r
581                         $this->setOldSessionId(session_id());           // 古いセッションIDを保存\r
582                         session_regenerate_id(true);\r
583                 }\r
584 \r
585                 // セッションからユーザ情報を取得\r
586                 // セッションが残っていない場合がある(IEのみ)→アクセスできない(原因不明)\r
587                 $userInfo = $gRequestManager->getSessionValueWithSerialize(M3_SESSION_USER_INFO);\r
588                 if (is_null($userInfo)) return false;           // ログインしていない場合\r
589 \r
590                 if ($userInfo->isSystemAdmin()){        // システム管理者の場合\r
591                         return true;\r
592                 } else {\r
593                         return false;\r
594                 }\r
595         }\r
596         /**\r
597          * ユーザの認証が完了しているかどうか判断(フレームワーク以外のアクセス制御用)\r
598          *\r
599          * @return bool         true=完了、false=未完了\r
600          */\r
601         function loginedByUser()\r
602         {\r
603                 global $gRequestManager;\r
604                 global $gSystemManager;\r
605                 global $gInstanceManager;\r
606                 \r
607                 // セッション変数を取得可能にする\r
608                 session_cache_limiter('none');          // IE対策(暫定対応20070703)\r
609                 session_start();\r
610                 \r
611                 // セッションを再生成する(セキュリティ対策)\r
612                 if ($gSystemManager->regenerateSessionId()){\r
613                         $this->setOldSessionId(session_id());           // 古いセッションIDを保存\r
614                         session_regenerate_id(true);\r
615                 }\r
616 \r
617                 // セッションからユーザ情報を取得\r
618                 // セッションが残っていない場合がある(IEのみ)→アクセスできない(原因不明)\r
619                 $userInfo = $gRequestManager->getSessionValueWithSerialize(M3_SESSION_USER_INFO);\r
620                 if (is_null($userInfo)) return false;           // ログインしていない場合\r
621                 \r
622                 // ユーザ情報を保存\r
623                 $gInstanceManager->setUserInfo($userInfo);\r
624                 \r
625                 return true;\r
626                 /*if ($userInfo->userType >= UserInfo::USER_TYPE_MANAGER){      // システム運用可能ユーザのとき\r
627                         return true;\r
628                 } else {\r
629                         return false;\r
630                 }*/\r
631         }\r
632         /**\r
633          * 管理者認証用一時キーが存在するかどうか\r
634          *\r
635          * @return bool                 true=完了、false=未完了\r
636          */\r
637         function isValidAdminKey()\r
638         {\r
639                 global $gRequestManager;\r
640                 static $isValidAdminKey;\r
641                 \r
642                 if (!isset($isValidAdminKey)){\r
643                         // 管理者一時キーを取得\r
644                         //$adminKey = $request->trimValueOf(M3_REQUEST_PARAM_ADMIN_KEY);\r
645                         $adminKey = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_ADMIN_KEY);\r
646                         if (empty($adminKey)){\r
647                                 $isValidAdminKey = false;\r
648                         } else {\r
649                                 //$ret = $this->db->isValidAdminKey($adminKey, $request->trimServerValueOf('REMOTE_ADDR'));\r
650                                 $isValidAdminKey = $this->db->isValidAdminKey($adminKey, $gRequestManager->trimServerValueOf('REMOTE_ADDR'));\r
651                         }\r
652                 }\r
653                 return $isValidAdminKey;\r
654         }\r
655         /**\r
656          * URL用のパラメータとして使用するセッションIDを取得\r
657          *\r
658          * @return string                       セッションIDパラメータ文字列\r
659          */     \r
660         function getSessionIdUrlParam()\r
661         {\r
662                 return session_name() . '=' . session_id();\r
663         }\r
664         /**\r
665          * 仮パスワードを発行して送信\r
666          *\r
667          * @param RequestManager $request               HTTPリクエスト処理クラス\r
668          * @return bool                                                 true=送信完了、false=送信失敗\r
669          */     \r
670         function sendPassword($request)\r
671         {\r
672                 global $gEnvManager;\r
673                 \r
674                 $account = $request->trimValueOf('account');\r
675                 $inputEmail = $request->trimValueOf('email');           // 送信先Eメール\r
676                 \r
677                 $isSend = false;\r
678                 $errMessage = '';\r
679                 $errMessageDetail = '';\r
680                 if ($this->db->getLoginUserRecord($account, $row, true/*有効なユーザのみ*/)){           // アカウントからログインIDを取得\r
681                         $siteEmail = $gEnvManager->getSiteEmail();\r
682                         $email = $row['lu_email'];\r
683                         \r
684                         // 送信先Eメールアドレスをチェック\r
685                         if (!empty($inputEmail) && $inputEmail == $email){\r
686                                 // 送信先が設定されているかチェック\r
687                                 if (!empty($email) && !empty($siteEmail)){\r
688                                         $now = date("Y/m/d H:i:s");     // 現在日時\r
689                                 \r
690                                         // パスワード作成\r
691                                         $password = makePassword(self::PASSWORD_LENGTH);\r
692                                 \r
693                                         // 仮パスワードと発行日時を更新\r
694                                         $fieldArray = array();\r
695                                         $fieldArray['lu_tmp_password'] = md5($password);                                // 仮パスワード\r
696                                         $fieldArray['lu_tmp_pwd_dt'] = $now;                    // 仮パスワード変更日時\r
697                                         $ret = $this->db->updateLoginUserByField($row['lu_id'], $fieldArray, $newSerial);\r
698                                         if ($ret){\r
699                                                 $fromAddress    = $siteEmail;           // 送信元アドレス\r
700                                                 $toAddress              = $email;                       // 送信先アドレス\r
701                                                 $mailParam = array();\r
702                                                 $mailParam['PASSWORD'] = $password;\r
703                                                 $ret = $this->gInstance->getMailManager()->sendFormMail(1/*自動送信*/, $this->gEnv->getCurrentWidgetId(), $toAddress, $fromAddress, '', '', self::SEND_PASSWORD_FORM, $mailParam);// 自動送信\r
704                                                 $isSend = true;         // 送信完了\r
705                                         }\r
706                                 } else {\r
707                                         $errMessageDetail = 'サイトEメールまたはアカウントの送信先Eメールが設定されていません。';\r
708                                 }\r
709                         } else {\r
710                                 $errMessage = '仮パスワード送信への不正なアクセスを検出しました。アカウント: ' . $account . ', Eメール: ' . $inputEmail;\r
711                         }\r
712                 } else {\r
713                         $errMessageDetail = '登録されていないアカウント、または、アカウントが承認済み、ログイン可、有効期間内になっていません。';\r
714                 }\r
715                 if ($isSend){\r
716                         $this->gOpeLog->writeUserInfo(__METHOD__, '仮パスワードを送信しました。アカウント: ' . $account, 2100);\r
717                 } else {\r
718                         if (empty($errMessage)) $errMessage = '仮パスワード送信に失敗しました。アカウント: ' . $account;\r
719                         $this->gOpeLog->writeUserError(__METHOD__, $errMessage, 2200, $errMessageDetail);\r
720                 }\r
721         }\r
722 }\r
723 ?>\r