0

wikidatabaseのuserテーブルに。という列を追加しましたapproved_account。その列の標準値は0(ゼロ)です。

ユーザーがWikiにログインしようとしたときに例外を追加してapproved_account = 0、ログインの試行が拒否されるようにします。

誰かが私がそのifステートメントをどこにどのように配置すべきか知っていますか?


編集:私はここまで来ました。ユーザーがログインしようとするたびにステートメントがtrueであるかどうかを確認する必要があるため、AbortLoginフックを使用しています。

ただし、私のコードでは誰も入れません。フィールドに正しい値がある場合でも、すべてのログイン試行がブロックされapproved_accountます。誰かが私がこれを修正するのを手伝ってもらえますか?

<?php
/** 
* Prevent a user from accessing this file directly and provide a helpful 
* message explaining how to install this extension.
*/
if ( !defined( 'MEDIAWIKI' ) ) {
    echo <<<EOT
To install the Test extension, put the following line in your LocalSettings.php file: 
require_once( "$IP/extensions/approvedaccount.php" );
EOT;
    exit( 1 );
}

// Extension credits that will show up on Special:Version
$wgExtensionCredits['parserhook'][] = array(
    'name' => 'Approved Account extension',
    'description' => 'Prevent login',
    'author' => 'Me',
    'url' => 'http://www.mediawiki.org/wiki/Extension:approvedaccount'
);
$wgHooks['AbortLogin'][] = 'approvedaccount::onAbortLogin';

class approvedaccount
{
    public static function onAbortLogin( $user, $password, &$retval ) {
    global $wgOut, $wgUser;

    $dbr = wfGetDB( DB_SLAVE );
    $res = $dbr->select(
    'user',                                     // $table
    array( 'user_name', 'approved_account' ),   // $vars (columns of the table)
    'user_name = "'.$wgUser.'"',                // $conds
    __METHOD__,                                 // $fname = 'Database::select',
    array( 'ORDER BY' => 'user_name ASC' )      // $options = array()
    );

    $output = '';
    foreach( $res as $row ) {
    $output .= 'Användarnamn: ' . $row->user_name . ' , Approved Account: ' . $row->approved_account . ".";
    }

    if ($row->approved_account = "1"){
    //$this->loadDefaults();
    //  return false;
    header("Location: http://hbg-whirlpool.emea.stream.corp/index.php?title=Special:UserLogout&returnto=Main+Page");
    exit();  // you need to exit after a Location header is sent
    }   
}
}
4

1 に答える 1

0

単純なAuthPluginでこれを行うことができ、メソッドをオーバーライドしてstrictUserAuth()、条件に一致するユーザーに対して true を返します。

ただし、この問題に間違った方法で取り組んでいると思われます。新しいユーザー グループ(たとえば、 ) を定義しapproved、対応するレコードを承認されたユーザーのuser_groups テーブルに追加しないのはなぜですか? 承認されていないユーザーがログインするのを防ぐことはできませんが、次のように、承認されたグループに権限を付与するだけで編集を防ぐことができます。edit

$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['user']['edit'] = false;
$wgGroupPermissions['approved']['edit'] = true;

(必要に応じて、承認されていないユーザーの許可を取り消すこともできますが、MediaWiki での読み取りアクセスの制限readに関する警告を最初に読んでください。)


編集: AbortLogin フックにいくつかの問題があります。

  • フックの途中で301 リダイレクトを行うのexit()は、おそらくあまり良い考えではありません。確かに、おそらくログイン中止されますが、それは実際にはフックの使用方法ではありません。むしろ、falseログインを中止する必要があることを示すかtrue、通常のログイン チェックを続行するために、フック関数を返す必要があります。

  • いずれにせよ、 列がであるexit()ときに実行しています。これは、おそらくログインを中止したくないときです。approved_account1

  • ...というか、条件で比較演算子の代わりにexit()代入演算子を使用したため、常に true になるため、常に実行しています。(心配しないでください。これは、PHP やその他の C に似た言語でよくあるバグです。回避する 1 つの方法は、 のような「Yoda 条件」を使用する習慣を身に付けることです。に割り当てることはできません。)===1 == $row->approved_account=1

  • また、User オブジェクトを文字列と連結しても、おそらく意味のあるものは何も生成されません。仮にそうだったとしても、そこには SQL インジェクションの脆弱性が存在するでしょう。さらに、フック パラメータにはすでに User オブジェクトが含まれているため、グローバルの代わりにそれを使用する必要があり$wgUserます (いずれにせよ、ログイン中に古くなる可能性があります)。

