| 1 | # OpenIDwithBanList plugin for Movable Type |
|---|
| 2 | # Author: Fumiaki Yoshimatsu (http://www.luckypines.com/mt/) |
|---|
| 3 | # Released under the Artistic License. |
|---|
| 4 | |
|---|
| 5 | package OpenID::WithBanList; |
|---|
| 6 | use strict; |
|---|
| 7 | use base qw( MT::Auth::OpenID ); |
|---|
| 8 | |
|---|
| 9 | sub login { |
|---|
| 10 | my $class = shift; |
|---|
| 11 | my ($app) = @_; |
|---|
| 12 | my $q = $app->{query}; |
|---|
| 13 | return $app->errtrans("Invalid request.") |
|---|
| 14 | unless $q->param('blog_id'); |
|---|
| 15 | my $blog = $app->model('blog')->load($q->param('blog_id')) |
|---|
| 16 | or return $app->errtrans("Invalid request."); |
|---|
| 17 | my %param = $app->param_hash; |
|---|
| 18 | my $csr = MT::Auth::OpenID::_get_csr(\%param, $blog) or return; |
|---|
| 19 | my $identity = $q->param('openid_url'); |
|---|
| 20 | if (!$identity && |
|---|
| 21 | (my $u = $q->param('openid_userid')) && $class->can('url_for_userid')) { |
|---|
| 22 | $identity = $class->url_for_userid($u); |
|---|
| 23 | } |
|---|
| 24 | my $claimed_identity = $csr->claimed_identity($identity); |
|---|
| 25 | if ( $claimed_identity && ( my $idp_server = $claimed_identity->{server} ) ) { |
|---|
| 26 | # check to see if the server is in the ban list |
|---|
| 27 | my $banned = 0; |
|---|
| 28 | require MT::PluginData; |
|---|
| 29 | my $plugindata = MT::PluginData->get_by_key({ plugin => 'OpenID::WithBanList', key => $blog->id . "_banlist" }); |
|---|
| 30 | if ( $plugindata ) { |
|---|
| 31 | my $list = $plugindata->data || []; |
|---|
| 32 | for my $hash ( @$list ) { |
|---|
| 33 | my $url = $hash->{url}; |
|---|
| 34 | if ( $idp_server =~ m|$url|i ) { |
|---|
| 35 | $banned = 1; |
|---|
| 36 | MT->log( |
|---|
| 37 | $app->translate('Banned login attempt by OpenID [_1]. [_2] is banned.', $identity, $url) |
|---|
| 38 | ); |
|---|
| 39 | return $app->errtrans('Your OpenID may be valid but you cannot use it here. Try different OpenID.'); |
|---|
| 40 | } |
|---|
| 41 | } |
|---|
| 42 | } |
|---|
| 43 | } |
|---|
| 44 | $class->SUPER::login(@_); |
|---|
| 45 | } |
|---|
| 46 | |
|---|
| 47 | sub list_idp { |
|---|
| 48 | my $app = shift; |
|---|
| 49 | my $q = $app->param; |
|---|
| 50 | |
|---|
| 51 | return $app->errtrans("Invalid request.") |
|---|
| 52 | unless $q->param('blog_id'); |
|---|
| 53 | my $blog = $app->model('blog')->load($q->param('blog_id')) |
|---|
| 54 | or return $app->errtrans("Invalid request."); |
|---|
| 55 | |
|---|
| 56 | require MT::PluginData; |
|---|
| 57 | my $plugindata = MT::PluginData->get_by_key({ plugin => 'OpenID::WithBanList', key => $blog->id . "_banlist" }); |
|---|
| 58 | |
|---|
| 59 | $app->load_tmpl( 'list_idps.tmpl', { |
|---|
| 60 | blog_id => $blog->id, |
|---|
| 61 | object_loop => $plugindata->data, |
|---|
| 62 | }); |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | sub add_idp { |
|---|
| 66 | my $app = shift; |
|---|
| 67 | my $q = $app->param; |
|---|
| 68 | |
|---|
| 69 | return $app->errtrans("Invalid request.") |
|---|
| 70 | unless $q->param('blog_id'); |
|---|
| 71 | my $blog = $app->model('blog')->load($q->param('blog_id')) |
|---|
| 72 | or return $app->errtrans("Invalid request."); |
|---|
| 73 | return $app->errtrans("Invalid request.") |
|---|
| 74 | unless $q->param('new_url'); |
|---|
| 75 | my $url = MT::Util::encode_html($q->param('new_url')); |
|---|
| 76 | |
|---|
| 77 | $app->validate_magic() or return; |
|---|
| 78 | |
|---|
| 79 | # First ban the existing commenters... |
|---|
| 80 | my $cmntr_iter = $app->model('commenter')->load_iter({ |
|---|
| 81 | name => { like => "%$url%" }, |
|---|
| 82 | type => MT::Author::COMMENTER(), |
|---|
| 83 | auth_type => [ 'OpenID', 'openid_banlist' ], |
|---|
| 84 | }); |
|---|
| 85 | while ( my $cmntr = $cmntr_iter->() ) { |
|---|
| 86 | next if MT::Author::BANNED() == $cmntr->commenter_status($blog->id); |
|---|
| 87 | $cmntr->ban($blog->id); |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | my $param = { |
|---|
| 91 | blog_id => $blog->id, |
|---|
| 92 | }; |
|---|
| 93 | |
|---|
| 94 | require MT::PluginData; |
|---|
| 95 | my $plugindata = MT::PluginData->get_by_key({ plugin => 'OpenID::WithBanList', key => $blog->id . "_banlist" }); |
|---|
| 96 | if ( $plugindata ) { |
|---|
| 97 | my $list = $plugindata->data || []; |
|---|
| 98 | my @keys = map { $_->{idp_id} } @$list; |
|---|
| 99 | @keys = sort { $b <=> $a } @keys; |
|---|
| 100 | my $next = $keys[0] + 1; |
|---|
| 101 | push @$list, { idp_id => $next, url => $url }; |
|---|
| 102 | $plugindata->data($list); |
|---|
| 103 | if ( $plugindata->save() ) { |
|---|
| 104 | $param->{saved} = 1; |
|---|
| 105 | } |
|---|
| 106 | else { |
|---|
| 107 | $param->{error} = $plugindata->errstr; |
|---|
| 108 | } |
|---|
| 109 | $param->{object_loop} = $list; |
|---|
| 110 | } |
|---|
| 111 | $app->load_tmpl( 'list_idps.tmpl', $param); |
|---|
| 112 | } |
|---|
| 113 | |
|---|
| 114 | sub delete_idp { |
|---|
| 115 | my $app = shift; |
|---|
| 116 | my $q = $app->param; |
|---|
| 117 | |
|---|
| 118 | return $app->errtrans("Invalid request.") |
|---|
| 119 | unless $q->param('blog_id'); |
|---|
| 120 | my $blog = $app->model('blog')->load($q->param('blog_id')) |
|---|
| 121 | or return $app->errtrans("Invalid request."); |
|---|
| 122 | |
|---|
| 123 | $app->validate_magic() or return; |
|---|
| 124 | |
|---|
| 125 | my $param = { |
|---|
| 126 | blog_id => $blog->id, |
|---|
| 127 | }; |
|---|
| 128 | |
|---|
| 129 | require MT::PluginData; |
|---|
| 130 | my $plugindata = MT::PluginData->get_by_key({ plugin => 'OpenID::WithBanList', key => $blog->id . "_banlist" }); |
|---|
| 131 | if ( $plugindata ) { |
|---|
| 132 | my $list = $plugindata->data || []; |
|---|
| 133 | my %id_hash = map { $_ => 1 } $q->param('id'); |
|---|
| 134 | my @new_list = map { $_ } grep { !exists( $id_hash{ $_->{idp_id} } ) } @$list; |
|---|
| 135 | $plugindata->data(\@new_list); |
|---|
| 136 | if ( $plugindata->save() ) { |
|---|
| 137 | $param->{saved_deleted} = 1; |
|---|
| 138 | } |
|---|
| 139 | else { |
|---|
| 140 | $param->{error} = $plugindata->errstr; |
|---|
| 141 | } |
|---|
| 142 | $param->{object_loop} = \@new_list; |
|---|
| 143 | } |
|---|
| 144 | $app->load_tmpl( 'list_idps.tmpl', $param); |
|---|
| 145 | } |
|---|
| 146 | |
|---|
| 147 | 1; |
|---|
| 148 | |
|---|