<?php
/**
 *  User/Update.php
 *
 *  @author     {$author}
 *  @package    Secioss
 *  @version    $Id: skel.action.php,v 1.10 2006/11/06 14:31:24 cocoitiban Exp $
 */

/**
 *  user_updateフォームの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Secioss
 */
class Secioss_Form_UserUpdate extends Secioss_ActionForm
{
    /** @var    bool    バリデータにプラグインを使うフラグ */
    var $use_validator_plugin = true;

    /**
     *  @access private
     *  @var    array   フォーム値定義
     */
    var $form = array(
        'id' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
            'name'          => 'ユーザID',
        ),
        'loginid' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => 'ログインID'
        ),
        'snkanji' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '姓',
            'required'        => true
        ),
        'gnkanji' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '名'
        ),
        'snkana' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '姓',
            'min'           => null,
            'max'           => null,
            'regexp'        => null
        ),
        'gnkana' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '名',
            'min'           => null,
            'max'           => null,
            'regexp'        => null
        ),
        'empnum' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
            'name'          => '社員番号'
        ),
        'mail' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => 'メールアドレス',
            'min'           => null,
            'max'           => null,
            'regexp'        => '/^[a-zA-Z0-9]+[a-zA-Z0-9\._-]*@[a-zA-Z0-9]+[a-zA-Z0-9\._-]+$/',
        ),
        'password' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_PASSWORD,
            'name'          => 'パスワード',
            'min'           => 4,
            'max'           => 20
        ),
        'status' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_SELECT,
            'name'          => 'ユーザ状態',
            'option'        => array('active' => '有効', 'inactive' => '無効'),
        ),
        'unlock' => array(
            'type'          => array(VAR_TYPE_BOOLEAN),
            'form_type'     => FORM_TYPE_CHECKBOX,
            'name'          => 'ロックアウト解除',
            'option'        => array(true => 'ロックアウト解除')
        ),
        'lockout' => array(
            'type'          => VAR_TYPE_BOOLEAN,
            'form_type'     => FORM_TYPE_HIDDEN
        ),
        'pwloduration' => array(
            'type'          => VAR_TYPE_INT,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => 'ロックアウトの解除時間（分）',
            'min'           => 0,
            'regexp'        => '/^[0-9]+$/'
        ),
        'certificate' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_FILE,
            'name'          => '証明書'
        ),
        'sync' => array(
            'type'          => array(VAR_TYPE_STRING),
            'form_type'     => FORM_TYPE_CHECKBOX,
            'name'          => '更新対象システム',
            'option'        => 'sync_select'
        ),
        'dn' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
            'required'       => true
        ),
        'operation' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN
        )
    );
}

/**
 *  user_updateアクションの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Secioss
 */
class Secioss_Action_UserUpdate extends Secioss_ActionClass
{
    /**
     *  user_updateアクションの前処理
     *
     *  @access public
     *  @return string      遷移名(正常終了ならnull, 処理終了ならfalse)
     */
    function prepare()
    {
        if ($this->af->get('operation') == 'update' && $this->af->validate() > 0) {
            $this->ae->add(null, $this->getInvalidValMsg($this->getErrorFormName()));

            return 'user_update';
        }

        return null;
    }