このようなもののいくつかは、文書化が不十分であることを認めます。AbortLoginのドキュメントに加えて、一般的な MediaWiki フックのドキュメントと、 SpecialUserlogin.phpからフックが呼び出される実際の方法を確認することをお勧めします。データベース アクセスについては、データベース ラッパー関数 docsも参照してください。残念ながら、メソッドのドキュメント ページでは現在 404 エラーが発生しているため、ドキュメントのソースを直接確認する必要があります。

とにかく、私はあなたのフックを次のように書き直します:

public static function onAbortLogin( $user, $password, &$retval, &$msg ) {
    $dbr = wfGetDB( DB_SLAVE );
    $row = $dbr->selectRow(
        'user',
        'approved_account',
        array( 'user_id' => $user->getID() ),
        __METHOD__
    );

    if ( !$row || !$row->approved_account ) {
        $retval = LoginForm::ABORTED;  // actually the default, but let's be sure
        $msg = 'login-abort-not-approved';  // optional: custom error message
        return false;
    }
    else {
        // account is approved, return true to proceed with other login checks
        return true;
    }
}

カスタム メッセージが必要な場合はMediaWiki:login-abort-not-approved、Wiki にページを作成する必要もあります。(これを適切な MediaWiki 拡張機能に変えたい場合は、i18n ファイルにデフォルトのメッセージを提供できますが、おそらくここではやり過ぎです。)


編集 2:はい、拡張機能に必要な数のフックを追加できます。(実際、拡張機能は必要ありません。必要に応じて、単純なサイト固有のフックを LocalSettings.php で直接定義してもまったく問題ありません。)このようなものは、ユーザーをログアウトするためのAddNewAccount フックで機能すると思います。ただし、これを実際にテストしていないことに注意する必要があります。

public static function onAddNewAccount( $user, $byEmail ) {
    global $wgUser;
    // try to log out the new user only if they're actually logged in
    if ( $user->getName() == $wgUser->getName() ) $user->logout();
    return true;
}

ifAddNewAccount は、ユーザーが既存のアカウントにログインしているときに新しいアカウントを作成するときにも呼び出されるため、この句が存在します。この場合、元のアカウントからログアウトすることは歓迎されない驚きです。(技術的にif ( $user == $wgUser )は十分ですが、オブジェクト参照ではなくユーザー名を明示的に比較する方が安全なようです。)

その時点で新しいユーザーをログアウトすると、新しいユーザー作成コードの下からカーペットが引っ張られるので、異常なことが起こる可能性があることに注意してください。たとえば、ユーザー作成ログが実際には「NewUserName が新しいユーザー アカウント NewUserName を作成しました」のようなメッセージを出力し、「アカウントが正常に作成されました」ページに、ユーザーが実際にはログインしているにもかかわらず、一時的にログインしていると表示される可能性があると思われます。いいえ。

そもそも自動ログイン動作をどうにかして回避する方がはるかにクリーンですが、SpecialUserlogin.php にパッチを適用せずにそれを行う明確な方法はありません。新しいユーザーが自動的にログインしているかどうかを判断する唯一のチェックは、if ( $this->getUser()->isAnon() )、ユーザーが既にログインしているかどうかを確認するだけです。私が知る限り、何らかの方法でそれを偽造することでさえ(それ自体が醜いクルージになるでしょう)、実際には実用的ではないようです。

ただし、MediaWiki コアにパッチを適用することを気にしない場合は、その条件をif ( false )(またはif ( false && $this->getUser()->isAnon() )、自己文書化を維持したい場合は ) に置き換えるだけでうまくいくはずです。アップグレードなどの後にパッチを再適用するのを忘れた場合に備えて、AddNewAccount フックをバックアップとして保持できることに注意してください。

于 2013-03-21T12:15:06.843 に答える