最近たまに書くというとこればかりの話になっているが、その割には一向に進まない・・・
djangoへの実装だが、今回はデータベースを使用するわけでもないテストページなので新たにアプリケーションを追加することなく、ポータルのトップページにコッソリぶら下げることとする。(とりあえずログインユーザーのみのアクセス制限は掛ける予定として)
まずはurls.pyへのページ追加
1 2 3 4 5 6 7 | app_name = 'top' urlpatterns = [ path(' ', views.IndexView.as_view(), name=' index'), path( 'iplog/' , views.BadIPView.as_view(), name = 'badip' ), path( 'ipsum/' , views.IpSumView.as_view(), name = 'iplog' ), ] |
indexは通常のポータルページで、今回 iplogとbadipという名前のページを追加する。iplogが不正アクセスの疑いのある(何回もログイン失敗を繰り返す輩)のIPアドレスとアクセス回数のリスト、badipがそのIPアドレスのアクセス履歴を表示するページ。
どちらのクラスもデータベースを使用せず、サーバー側のデータをリスト化して参照するので、まずはIpSumViewクラスから。
1 2 3 4 5 6 7 | class IpSumView(generic.ListView): template_name = 'top/ipsumlist.html' context_object_name = 'ipaddress_records' queryset = None paginate_by_default = 20 form1 = None form_initial = {} |
template_nameは使用するテンプレートのパス名、context_object_nameはテンプレートで使用するリスト。querysetは通常であればデータベースの問い合わせとして、モデルオブジェクトとの接続を行なうが、ここではNoneとしてメソッドのget_queryset()をオーバーライドして先のアクセス解析関数からの戻り値のリストとして返す
1 2 3 4 5 6 7 8 | def get_queryset( self ): """URL引数を取り出すサンプルとデータベースの代わりに動的にリストを作成する """ days = int ( self .request.GET.get( 'days' , 1 )) max = int ( self .request.GET.get( 'count' , 1 )) srt = self .request.GET.get( 'srt' , 'count' ) src = self .request.GET.get( 'src' , 'bt' ) return get_login_report(get_datetime_hours_ago(days * 24 ), get_datetime_hours_ago( 0 ), max , src, srt) |
実際はフォームのためのパラメータセットなどがあるが省略。
リクエストGETでパラメータを設定するが、パラメータがない場合の初期値を取るため上記のような書き方となっている。get_login_reportがアクセス集計関数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def get_login_report(st, ed, max = 1 , src = 'bt' , srt = 'count' ): iplist = {} #hists = get_login_history(st, ed) list1 = get_django_loginfails( None , st, ed) if src ! = 'wp' else [] list2 = get_wp_loginfails(st, ed) if src ! = 'dj' else [] hists = list1 + list2 blist = get_blocklist() for adr in map ( lambda x: x[ 'address' ], hists): iplist[adr] = iplist[adr] + 1 if adr in iplist.keys() else 1 retv = [{ 'address' :adr, 'count' : cnt} for adr, cnt in iplist.items() if cnt > = max and adr not in blist] if srt = = 'count' : retv.sort(key = lambda x: x[ 'count' ], reverse = True ) else : retv.sort(key = lambda x: hash (x[ 'address' ]), reverse = True ) return retv |
wordpressのログイン履歴データベースからのリストと、djangoポータルページへの履歴を合せて、アクセス回数ごとのリストに変換。指定回数以上アクセスした対象を返す関数となっている。
めっちゃくちゃ端折った感じで完成してますが、所詮覚え書きなので、ここまでの作り込みに関して気が付いたときに勘所とかを追記していこうと思います。