Xampp+Pukiwiki1.5.1導入ガイド覚書

はじめまして。ReGadexと申します。
超へっぽこエンジニアです。
今回は、社内用PCへ情報共有ツールを超簡単に構築したろ！
と思い立ち、行った忘却禄みたいなものです。
ふんわりしてて分かり難いぞこの野郎！って思われたらごめんなさい。
では手順を振り返ってみます。


#手順1.xamppのインストール
xampp公式サイト(https://www.apachefriends.org/jp/index.html)
から落としてきます。

・xamppインストール後、Apache と　MySQLが動いていることを確認。

※ここでMySQLが動かない場合、使用できるポートがほかのソフト（Skype等）に
使われている可能性が高い。

#手順2.phpMyAdmin（DB）のログイン設定
動作確認後、windowsコマンドプロセッサで以下のコマンドを実行し、
phpMyAdminのrootユーザーにパスワードを設定します。

【cmdコマンド】
①cd C:\xampp\mysql\bin\　
②mysql -u root
③use mysql;
④set password for root@localhost=PASSWORD('DBの接続パスワード');

ここでDBのテーブルを作成してもよいですが、まずはPukiwikiを導入しましょう。
 https://pukiwiki.osdn.jp/
からDLしたファイルを解凍、Pukiwikiへリネームします。
そのフォルダを下記デイレクトリ下へ配置します。
C:\xampp\htdocs

#手順3.PukiWikiのログインユーザー設定（ログインイメージ確認＆試し）
ログインユーザー設定を行う為、
pukiwikiフォルダ下にある設定ファイルpukiwiki.ini.phpを編集します。

※別にDBからデータを読み込むとかしなくていいよって方はここで終了です。
詳しい設定方法はPukiWiki本家さんを参照してください。

####編集する項目
・＄auth_users　　　　・・ユーザー名とパスワードの組を設定します。
・＄read_auth = 0;　・・ログインできたユーザーは基本的に閲覧許可するので、無効。
・＄edit_auth = 1;　・・編集設定。有効（:1）にします。
・＄edit_auth_pages・・編集可能なユーザーのみ設定します。

###設定例
####   ユーザーID：Administratorだけを編集可能にしたい場合
```
$edit_auth_pages = array(
	'##' => 'Administrator',
);
```

###【注意】
・＄adminpass　・・凍結用パスワードが指定できます。デフォルトでは設定されていないので注意。任意の値を指定しましょう。
→デフォルトではFrontPageが凍結されてて編集できないやん！ってなったので一応記載。

#手順4.DBにログインユーザー用のテーブルを作成、データ登録

任意の名前のテーブルで作成してください。
ちなみに私の場合は、以下のような構造(SQL)で作成しました。
上から順にログインID、パス、名前、権限、備考みたいな感じです。
この中で必須なのはログインID、パス、権限だけなのであとは自分でカスタマイズ！

```sql
CREATE TABLE `user_mas` (
  `USER_ID` varchar(20) CHARACTER SET utf8 NOT NULL,
  `USER_PASS` varchar(20) CHARACTER SET utf8 NOT NULL,
  `USER_NAME` varchar(25) CHARACTER SET utf8,
  `USER_AUTH` char(1) CHARACTER SET utf8 NOT NULL,
  `REMARKS` varchar(100) CHARACTER SET utf8
) ENGINE=InnoDB DEFAULT CHARSET=latin1
```

適当にユーザー用のデータを追加します。
私の場合は動作確認用に管理者ユーザーと一般ユーザー（閲覧のみ）を作成しました。
一応、権限の定義は編集権限が'A',閲覧のみを'R'としています。


```sql
-- 管理者ユーザー追加SQL
INSERT 
INTO pukiwikidb.user_mas( 
  `USER_ID`
  , `USER_PASS`
  , `USER_NAME`
  , `USER_AUTH`
  , `REMARKS`
) 
VALUES ( 
   'Administrator'
  ,'P@ssw0rd'
  ,'管理者ユーザー'
  ,'A'
  ,''')
```

```sql
-- 一般ユーザー（閲覧のみ）追加SQL
INSERT 
INTO pukiwikidb.user_mas( 
  `USER_ID`
  , `USER_PASS`
  , `USER_NAME`
  , `USER_AUTH`
  , `REMARKS`
) 
VALUES ( 
   'user01'
  ,'user01'
  ,'一般ユーザー(参照のみ)'
  ,'R'
  ,''') 
```

#手順5.DBに登録したユーザーで認証できるようにpukiwiki.ini.phpを編集する。

①まず、手順3.で＄auth_users,＄edit_auth_pagesはコメントアウトor削除してください。
②以下のコードを＄auth_usersを定義していた場所付近にペーストして下さい。

```php5
/////////////////////////////////////////////////
// ユーザー定義

//DB接続(PDO)
$dsn ='mysql:host=localhost;dbname=DB名;charset=utf8mb4';
$username='root';
$password='DBの接続パスワード';


try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $auth_users = array();
    $edit_auth_pages = array();
    // ユーザマスタからユーザー情報を取り出す。
    $sql = 'SELECT * FROM user_mas';
    // SQLステートメントを実行し、結果を変数に格納
    $stmt = $pdo->query($sql);
	while($result = $stmt->fetch(PDO::FETCH_ASSOC)){
		// ログインユーザー情報取得
		$auth_users += array($result["USER_ID"]=>$result["USER_PASS"]);
		}
	}
} catch (PDOException $e) {
	// 500 サーバ側の内部エラーが起きたらエラーメッセージを出して終了。
    header('Content-Type: text/plain; charset=UTF-8', true, 500);
    exit($e->getMessage()); 
}
```

#手順6.DBに登録したユーザーで編集権限が設定できるようにpukiwiki.ini.phpとauth.phpを編集する。

1.フォーム認証を行っているauth.phpを編集します。(場所: pukiwiki\lib)
get_authinfo関数を追加、ファイル内のform_auth関数を下記の様に置き換えます。

```php5
/**
 * 指定されたユーザーidに対応する権限を取得する
 *
 * @param String userid
 * @return 権限(R/A)
 */
function get_authinfo($userid){

	//DB接続(PDO)
	$dsn ='mysql:host=localhost;dbname=pukiwikidb;charset=utf8mb4';
	$username='root';
	$password='P@ssw0rd';

	try {
	    $pdo = new PDO($dsn, $username, $password);
	    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
	    $sql = 'SELECT USER_AUTH FROM user_mas WHERE USER_ID = :USER_ID';
	    $stmt = $pdo->prepare($sql);
	    $stmt->bindParam(':USER_ID', $userid, PDO::PARAM_STR);
	    $stmt->execute();
	    $authinfo = $stmt->fetchAll(PDO::FETCH_ASSOC);
	    return $authinfo[0]['USER_AUTH'];

	} catch (PDOException $e) {
	    // 500 サーバ側の内部エラーが起きたらエラーメッセージを出して終了。
	    header('Content-Type: text/plain; charset=UTF-8', true, 500);
	    exit($e->getMessage()); 
	}
}

/**
 * ユーザーidとパスワードでログインする
 *
 * @param String userid
 * @param String password
 * @return true なら　サインインOK
 */
function form_auth($userid, $password)
{
	global $auth_users,$edit_auth_pages;

	// ユーザー(auth_users)はpukiwiki.ini.phpで定義します。
	if (in_array($userid, array_keys($auth_users))) {
		session_start();
		session_regenerate_id(true); // require: PHP5.1+
		$_SESSION['authenticated_user'] = $userid;
		$_SESSION['authenticated_user_fullname'] = $userid;
		
		// 入力したユーザーIDに対応した権限が編集可能ならユーザーIDを編集可能として設定。
		if(get_authinfo($userid) === 'A'){
			setcookie("user_id",$userid,time()+180000);
		}else{
			// クッキーを削除(有効期限を変更して無効化)
			setcookie("user_id",$userid,time()-180000);
		}

		return true;
	}
	
	return false;
}

```

2.次にpukiwiki.ini.php側の編集設定用の変数$edit_auth =1;を設定されていることを確認した後に下記のコードをペーストします。

```php5
// クッキーに保存されたユーザーIDを確認する。（編集権限有の場合、認証時にクッキー保存）
 if (isset($_COOKIE['user_id'])){
	$edit_auth_pages = array(
		'##' => $_COOKIE['user_id'],
	);
}else{
	$edit_auth_pages = array(
		'##' => 'dummy_user',
	);
}
```

3.ログインしたユーザーで編集できるか確認してみましょう。
編集権限(A)の場合のみ編集出来る様になっているはずです。


#最後に
※なお、今回、パスワードは平文で登録しているので、MD5で暗号化したハッシュ値をDBへ登録して入力した値を変換して認証する等した方が良いです。他にも、外部認証方式などPukiWiki1.5.1ではサポートされているようなので、試してみてはいかがでしょうか。
他にもっと書き方もあると思いますが、その際は教えていただけるとありがたいです。

(2018/05/05追記：編集権限が上手く動作していなかった為、記事を手順5を修正、手順6を追記しました)

【参考URL】
MySQLのユーザ管理
https://qiita.com/shell/items/917cf7c67a54d0d128dc

PukiWiki/1.4/ちょっと便利に/任意のページごとの閲覧・編集制限
https://pukiwiki.osdn.jp/dev/?PukiWiki/1.4/%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E4%BE%BF%E5%88%A9%E3%81%AB/%E4%BB%BB%E6%84%8F%E3%81%AE%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%94%E3%81%A8%E3%81%AE%E9%96%B2%E8%A6%A7%E3%83%BB%E7%B7%A8%E9%9B%86%E5%88%B6%E9%99%90

PukiWikiの公式サイト
https://pukiwiki.osdn.jp/