2

Moodle の外部データベース プラグインを使用していますが、非常に厄介な問題が発生しています。次に例を示します。

ユーザー名: johndoe@gmail.com は自分のパスワードでログインし、両方とも外部 DB に保存されます。Moodle はそのデータ (ユーザ名、パスワード) を取得し、そのユーザの外部 DB ID とともにローカル (mysql) に保存します。外部 DB はすべてが発生するメイン DB であることに注意してください。Moodle は、テストを受ける必要がある許可されたユーザー専用です。だからMoodleでは、私は持っています:

ユーザー名: johndoe@gmail.com パスワード: blabla ユーザー ID: 1234

johndoe@gmail.comが外部 DB で自分のユーザー名/電子メールを更新することを決定した場合を除いて、これはうまく機能します。彼がログインしようとすると、Moodle は外部 DB でユーザー名とパスワードの両方をチェックするため、正常にログインします。問題: Moodle 内で johndoe@hotmail.com の新しいレコードが同じパスワードとユーザー ID で作成されます

私の質問は次のとおりです。ユーザー ID が既に存在し、新しいレコードを作成しない場合、どこでローカル DB を安全に確認できますか? 今後アップグレードの問題が発生したくないので、moodlelib doc を更新したくありません。外部 DB プラグインを更新できますが、どこが最適かわかりません。

これは誰かが行った回避策です - https://moodle.org/mod/forum/discuss.php?d=232163 - しかし、それはログイン直後ではなくcronジョブで行われます。

更新: moodlelibと外部dbプラグインを更新する必要があるようです。誰も投稿しない場合は、ソリューションを投稿します。

4

2 に答える 2

1

誰も答えなかったので、これが私が思いつく最高のものです。*UPDATED という独自のコメントがあるので、どこでコードを更新したかがわかります。

\moodle\lib\moodlelib.php の下(残念ながら、複製の作成をトリガーする認証呼び出しのため、このファイルを更新する必要がありました)

1) 更新関数 authenticate_user_login(); 行 4342 ~ 4382 を次のように置き換えます。

$authsenabled = get_enabled_auth_plugins();

// *UPDATED - begin
$authplugin = get_auth_plugin('DB');
$userinfo = ($authplugin->get_userinfo($username)) ? $authplugin->get_userinfo($username) : 0;
// *UPDATED - end    

// *UPDATED - added second elseif
if ($user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id)) {    
    // Use manual if auth not set.
    $auth = empty($user->auth) ? 'manual' : $user->auth;
    if (!empty($user->suspended)) {
        add_to_log(SITEID, 'login', 'error', 'index.php', $username);
        error_log('[client '.getremoteaddr()."]  $CFG->wwwroot  Suspended Login:  $username  ".$_SERVER['HTTP_USER_AGENT']);
        $failurereason = AUTH_LOGIN_SUSPENDED;
        return false;
    }
    if ($auth=='nologin' or !is_enabled_auth($auth)) {
        add_to_log(SITEID, 'login', 'error', 'index.php', $username);
        error_log('[client '.getremoteaddr()."]  $CFG->wwwroot  Disabled Login:  $username  ".$_SERVER['HTTP_USER_AGENT']);
        // Legacy way to suspend user.
        $failurereason = AUTH_LOGIN_SUSPENDED;
        return false;
    }
    $auths = array($auth);

} 
elseif ($user = get_complete_user_data('idnumber', $userinfo['idnumber'], $CFG->mnet_localhost_id)) {
    $auth = empty($user->auth) ? 'manual' : $user->auth;  // use manual if auth not set
    if (!empty($user->suspended)) {
        add_to_log(SITEID, 'login', 'error', 'index.php', $username);
        error_log('[client '.getremoteaddr()."]  $CFG->wwwroot  Suspended Login:  $username  ".$_SERVER['HTTP_USER_AGENT']);
        $failurereason = AUTH_LOGIN_SUSPENDED;
        return false;
    }
    if ($auth=='nologin' or !is_enabled_auth($auth)) {
        add_to_log(SITEID, 'login', 'error', 'index.php', $username);
        error_log('[client '.getremoteaddr()."]  $CFG->wwwroot  Disabled Login:  $username  ".$_SERVER['HTTP_USER_AGENT']);
        $failurereason = AUTH_LOGIN_SUSPENDED; // Legacy way to suspend user.
        return false;
    }
    $auths = array($auth);    
}    
else {
    // Check if there's a deleted record (cheaply), this should not happen because we mangle usernames in delete_user().
    if ($DB->get_field('user', 'id', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id,  'deleted' => 1))) {
        error_log('[client '.getremoteaddr()."]  $CFG->wwwroot  Deleted Login:  $username  ".$_SERVER['HTTP_USER_AGENT']);
        $failurereason = AUTH_LOGIN_NOUSER;
        return false;
    }

    // Do not try to authenticate non-existent accounts when user creation is not disabled.
    if (!empty($CFG->authpreventaccountcreation)) {
        add_to_log(SITEID, 'login', 'error', 'index.php', $username);
        error_log('[client '.getremoteaddr()."]  $CFG->wwwroot  Unknown user, can not create new accounts:  $username  ".$_SERVER['HTTP_USER_AGENT']);
        $failurereason = AUTH_LOGIN_NOUSER;
        return false;
    }

    // User does not exist.
    $auths = $authsenabled;
    $user = new stdClass();
    $user->id = 0;
}

2) 同じ機能で、行 4408 ~ 4427 を次のように置き換えます。

if ($user->id) {
    // User already exists in database.
    if (empty($user->auth)) {
        // For some reason auth isn't set yet.
        // *UPDATED $DB->set_field('user', 'auth', $auth, array('username'=>$username));
        $DB->set_field('user', 'auth', $auth, array('idnumber'=>$user->idnumber));                
        $user->auth = $auth;
    }

    // If the existing hash is using an out-of-date algorithm (or the legacy md5 algorithm), then we should update to
    // the current hash algorithm while we have access to the user's password.
    update_internal_user_password($user, $password);

    if ($authplugin->is_synchronised_with_external()) {
        // Update user record from external DB.
        // *UPDATED $user = update_user_record($username);
        $user = $authplugin->update_user_record($username, $user->idnumber);                
    }
} else {
    // Create account, we verified above that user creation is allowed.
    $user = create_user_record($username, $password, $auth);
}

\moodle\auth\db\auth.php (外部 DB プラグイン Lib)の下

1) IDNUMBER パラメータを受け取るように関数 update_user_record() を更新します。

function update_user_record($username, $idnumber='', $updatekeys=false) {  

2) 行 512 を次のように置き換えます。

$user = $DB->get_record('user', array('idnumber'=>$idnumber, 'mnethostid'=>$CFG->mnet_localhost_id)); 

したがって、moodle lib の下のメイン関数は、ユーザーがユーザー名で存在するかどうかを確認し、存在しない場合はユーザー ID が存在するかどうかを確認します...存在する場合は、外部 DB からの新しい情報でユーザーの情報を更新します。私の場合、Moodle 2.4 および 2.6 で問題なく動作します。

于 2013-11-22T21:51:56.280 に答える