    /**
     *  user_updateアクションの実装
     *
     *  @access public
     *  @return string  遷移名
     */
    function perform()
    {
        $auth =& $this->backend->getManager('Auth');
        $logger =& $this->backend->getLogger();
        $login_user = $this->session->get('user');
        $conf = $this->config->get('secioss');

        // input value
        $id = $this->af->get('id');
        $loginid = $this->af->get('loginid');
        $snkanji = $this->af->get('snkanji');
        $gnkanji = $this->af->get('gnkanji');
        $snkana = $this->af->get('snkana');
        $gnkana = $this->af->get('gnkana');
        $empnum = $this->af->get('empnum');
        $mail = $this->af->get('mail');
        $password = $this->af->get('password');
        $sync = $this->af->get('sync');
        $status = $this->af->get('status');
        $unlock = $this->af->get('unlock');
        $lockout = $this->af->get('lockout');
        $pwloduration = $this->af->get('pwloduration') * 60;
        $dn = $this->af->get('dn');

        $tenant = $this->session->get('tenant');
        $role = $this->session->get('role');
        $system = $this->session->get('system');
        $ldaptype = $this->session->get('ldaptype');

        if ($this->af->get('operation') == 'update') {
            // update user data
            $prop = array(
                'id' => $dn,
                'uid' => $id,
                'employeenumber' => $empnum,
                'mail' => $mail
            );

            if (!$ldaptype || $ldaptype != 'AD') {
                $prop['cn'] = $snkanji." ".$gnkanji;
                $prop['sn'] = $snkanji;
            }
            if ($gnkanji) {
                $prop['givenname'] = $gnkanji;
            }
            if ($snkana) {
                $prop['cn;lang-ja;phonetic'] = "$snkana $gnkana";
                $prop['sn;lang-ja;phonetic'] = $snkana;
            }
            if ($gnkana) {
                $prop['givenname;lang-ja;phonetic'] = $gnkana;
            }
            if (isset($conf['user']['loginidattr'])) {
                $prop[$conf['user']['loginidattr']] = $loginid;
            }
            if (isset($conf['user']['statusattr'])) {
                $prop[$conf['user']['statusattr']] = $status;
            }
            if (isset($conf['user']['pwlockoutattr']) && $lockout) {
                if ($unlock) {
                    $prop[$conf['user']['pwlockoutattr']] = 'FALSE';
                    $this->af->set('lockout', false);
                }
            }
            if (isset($conf['user']['pwlodurationattr'])) {
                if ($pwloduration) {
                    $prop[$conf['user']['pwlodurationattr']] = $pwloduration;
                } else {
                    $prop[$conf['user']['pwlodurationattr']] = -1;
                }
            }
            if (isset($_FILES['certificate']['name']) && $_FILES['certificate']['name']) {
                if ($_FILES['certificate']['size'] == 0) {
                     $this->ae->add(null, $this->getInvalidValMsg('certificate'));

                     return 'user_update';
                }

                $certificate = '';
                $begin_cert = false;
                $file = fopen($_FILES['certificate']['tmp_name'], 'r');
                while (!feof($file)) {
                    $line = chop(fgets($file));
                    if ($line == '-----BEGIN CERTIFICATE-----') {
                        $begin_cert = true;
                    } else if ($line == '-----END CERTIFICATE-----') {
                        break;
                    } else if ($begin_cert) {
                        $certificate .= $line;
                    }
                }
                fclose($file);

                $ldapconf = $this->config->get('ldap');
                if ($ldapconf['type'] == 'LISM') {
                    $prop['seciosscertificate'] = $certificate;
                } else {
                    $prop['usercertificate;binary'] = base64_decode($certificate);
                }
            }
            if (isset($conf['sync'])) {
                $prop['seciossallowedservice'] = $sync;
            }
            if ($tenant) {
                $prop['area'] = $tenant;
            }
            if ($system) {
                $prop['system'] = $system;
            }
            if (isset($conf['user']['userdefinedattr'])) {
                foreach ($conf['user']['userdefinedattr'] as $key => $name) {
                    if (isset($_POST['attr_'.$key])) {
                        $prop[$key] = $_POST['attr_'.$key];
                    }
                }
            }
            if ($password) {
                $prop['userpassword'] = Secioss_User::getLdapPasswd($password);
            }

            $user = $auth->updateObject('user', null, null, $prop);
            if (Ethna::isError($user)) {
                $logger->log(LOG_ERR, "$login_user failed to update the user($dn): ".$user->getMessage());
                $this->ae->add(null, O_UPDATE_ERR_MSG);

                return 'user_update';
            }

            $this->af->setApp('message', O_UPDATE_SUCCESS_MSG);
            $logger->log(LOG_INFO, "$login_user succeeded to update the user($dn)");
        } else {
            $r = $auth->getObjectList('user', array('id' => $dn));
            if (Ethna::isError($r)) {
                $logger->log(LOG_ERR, "$login_user failed to get the user($dn): ".$r->getMessage());
                $this->ae->add(null, S_INTERNAL_ERR_MSG);

                return 'user_update';
            } else if ($r[0] != 1) {
                $logger->log(LOG_ERR, "$login_user gets no user($dn)");
                $this->ae->add(null, O_NO_SUCH_OBJECT_MSG);

                return 'user_update';
            }

            $user = $r[1][0];

            $this->af->set('id', $user->get('uid'));
            $sn = $user->get('sn');
            $this->af->set('snkanji', $sn);
            $cn = $user->get('cn');
            $sn = preg_quote($sn);
            $this->af->set('gnkanji', preg_match("/^$sn +(.*)$/", $cn, $matches) ? $matches[1] : '');
            $snkana = $user->get('sn;lang-ja;phonetic');
            $this->af->set('snkana', $snkana);
            $cnkana = $user->get('cn;lang-ja;phonetic');
            $snkana = preg_quote($snkana);
            $this->af->set('gnkana', preg_match("/^$snkana +(.*)$/", $cnkana, $matches) ? $matches[1] : '');
            $this->af->set('empnum', $user->get('employeenumber'));
            $this->af->set('mail', $user->get('mail'));
            if (isset($conf['user']['loginattr'])) {
                $this->af->set('loginid', $conf['user']['loginidattr']);
            }
            if (isset($conf['user']['statusattr'])) {
                $this->af->set('status', $user->get($conf['user']['statusattr']));
            }
            if (isset($conf['user']['pwlockoutattr'])) {
                if ($user->get($conf['user']['pwlockoutattr']) == 'TRUE') {
                   $this->af->set('lockout', true);
                }
            }
            if (isset($conf['user']['pwlodurationattr'])) {
                $pwloduration = $user->get($conf['user']['pwlodurationattr']);
                $pwloduration = $pwloduration < 0 ? 0 : $pwloduration / 60;
                $this->af->set('pwloduration', $pwloduration);
            }
            if (isset($conf['sync'])) {
                $this->af->set('sync', to_array($user->get('seciossallowedservice')));
            }
            if (isset($conf['unit'])) {
                $this->session->set('unit', $auth->getAttrName('unit', preg_replace('/^[^,]+,/', '', $dn)));
            }
            if (isset($conf['area']) && $role == 'system_admin') {
                $this->session->set('tenant', $user->get('area'));
            }
            if (isset($conf['system'])) {
                $this->session->set('system', $user->get('system'));
            }
        }

        if (isset($conf['user']['userdefinedattr'])) {
            foreach ($conf['user']['userdefinedattr'] as $key => $name) {
                $this->af->setApp($key, $user->get($key));
            }
        }

        $this->session->set('user_name', $user->get('cn'));

        return 'user_update';
    }
}
?>
