Index: /trunk/mixiComment/plugins/mixiComment/mixiComment.pl
===================================================================
--- /trunk/mixiComment/plugins/mixiComment/mixiComment.pl (revision 971)
+++ /trunk/mixiComment/plugins/mixiComment/mixiComment.pl (revision 971)
@@ -0,0 +1,101 @@
+package MT::Plugin::mixiComment;
+
+use strict;
+use warnings;
+
+use MT;
+use base qw(MT::Plugin);
+
+my $plugin = MT::Plugin::mixiComment->new({
+    id => 'mixicomment',
+    name => 'mixiComment',
+    author_name => 'Six Apart K.K.',
+    author_url => 'http://www.movabletype.jp/',
+    description => '<MT_TRANS phrase="Allows commenters to sign in to Movable Type 4 using their own mixi username and password via OpenID.">',
+    version => '1.0',
+    settings => new MT::PluginSettings([
+        ['mixi_id', { Scope => 'blog' }],
+    ]),
+    l10n_class => 'mixiComment::L10N',
+	blog_config_template => 'config.tmpl',
+});
+MT->add_plugin($plugin);
+
+sub load_config {
+    my $plugin = shift;
+    my ($args, $scope) = @_;
+
+    $plugin->SUPER::load_config(@_);
+
+    if ( $scope =~ /blog:(\d+)/ ) {
+        my $blog_id = $1;
+        $args->{blog_id} = $blog_id;
+    }
+}
+
+sub init_registry {
+    my $plugin = shift;
+    $plugin->registry({
+        applications => {
+            cms => {
+                methods => {
+                    mixicomment_login_blog_owner => '$mixicomment::mixiComment::App::login_blog_owner',
+                    mixicomment_verify_blog_owner => '$mixicomment::mixiComment::App::verify_blog_owner',
+                }
+            }
+        },
+        commenter_authenticators => {
+            'mixicomment' => {
+                label => 'mixi',
+                class => 'mixiComment::Auth::mixi',
+                login_form => <<EOT,
+<__trans_section component="mixicomment">
+<form method="post" action="<mt:var name="script_url">">
+<input type="hidden" name="__mode" value="login_external" />
+<input type="hidden" name="openid_url" value="<mt:var name="url">" />
+<input type="hidden" name="blog_id" value="<mt:var name="blog_id">" />
+<input type="hidden" name="entry_id" value="<mt:var name="entry_id">" />
+<input type="hidden" name="static" value="<mt:var name="static" escape="html">" />
+<input type="hidden" name="key" value="mixicomment" />
+<fieldset>
+<mtapp:setting
+    id="mixiComment_display"
+    hint="<__trans phrase="Sign in using your mixi ID">">
+    <input type="image" src="<mt:var name="static_uri">plugins/mixiComment/images/mixi_button.gif" width="150" height="30" />
+    <p><__trans phrase="Click the button to sign in using your mixi ID"></p>
+</mtapp:setting>
+</fieldset>
+</form>
+</__trans_section>
+EOT
+                login_form_params => sub {
+                    my ($key, $blog_id, $entry_id, $static) = @_;
+
+                    my %param;
+                    $plugin->load_config(\%param, "blog:$blog_id");
+                    my $url;
+                    if ( my $mixi_id = $param{mixi_id} ) {
+                        $url = "https://id.mixi.jp/$mixi_id/friends";
+                    }
+                    else {
+                        $url = "http://mixi.jp/";
+                    }
+                    my $params = {
+                        blog_id => $blog_id,
+                        static  => $static,
+                        url     => $url,
+                    };
+                    $params->{entry_id} = $entry_id if defined $entry_id;
+                    return $params;
+                },
+                logo => 'plugins/mixiComment/images/signin_mixi.png',
+                logo_small => 'plugins/mixiComment/images/signin_mixi_small.gif'
+            },
+        },
+    });
+}
+
+sub instance { $plugin }
+
+1;
+__END__
Index: /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/Auth/mixi.pm
===================================================================
--- /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/Auth/mixi.pm (revision 971)
+++ /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/Auth/mixi.pm (revision 971)
@@ -0,0 +1,93 @@
+package mixiComment::Auth::mixi;
+
+use strict;
+use base qw( MT::Auth::OpenID );
+
+sub check_url_params {
+    my $class = shift;
+    my ( $app, $blog ) = @_;
+    my $q = $app->{query};
+
+    if ( $q->param('verify_blog_owner') ) {
+        my $path = MT->config->AdminCGIPath || MT->config->CGIPath;
+        $path = _adjust_path( $path, $blog );
+        $path .= MT->config->AdminScript;
+        my $return_to = $path . '?__mode=mixicomment_verify_blog_owner'
+            . '&blog_id='  . $blog->id;
+        return ( trust_root => $path, return_to => $return_to );
+    }
+    else {
+        return $class->SUPER::check_url_params(@_);
+    }
+}
+
+sub _adjust_path {
+    my ( $path, $blog ) = @_;
+    if ($path =~ m!^/!) {
+        # relative path, prepend blog domain
+        my ($blog_domain) = $blog->archive_url =~ m|(.+://[^/]+)|;
+        $path = $blog_domain . $path;
+    }
+    $path .= '/' unless $path =~ m|/$|;
+    $path;
+}
+
+# TODO: remove these once core code supports SREG - BugID:71011
+sub NS_OPENID_SREG { "http://openid.net/extensions/sreg/1.1" }
+
+sub login {
+    my $class = shift;
+    my ($app) = @_;
+    my $q = $app->{query};
+    return $app->errtrans("Invalid request.")
+        unless $q->param('blog_id');
+    my $blog = MT::Blog->load(scalar $q->param('blog_id'));
+    my %param = $app->param_hash;
+    my $csr = MT::Auth::OpenID::_get_csr(\%param, $blog) or return;
+    my $identity = $q->param('openid_url');
+    if (!$identity &&
+        (my $u = $q->param('openid_userid')) && $class->can('url_for_userid')) {
+        $identity = $class->url_for_userid($u);
+    }
+    my $claimed_identity = $csr->claimed_identity($identity);
+    if (!$claimed_identity) {
+        my ($err_code, $err_msg) = ($csr->errcode, $csr->errtext);
+        if ($err_code eq 'no_head_tag' || $err_code eq 'no_identity_server' || $err_code eq 'url_gone') {
+            $err_msg = $app->translate('The address entered does not appear to be an OpenID');
+        }
+        elsif ($err_code eq 'empty_url' || $err_code eq 'bogus_url') {
+            $err_msg = $app->translate('The text entered does not appear to be a web address');
+        }
+        elsif ($err_code eq 'url_fetch_error') {
+            $err_msg =~ s{ \A Error \s fetching \s URL: \s }{}xms;
+            $err_msg = $app->translate('Unable to connect to [_1]: [_2]', $identity, $err_msg);
+        }
+        return $app->error($app->translate("Could not verify the OpenID provided: [_1]", $err_msg));
+    }
+
+    my %params = $class->check_url_params( $app, $blog );
+
+    $claimed_identity->set_extension_args(NS_OPENID_SREG(), {
+        optional => join(",", qw/email nickname fullname/)
+    });
+
+    my $check_url = $claimed_identity->check_url(
+        ( %params, delayed_return => 1 )
+    );
+
+    return $app->redirect($check_url);
+}
+
+sub get_nickname {
+    my $class = shift;
+    my ($vident) = @_;
+
+    # Try SREG extension first
+    my $fields = $vident->extension_fields(NS_OPENID_SREG);
+    return $fields->{nickname} if exists $fields->{nickname};
+    return $fields->{fullname} if exists $fields->{fullname};
+    $class->SUPER::get_nickname(@_);
+}
+
+1;
+__END__
Index: /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N.pm
===================================================================
--- /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N.pm (revision 971)
+++ /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N.pm (revision 971)
@@ -0,0 +1,5 @@
+package mixiComment::L10N;
+use strict;
+use base 'MT::Plugin::L10N';
+
+1;
Index: /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N/en_us.pm
===================================================================
--- /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N/en_us.pm (revision 971)
+++ /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N/en_us.pm (revision 971)
@@ -0,0 +1,9 @@
+package mixiComment::L10N::en_us;
+
+use strict;
+
+use base 'mixiComment::L10N';
+use vars qw( %Lexicon );
+%Lexicon = ();
+
+1;
Index: /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N/ja.pm
===================================================================
--- /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N/ja.pm (revision 971)
+++ /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/L10N/ja.pm (revision 971)
@@ -0,0 +1,16 @@
+package mixiComment::L10N::ja;
+
+use strict;
+use base 'mixiComment::L10N::en_us';
+use vars qw( %Lexicon );
+
+%Lexicon = (
+    'Allows commenters to sign in to Movable Type 4 using their own mixi username and password via OpenID.' => 'mixiã®ã¢ã«ãŠã³ããäœ¿ã£ãŠMovable Type 4ã«ã³ã¡ã³ãããããšãã§ããããã«ããŸãã',
+    'mixi reported that you failed to login.  Try again.' => 'ã­ã°ã€ã³ã«å€±æããŸããã',
+    'A mixi ID has already been registered in this blog.  If you want to change the mixi ID for the blog, <a href="[_1]">click here</a> to sign in using your mixi account.  If you want all of the mixi users to comment to your blog (not only your my mixi users), click the reset button to remove the setting.' => 'ãã§ã«mixiã®IDãç»é²ããŠãããŸãããã­ã°ã«é¢é£ä»ããmixiã®IDãå€ãããå Žåã¯ã<a href="[_1]">ãããã¯ãªãã¯ããŠmixiã«ã­ã°ã€ã³</a>ããŠãã ããããã€ãã¯ã ãã§ãªããã¹ãŠã®mixiãŠãŒã¶ãŒããã®ã³ã¡ã³ããåãä»ããããšãã¯ãåæåãã¿ã³ãã¯ãªãã¯ããŠèš­å®ãæ¶å»ããŠãã ããã',
+    'If you want to restrict comments only from your my mixi users, <a href="[_1]">click here</a> to sign in using your mixi account.' => 'ãã€ãã¯ããã®ã¿ã³ã¡ã³ããåãä»ããèš­å®ã«ããã«ã¯ã<a href="[_1]">ãããã¯ãªãã¯ããŠãŸãmixiã«ã­ã°ã€ã³</a>ããŠãã ããã',
+    'Click the button to sign in using your mixi ID' => 'ãã¿ã³ãã¯ãªãã¯ããŠmixiã«ã­ã°ã€ã³ããŠãã ããã',
+    'Sign in using your mixi ID' => 'mixiã®IDã§ã­ã°ã€ã³ãã',
+);
+
+1;
Index: /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/App.pm
===================================================================
--- /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/App.pm (revision 971)
+++ /trunk/mixiComment/plugins/mixiComment/lib/mixiComment/App.pm (revision 971)
@@ -0,0 +1,55 @@
+package mixiComment::App;
+
+use strict;
+use mixiComment::Auth::mixi;
+
+sub login_blog_owner {
+    my $app = shift;
+
+    $app->param('verify_blog_owner', 1);
+    mixiComment::Auth::mixi->login($app);
+}
+
+sub verify_blog_owner {
+    my $app = shift;
+    my $q   = $app->param;
+
+    my $plugin = $app->component('mixicomment');
+    return $app->errtrans('Invalid request') unless $plugin;
+
+    my $blog_id = $q->param('blog_id');
+    my $blog    = $app->model('blog')->load($blog_id);
+    return $app->errtrans('Invalid blog') unless $blog;
+
+    my %param = $app->param_hash;
+    my $csr   = MT::Auth::OpenID::_get_csr(\%param, $blog)
+        or return $app->errtrans('Invalid request');
+
+    if ( my $setup_url = $csr->user_setup_url( post_grant => 'return' ) ) {
+        return $app->redirect($setup_url);
+    }
+    elsif ( my $vident = $csr->verified_identity ) {
+        my $url = $vident->url;
+        my ($mixi_id) = $url =~ m|^https?://id.mixi.jp/(\d+)$|;
+        return $app->error( $plugin->translate('mixi reported that you failed to login.  Try again.') )
+            unless $mixi_id;
+
+        $plugin->save_config(
+            { mixi_id => $mixi_id },
+            'blog:' . $blog->id
+        );
+
+        return $app->redirect(
+            $app->uri(
+                mode => 'cfg_plugins',
+                args => { blog_id => $blog->id }
+            )
+        );
+    }
+
+    # login failed
+    return $app->error( $plugin->translate('mixi reported that you failed to login.  Try again.') );
+}
+
+1;
+__END__
Index: /trunk/mixiComment/README.ja
===================================================================
--- /trunk/mixiComment/README.ja (revision 971)
+++ /trunk/mixiComment/README.ja (revision 971)
@@ -0,0 +1,31 @@
+mixiCommentãã©ã°ã€ã³ã®äœ¿ãæ¹
+
+1. å¿
+èŠç°å¢
+
+Movable TypeãåäœããŠãããµãŒããŒã«ãCrypt::SSLeayã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ãããŠããå¿
+èŠããããŸããã€ã³ã¹ããŒã«ãããŠããªããšãmixiã«OpenIDã§ã­ã°ã€ã³ããããšããéã«ããOpenIDãæ€èšŒã§ããŸããã§ãã: å
+¥åãããã¢ãã¬ã¹ã¯OpenIDã§ã¯ãããŸãããããšãããšã©ãŒã«ãªããŸãã
+
+2. ã»ããã¢ãã
+
+mixiCommentãã©ã°ã€ã³ã«å«ãŸããpluginsãã£ã¬ã¯ããªã®äž­èº«ãããäœ¿ãã®Movable Type 4ã®pluginsãã£ã¬ã¯ããªã«ã³ããŒããŠãã ãããåãããmixiCommentãã©ã°ã€ã³ã«å«ãŸããmt-staticãã£ã¬ã¯ããªã®äž­èº«ãããäœ¿ãã®Movable Type 4ã®mt-staticãã£ã¬ã¯ããªã«ã³ããŒããŠãã ããã
+
+æ¬¡ã«ãMovable Type 4ã®ã¡ãã¥ãŒãããèš­å®ãïŒãç»é²/èªèšŒãç»é¢ã«é²ã¿ãŸãããèªèšŒæ¹åŒãã®äžèŠ§ã«mixiãè¡šç€ºãããã®ã§ããã§ãã¯ããŠæå¹ã«ããŠãèš­å®ãä¿å­ããŸãã
+
+ããã§ã»ããã¢ããã¯å®äºã§ãããã­ã°èšäºã«ã³ã¡ã³ãããéã«ãèªèšŒãµãŒãã¹ã®äžèŠ§ã«mixiãè¿œå ãããŸãã
+
+3. ãã€ãã¯èªèšŒ
+
+ã»ããã¢ããããç¶æ
+ã§ã¯ãmixiã®ãŠãŒã¶ãŒã§ããã°ã ãã§ããµã€ã³ã€ã³ããŠã³ã¡ã³ãããããšãã§ããŸãããã­ã°ã®ç®¡çè
+ãšãã€ãã¯ã«ãªã£ãŠãããŠãŒã¶ãŒã ãã«ã³ã¡ã³ããå¶éãããå Žåã«ã¯ãä»¥äžã®è¿œå æäœãè¡ããŸãã
+
+ãã­ã°ã®ç®¡çè
+æš©éãæã€ãŠãŒã¶ãŒã§Movable Typeã«ãµã€ã³ã€ã³ãããã©ã°ã€ã³ã®èš­å®ç»é¢ã«ç§»åããŠãã ãããmixiCommentãã©ã°ã€ã³ãäžèŠ§ã«è¡šç€ºãããã®ã§ãååã®éšåãã¯ãªãã¯ããŸããè©³çŽ°ç»é¢ãéãããããèš­å®ãã¿ããã¯ãªãã¯ããŸããããããã¯ãªãã¯ããŠãŸãmixiã«ã­ã°ã€ã³ãã®ãªã³ã¯ãã¯ãªãã¯ããŠãmixiã«ã­ã°ã€ã³ããŸããã­ã°ã€ã³ãããšãmixiã®IDãMovable Type 4ã®ããŒã¿ããŒã¹ã«ä¿å­ãããŸãããã®ãšãmixiã«ã­ã°ã€ã³ãããŠãŒã¶ãŒãšãã€ãã¯ã«ãªã£ãŠããmixiãŠãŒã¶ãŒã ããã³ã¡ã³ãã§ããããã«ãªããŸãã
+
+4. ã³ã¡ã³ã
+
+ãã­ã°èšäºã«ã³ã¡ã³ãããéã«ããµã€ã³ã€ã³ããããšãããšããµã€ã³ã€ã³ç»é¢ã§mixiãéžæã§ããŸããéžæããŠãè¡šç€ºããããã¿ã³ãã¯ãªãã¯ããŸããmixiã®ã­ã°ã€ã³ç»é¢ã«ç§»åããã®ã§ãèªåã®ãŠãŒã¶ãŒåãšãã¹ã¯ãŒãã§ã­ã°ã€ã³ããŸããmixiããã®äœ¿çšæ¡ä»¶ãè¡šç€ºãããã®ã§ãåæããã°ãMovable Type 4ã«ãµã€ã³ã€ã³ããããšãã§ããŸãã
+
+ã¹ããã2ã®ãã€ãã¯èªèšŒã®èš­å®ãè¡ã£ãŠããå Žåã«ã¯ããµã€ã³ã€ã³ã§ããã®ã¯ãã€ãã¯ã«ãªã£ãŠãããŠãŒã¶ãŒã ãã§ãããã®å Žåã¯ãããšãmixiã«æ­£ããã­ã°ã€ã³ããŠãããã€ãã¯ã§ãªããã°ãã­ã°ã€ã³ã«å€±æãããšã¿ãªãããŸãã
