Auth   B
last analyzed

Complexity

Total Complexity 51

Size/Duplication

Total Lines 261
Duplicated Lines 15.33 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 8
Bugs 5 Features 4
Metric Value
wmc 51
c 8
b 5
f 4
lcom 1
cbo 1
dl 40
loc 261
rs 8.3206

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getEncPass() 0 4 1
A getProvider() 0 13 2
A getBasicAuthDialog() 0 8 1
C basicAuth() 0 30 8
D callProviderMethod() 40 129 38

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Auth often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Auth, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Auth
4
 *
5
 * 認証のためのファンクション群
6
 *
7
 * @package           risoluto
8
 * @author            Risoluto Developers
9
 * @license           http://opensource.org/licenses/bsd-license.php new BSD license
10
 * @copyright     (C) 2008-2015 Risoluto Developers / All Rights Reserved.
11
 */
12
13
//------------------------------------------------------//
14
// 名前空間の定義
15
//------------------------------------------------------//
16
namespace Risoluto;
17
18
//------------------------------------------------------//
19
// クラス定義
20
//------------------------------------------------------//
21
class Auth
22
{
23
    //------------------------------------------------------//
24
    // クラスメソッド定義
25
    //------------------------------------------------------//
26
    /**
27
     * __construct()
28
     *
29
     * コンストラクタ
30
     */
31
    private function __construct()
32
    {
33
    }
34
35
    /**
36
     * getEncPass($target)
37
     *
38
     * 引数で与えられた文字列をパスワード用にハッシュ化する
39
     *
40
     * @access    private
41
     *
42
     * @param     string $target パスワード文字列
43
     *
44
     * @return    string ハッシュ化したパスワード文字列
45
     */
46
    private static function getEncPass( $target )
47
    {
48
        return password_hash( $target, PASSWORD_DEFAULT );
49
    }
50
51
    /**
52
     * getProvider()
53
     *
54
     * 認証プロバイダの情報を取得する
55
     *
56
     * @access    private
57
     *
58
     * @param     void
59
     *
60
     * @return    object    認証プロバイダのインスタンス
61
     */
62
    private static function getProvider()
63
    {
64
        // コンフィグファイルの読み込み
65
        $conf = new Conf;
66
        $conf->parse( RISOLUTO_CONF . 'risoluto.ini' );
67
68
        // プロバイダ情報を取得
69
        $tmp_provider = $conf->getIni( 'AUTH', 'provider' );
70
        $provider = !empty( $tmp_provider ) ? $tmp_provider : 'Risoluto\\AuthDb';
71
72
        // 取得したプロバイダのインスタンスを生成し返却する
73
        return ( $provider );
74
    }
75
76
    /**
77
     * getBasicAuthDialog($realm, $message)
78
     *
79
     * BASIC認証のダイアログ表示用ヘッダを出力する
80
     *
81
     * @access    private
82
     *
83
     * @param     string $realm レルム
84
     * @param     string $message ブラウザ側に出力するメッセージ
85
     *
86
     * @return    void なし
87
     */
88
    private static function getBasicAuthDialog( $realm, $message )
89
    {
90
        // 認証に失敗したらダイアログ表示をセットし、強制終了
91
        header( "WWW-Authenticate: Basic realm=\"$realm\"" );
92
        http_response_code( 401 );
93
        echo $message;
94
        exit;
95
    }
96
97
    /**
98
     * getBasicAuthDialog($realm, $message)
99
     *
100
     * BASIC認証を行う
101
     *
102
     * @access    public
103
     *
104
     * @param     string $realm レルム(省略可、デフォルトは'Authorization Required')
105
     * @param     string $message ブラウザ側に出力するメッセージ(省略可、デフォルトは'Authorization Required')
106
     *
107
     * @return    mixed ユーザ情報:認証成功時/false: 認証失敗時
108
     */
109
    public static function basicAuth( $realm = 'Authorization Required', $message = 'Authorization Required' )
110
    {
111
        // ユーザ情報とパスワード情報を取得する
112
        $user = ( isset( $_SERVER[ 'PHP_AUTH_USER' ] ) and !empty( $_SERVER[ 'PHP_AUTH_USER' ] ) ) ? $_SERVER[ 'PHP_AUTH_USER' ] : null;
113
        $pass = ( isset( $_SERVER[ 'PHP_AUTH_PW' ] ) and !empty( $_SERVER[ 'PHP_AUTH_PW' ] ) ) ? $_SERVER[ 'PHP_AUTH_PW' ] : null;
114
115
        // 認証に必要な情報がセットされていれば認証ロジックをコール
116
        if ($user and $pass) {
117
            // プロバイダのインスタンスを取得し、認証ロジックをコール
118
            $call_provider = self::getProvider();
119
            $provider = new $call_provider;
120
121
            // 認証に失敗したときはダイアログを出力
122
            /** @noinspection PhpUndefinedMethodInspection */
123
            if (!$provider->doAuth( $user, $pass )) {
124
                self::getBasicAuthDialog( $realm, $message );
125
126
                return false;
127
            } else {
128
                // 認証に成功したらユーザ情報を返却
129
                /** @noinspection PhpUndefinedMethodInspection */
130
                return $provider->doOperation( 'showuser', [ 'userid' => $user ] );
131
            }
132
        }
133
134
        // 認証に必要な情報がセットされていないときはダイアログを出力
135
        self::getBasicAuthDialog( $realm, $message );
136
137
        return false;
138
    }
139
140
    /**
141
     * callProviderMethod()
142
     *
143
     * 認証プロバイダのメソッドをコールする
144
     *
145
     * @access    public
146
     *
147
     * @param     string $operation オペレーション識別子(init/addUser/addGroup/modUser/modGroup/delUser/delGroup/showUser/showGroup/showUserAll/showGroupAll)
148
     * @param     array  $option オプション情報(省略可)
149
     *
150
     * @return    mixed trueまたは取得内容:成功/false:失敗
151
     */
152
    public static function callProviderMethod( $operation, array $option = [ ] )
153
    {
154
        // プロバイダのインスタンスを取得し、認証ロジックをコール
155
        $call_provider = self::getProvider();
156
        $provider = new $call_provider;
157
158
        switch ($operation) {
159
            // 初期化
160
            case 'init':
161
                /** @noinspection PhpUndefinedMethodInspection */
162
                $retval = $provider->init();
163
                break;
164
165
            // 認証
166
            case 'doAuth':
167
                /** @noinspection PhpUndefinedMethodInspection */
168
                if (isset( $option[ 'userid' ] ) and isset( $option[ 'password' ] )) {
169
                    // メソッドをコール
170
                    /** @noinspection PhpUndefinedMethodInspection */
171
                    $retval = $provider->doAuth( $option[ 'userid' ], $option[ 'password' ], $option );
172
                } else {
173
                    $retval = false;
174
                }
175
                break;
176
177
            // ユーザ追加/変更
178
            case 'addUser': // FALL THRU
179 View Code Duplication
            case 'modUser':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
                // パラメタのチェック
181
                if (isset( $option[ 'userid' ] ) and isset( $option[ 'username' ] ) and isset( $option[ 'password' ] ) and isset( $option[ 'groupno' ] )) {
182
                    // パスワードをハッシュ化したのちメソッドをコール
183
                    $option[ 'password' ] = self::getEncPass( $option[ 'password' ] );
184
                    /** @noinspection PhpUndefinedMethodInspection */
185
                    $retval = $provider->doOperation( $operation, $option );
186
                } else {
187
                    $retval = false;
188
                }
189
                break;
190
191
192
            // ユーザ変更(No使用)
193 View Code Duplication
            case 'modUserByNo':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
                // パラメタのチェック
195
                if (isset( $option[ 'no' ] ) and isset( $option[ 'userid' ] ) and isset( $option[ 'username' ] ) and isset( $option[ 'password' ] ) and isset( $option[ 'groupno' ] )) {
196
                    // パスワードをハッシュ化したのちメソッドをコール
197
                    $option[ 'password' ] = self::getEncPass( $option[ 'password' ] );
198
                    /** @noinspection PhpUndefinedMethodInspection */
199
                    $retval = $provider->doOperation( $operation, $option );
200
                } else {
201
                    $retval = false;
202
                }
203
                break;
204
205
            // グループ追加/変更
206
            case 'addGroup': // FALL THRU
207 View Code Duplication
            case 'modGroup':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
                // パラメタのチェック
209
                if (isset( $option[ 'groupid' ] ) and isset( $option[ 'groupname' ] )) {
210
                    /** @noinspection PhpUndefinedMethodInspection */
211
                    $retval = $provider->doOperation( $operation, $option );
212
                } else {
213
                    $retval = false;
214
                }
215
                break;
216
217
            // グループ変更(No使用)
218 View Code Duplication
            case 'modGroupByNo':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
219
                // パラメタのチェック
220
                if (isset( $option[ 'no' ] ) and isset( $option[ 'groupid' ] ) and isset( $option[ 'groupname' ] )) {
221
                    /** @noinspection PhpUndefinedMethodInspection */
222
                    $retval = $provider->doOperation( $operation, $option );
223
                } else {
224
                    $retval = false;
225
                }
226
                break;
227
228
            // ユーザ削除/情報表示
229
            case 'delUser': // FALL THRU
230
            case 'showUser':
231
                // パラメタのチェック
232
                if (isset( $option[ 'userid' ] )) {
233
                    /** @noinspection PhpUndefinedMethodInspection */
234
                    $retval = $provider->doOperation( $operation, $option );
235
                } else {
236
                    $retval = false;
237
                }
238
                break;
239
240
            // グループ削除/情報表示
241
            case 'delGroup': // FALL THRU
242
            case 'showGroup':
243
                // パラメタのチェック
244
                if (isset( $option[ 'groupid' ] )) {
245
                    /** @noinspection PhpUndefinedMethodInspection */
246
                    $retval = $provider->doOperation( $operation, $option );
247
                } else {
248
                    $retval = false;
249
                }
250
                break;
251
252
            // ユーザ/グループNo削除/表示
253
            case 'delUserByNo':
254
            case 'delGroupByNo':
255
            case 'showUserByNo':
256
            case 'showGroupByNo':
257
                // パラメタのチェック
258
                if (isset( $option[ 'no' ] )) {
259
                    /** @noinspection PhpUndefinedMethodInspection */
260
                    $retval = $provider->doOperation( $operation, $option );
261
                } else {
262
                    $retval = false;
263
                }
264
                break;
265
266
            // ユーザ/グループ情報全件表示
267
            case 'showUserAll': // FALL THRU
268
            case 'showGroupAll':
269
                /** @noinspection PhpUndefinedMethodInspection */
270
                $retval = $provider->doOperation( $operation, [ ] );
271
                break;
272
273
            // 未定義の場合はfalseを返す
274
            default:
275
                $retval = false;
276
                break;
277
        }
278
279
        return $retval;
280
    }
281
}
282