dio_tests 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b706dbbce73c864ffbb024b0c8ab4552f4bcfc96
4
+ data.tar.gz: 095fb9deae8866e16bf6f01e185f1c402443243b
5
+ SHA512:
6
+ metadata.gz: c26fdacd4d332a05e756be273d9366cb8db44f38630e184b2033e3fb8c666c1a1fc1657a91602cfa153f90a67e7ed16278c655aae56684e3c6418cdb4f5c1f3b
7
+ data.tar.gz: 45b858941bd891edcb4b673db4c73b4334efc40fe772102cbe178b9fa27d2ac2b1c743c65bffa6facefd4146685b8616f791d7a512848f02d11c48ddf7239713
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor/bundle/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ gemfile:
6
+ - Gemfile
7
+ script: bundle exec rspec
8
+ branches:
9
+ only:
10
+ - master
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dio_tests.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 sue445
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/dio ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/ruby
2
+ require "optparse"
3
+ require "dio_tests"
4
+
5
+ options = {}
6
+ opt = OptionParser.new
7
+
8
+ formats = DioTests::Client.formats.keys.join(",")
9
+ opt.on("-f", "--format=<format>", "supported: #{formats}") do |v|
10
+ options[:format] = v
11
+ end
12
+
13
+ opt.on("-s", "--since=<since-commit>",
14
+ "git log <since-commit>...HEAD (default: master)") do |v|
15
+ options[:since_commit] = v
16
+ end
17
+
18
+ opt.on("-a", "--author=<author-name>",
19
+ "git log --author=<author-name> (default: use 'user.name' in .gitconfig)") do |v|
20
+ options[:author] = v
21
+ end
22
+
23
+ opt.parse!(ARGV)
24
+
25
+ options[:format] = ARGV[0] unless options[:format]
26
+
27
+ begin
28
+ DioTests::Client.new(options).print_test_count
29
+ rescue => e
30
+ puts e.message
31
+ exit 1
32
+ end
33
+
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dio_tests/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dio_tests"
8
+ spec.version = DioTests::VERSION
9
+ spec.authors = ["sue445"]
10
+ spec.email = ["sue445@sue445.net"]
11
+ spec.description = %q{Do you remember how many tests you have written ?}
12
+ spec.summary = %q{count your tests on git-log}
13
+ spec.homepage = "https://github.com/sue445/dio_tests/"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "rspec-parameterized", "~> 0.0.8"
25
+ spec.add_development_dependency "pry"
26
+ spec.add_development_dependency "pry-doc"
27
+ spec.add_development_dependency "spork"
28
+ end
Binary file
@@ -0,0 +1,6 @@
1
+ require "dio_tests/version"
2
+ require "dio_tests/client"
3
+
4
+ module DioTests
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,55 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "yaml"
3
+
4
+ class DioTests::Client
5
+ attr_reader :plus_count, :minus_count
6
+
7
+ def initialize(args={})
8
+ @format = args[:format]
9
+ @since_commit = args[:since_commit] || "master"
10
+ @author = args[:author] || git_config("user.name")
11
+ end
12
+
13
+ def print_test_count
14
+ format_pattern = DioTests::Client.format_pattern(@format)
15
+ log = git_log
16
+
17
+ @plus_count = log.each_line.select{|line| line[0] == "+"}.
18
+ inject(0){|count, line|
19
+ line[0] = ""
20
+ count += 1 if line =~ /#{format_pattern}/
21
+ count
22
+ } || 0
23
+
24
+ @minus_count = log.each_line.select{|line| line[0] == "-"}.
25
+ inject(0){|count, line|
26
+ line[0] = ""
27
+ count += 1 if line =~ /#{format_pattern}/
28
+ count
29
+ } || 0
30
+
31
+ puts "plus=#{@plus_count}, minus=#{@minus_count}, increment=#{@plus_count - @minus_count}"
32
+ end
33
+
34
+ def git_log
35
+ git_log_command = "git log --author=#{@author} --remove-empty --oneline --unified=0 --ignore-all-space #{@since_commit}..HEAD"
36
+ puts git_log_command
37
+ `#{git_log_command}`
38
+ end
39
+
40
+ def git_config(name)
41
+ `git config --get #{name}`.strip
42
+ end
43
+
44
+ def self.format_pattern(format)
45
+ raise "format is require" unless format
46
+
47
+ raise "Not found: #{format} in formats.yml" unless formats[format]
48
+ formats[format]
49
+ end
50
+
51
+ def self.formats
52
+ formats = YAML.load_file("#{File.dirname(__FILE__)}/formats.yml")
53
+ end
54
+ end
55
+
@@ -0,0 +1,4 @@
1
+ junit4: "@(Test|Theory)"
2
+ qunit: "^\\s*test"
3
+ rspec: "^\\s*its?"
4
+
@@ -0,0 +1,3 @@
1
+ module DioTests
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,56 @@
1
+ # DIO Tests [![Build Status](https://travis-ci.org/sue445/dio_tests.png?branch=master)](https://travis-ci.org/sue445/dio_tests)
2
+
3
+ ![お前は今まで書いたテストの個数を覚えているのか?](https://raw.github.com/sue445/dio_tests/master/img/dio.png)
4
+
5
+
6
+ ## Overview
7
+ count test on your git log
8
+
9
+ $ dio_tests rspec
10
+ git log --author=sue445 --remove-empty --oneline --unified=0 --ignore-all-space master..HEAD
11
+ plus=2, minus=0, increment=2
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'dio_tests'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install dio_tests
26
+
27
+ ## Usage
28
+
29
+ ```sh
30
+ Usage: dio <format_type> [options]
31
+ format_type test format(ex. rspec, junit4, qunit)
32
+ -s, --since=SINCE_COMMIT git log <SINCE_COMMIT>...HEAD (default: master)
33
+ -a, --author=AUTHOR_NAME git log --author=<AUTHOR_NAME> (default: use 'user.name' in .gitconfig)
34
+ ```
35
+
36
+ ## Supported
37
+ * Ruby
38
+ * RSpec
39
+ * Java
40
+ * JUnit4
41
+ * JavaScript
42
+ * QUnit
43
+
44
+ ## Required
45
+ * ruby
46
+ * git
47
+
48
+ [![endorse](http://api.coderwall.com/sue445/endorsecount.png)](http://coderwall.com/sue445)
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create new Pull Request
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "spec_helper"
4
+
5
+ describe DioTests::Client do
6
+ def stub_file(format)
7
+ open("./spec/stubs/#{format}.txt").read
8
+ end
9
+
10
+ describe "#print_test_count" do
11
+ subject{ dio.print_test_count }
12
+
13
+ where(:format, :expected_plus_count, :expected_minus_count) do
14
+ [
15
+ ["rspec" , 1 , 0],
16
+ ["junit4", 33, 0],
17
+ ["qunit" , 1 , 0],
18
+ ]
19
+ end
20
+
21
+ with_them do
22
+ before do
23
+ dio.stub!(:git_log).and_return(stub_file(format))
24
+ subject
25
+ end
26
+
27
+ let(:dio) { DioTests::Client.new(:format => format) }
28
+
29
+ it{ expect(dio.plus_count).to eq expected_plus_count }
30
+ it{ expect(dio.minus_count).to eq expected_minus_count }
31
+ end
32
+ end
33
+
34
+ describe "#format_pattern" do
35
+ subject{ DioTests::Client.format_pattern(fotmat) }
36
+
37
+ let(:fotmat){ "junit4" }
38
+
39
+ it{ should == "@(Test|Theory)" }
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'spork'
3
+
4
+ #uncomment the following line to use spork with the debugger
5
+ #require 'spork/ext/ruby-debug'
6
+
7
+ Spork.prefork do
8
+ # Loading more in this block will cause your tests to run faster. However,
9
+ # if you change any configuration or code from libraries loaded here, you'll
10
+ # need to restart spork for it take effect.
11
+
12
+ end
13
+
14
+ Spork.each_run do
15
+ # This code will be run each time you run your specs.
16
+
17
+ require 'rspec'
18
+ require 'rspec-parameterized'
19
+ require 'dio_tests'
20
+ require 'pry'
21
+
22
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
23
+
24
+ # Requires supporting files with custom matchers and macros, etc,
25
+ # in ./support/ and its subdirectories.
26
+ Dir["#{File.dirname(__FILE__)}/../lib/dio_tests/**/*.rb"].each {|f| require f}
27
+
28
+ RSpec.configure do |config|
29
+ end
30
+ end
31
+
32
+ # --- Instructions ---
33
+ # Sort the contents of this file into a Spork.prefork and a Spork.each_run
34
+ # block.
35
+ #
36
+ # The Spork.prefork block is run only once when the spork server is started.
37
+ # You typically want to place most of your (slow) initializer code in here, in
38
+ # particular, require'ing any 3rd-party gems that you don't normally modify
39
+ # during development.
40
+ #
41
+ # The Spork.each_run block is run each time you run your specs. In case you
42
+ # need to load files that tend to change during development, require them here.
43
+ # With Rails, your application modules are loaded automatically, so sometimes
44
+ # this block can remain empty.
45
+ #
46
+ # Note: You can modify files loaded *from* the Spork.each_run block without
47
+ # restarting the spork server. However, this file itself will not be reloaded,
48
+ # so if you change any of the code inside the each_run block, you still need to
49
+ # restart the server. In general, if you have non-trivial code in this file,
50
+ # it's advisable to move it into a separate file so you can easily edit it
51
+ # without restarting spork. (For example, with RSpec, you could move
52
+ # non-trivial code into a file spec/support/my_helper.rb, making sure that the
53
+ # spec/support/* files are require'd from inside the each_run block.)
54
+ #
55
+ # Any code that is left outside the two blocks will be run during preforking
56
+ # *and* during each_run -- that's probably not what you want.
57
+ #
58
+ # These instructions should self-destruct in 10 seconds. If they don't, feel
59
+
60
+ # free to delete them.
@@ -0,0 +1,2715 @@
1
+ 3a72fdc impl Twitter login home
2
+ diff --git a/eclipse.lib/scenic3-0.5.1.jar b/eclipse.lib/scenic3-0.5.1.jar
3
+ new file mode 100644
4
+ index 0000000..3d65267
5
+ Binary files /dev/null and b/eclipse.lib/scenic3-0.5.1.jar differ
6
+ diff --git a/pom.xml b/pom.xml
7
+ index 809997e..4593a77 100644
8
+ --- a/pom.xml
9
+ +++ b/pom.xml
10
+ @@ -13 +13,3 @@
11
+ - <twitter4j.version>2.2.5</twitter4j.version>
12
+ + <twitter4j.version>2.2.6</twitter4j.version>
13
+ + <scenic3.version>0.5.1</scenic3.version>
14
+ + <slim3.rootPackage>net.sue445.azusaar</slim3.rootPackage>
15
+ @@ -41,0 +44,9 @@
16
+ + <repository>
17
+ + <id>maven.deathmarch.jp</id>
18
+ + <name>The Deathmarch Maven2 Repository</name>
19
+ + <url>http://maven.deathmarch.jp/maven2</url>
20
+ + <snapshots>
21
+ + <enabled>true</enabled>
22
+ + <updatePolicy>always</updatePolicy>
23
+ + </snapshots>
24
+ + </repository>
25
+ @@ -104,0 +116,5 @@
26
+ + <groupId>jstl</groupId>
27
+ + <artifactId>jstl</artifactId>
28
+ + <version>1.2</version>
29
+ + </dependency>
30
+ + <dependency>
31
+ @@ -189,0 +206,5 @@
32
+ + <dependency>
33
+ + <groupId>scenic3</groupId>
34
+ + <artifactId>scenic3</artifactId>
35
+ + <version>${scenic3.version}</version>
36
+ + </dependency>
37
+ @@ -248,0 +270,3 @@
38
+ + <options>
39
+ + <option>slim3.rootPackage=${slim3.rootPackage}</option>
40
+ + </options>
41
+ @@ -284 +308 @@
42
+ - <includeArtifactIds>slim3-gen</includeArtifactIds>
43
+ + <includeArtifactIds>slim3-gen,scenic3</includeArtifactIds>
44
+ @@ -351,0 +376 @@
45
+ + <factorypathentry kind="WKSPJAR" id="/${artifactId}/${eclipse.lib}/scenic3-${scenic3.version}.jar" enabled="true" runInBatchMode="false"/>
46
+ diff --git a/src/main/java/net/sue445/azusaar/controller/AppUrls.java b/src/main/java/net/sue445/azusaar/controller/AppUrls.java
47
+ new file mode 100644
48
+ index 0000000..a9f9eb1
49
+ --- /dev/null
50
+ +++ b/src/main/java/net/sue445/azusaar/controller/AppUrls.java
51
+ @@ -0,0 +1,35 @@
52
+ +package net.sue445.azusaar.controller;
53
+ +
54
+ +import net.sue445.azusaar.controller.matcher.HomePageMatcher;
55
+ +import scenic3.UrlsImpl;
56
+ +
57
+ +/**
58
+ + * Scenic3でアプリケーションに利用するPageクラスを設定します。
59
+ + *
60
+ + * @author shuji.w6e
61
+ + */
62
+ +public class AppUrls extends UrlsImpl {
63
+ +
64
+ + public AppUrls() {
65
+ + excludes(
66
+ + "/*.png",
67
+ + "/*.ico",
68
+ + "/*.txt",
69
+ + "/*.xml",
70
+ + "/*.html",
71
+ +
72
+ + "/_ah/*",
73
+ + "/admin/*",
74
+ + "/cn/*",
75
+ + "/css/*",
76
+ + "/img/*",
77
+ + "/js/*",
78
+ + "/ktrwjr/*",
79
+ + "/smart/*"
80
+ + );
81
+ +
82
+ + // TODO Pageを追加したらこっちも追加する
83
+ + add(HomePageMatcher.get()); // /home
84
+ + }
85
+ +
86
+ +}
87
+
88
+ diff --git a/src/main/java/net/sue445/azusaar/controller/auth/CallbackController.java b/src/main/java/net/sue445/azusaar/controller/auth/CallbackController.java
89
+ new file mode 100644
90
+ index 0000000..8629d70
91
+ --- /dev/null
92
+ +++ b/src/main/java/net/sue445/azusaar/controller/auth/CallbackController.java
93
+ @@ -0,0 +1,66 @@
94
+ +package net.sue445.azusaar.controller.auth;
95
+ +
96
+ +import net.sue445.azusaar.dao.UserDao;
97
+ +import net.sue445.azusaar.model.UserModel;
98
+ +import net.sue445.azusaar.util.SessionUtil;
99
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
100
+ +import net.sue445.azusaar.util.TwitterUtil;
101
+ +import net.sue445.common.logging.Jdk14LogFactory;
102
+ +import net.sue445.common.logging.Log;
103
+ +
104
+ +import org.slim3.controller.Controller;
105
+ +import org.slim3.controller.Navigation;
106
+ +
107
+ +import twitter4j.Twitter;
108
+ +import twitter4j.TwitterException;
109
+ +import twitter4j.auth.AccessToken;
110
+ +import twitter4j.auth.RequestToken;
111
+ +
112
+ +public class CallbackController extends Controller {
113
+ + private static final Log log = Jdk14LogFactory.getLogger(CallbackController.class);
114
+ +
115
+ + private final UserDao userDao = new UserDao();
116
+ +
117
+ + // package private
118
+ + static AccessToken mockAccessToken = null;
119
+ +
120
+ + @Override
121
+ + public Navigation run() throws Exception {
122
+ + AccessToken accessToken = getAccessToken();
123
+ + long userId = accessToken.getUserId();
124
+ +
125
+ + UserModel userModel = userDao.getOrNew(userId);
126
+ + userModel.setScreenName(accessToken.getScreenName());
127
+ + userModel.setAccessToken(accessToken.getToken());
128
+ + userModel.setAccessTokenSecret(accessToken.getTokenSecret());
129
+ + userDao.put(userModel);
130
+ +
131
+ + // indexに反映させるため1回getする
132
+ + userDao.getOrNull(userId);
133
+ +
134
+ + SessionUtil.remove(request, SessionKey.REQUEST_TOKEN);
135
+ + SessionUtil.put(request, SessionKey.ACCESS_TOKEN, accessToken);
136
+ +
137
+ + log.info("save accessToken success: " + accessToken);
138
+ +
139
+ + if(userModel.getVersion() == 1){
140
+ + // 未登録
141
+ + return redirect("/home/");
142
+ + }
143
+ +
144
+ + // 登録済
145
+ + return redirect("/");
146
+ + }
147
+ +
148
+ + private AccessToken getAccessToken() throws TwitterException {
149
+ + if(mockAccessToken != null){
150
+ + return mockAccessToken;
151
+ + }
152
+ +
153
+ + String oauthVerifier = asString("oauth_verifier");
154
+ + RequestToken requestToken = SessionUtil.get(request, SessionKey.REQUEST_TOKEN);
155
+ +
156
+ + Twitter twitter = TwitterUtil.getTwitter();
157
+ + return twitter.getOAuthAccessToken(requestToken, oauthVerifier);
158
+ + }
159
+ +}
160
+ diff --git a/src/main/java/net/sue445/azusaar/controller/auth/LogoutController.java b/src/main/java/net/sue445/azusaar/controller/auth/LogoutController.java
161
+ new file mode 100644
162
+ index 0000000..012bc5f
163
+ --- /dev/null
164
+ +++ b/src/main/java/net/sue445/azusaar/controller/auth/LogoutController.java
165
+ @@ -0,0 +1,52 @@
166
+ +package net.sue445.azusaar.controller.auth;
167
+ +
168
+ +import javax.servlet.http.Cookie;
169
+ +
170
+ +import net.sue445.azusaar.dao.UserDao;
171
+ +import net.sue445.azusaar.model.UserModel;
172
+ +import net.sue445.azusaar.util.CookieUtil;
173
+ +import net.sue445.azusaar.util.SessionUtil;
174
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
175
+ +import net.sue445.common.logging.Jdk14LogFactory;
176
+ +import net.sue445.common.logging.Log;
177
+ +
178
+ +import org.slim3.controller.Controller;
179
+ +import org.slim3.controller.Navigation;
180
+ +
181
+ +public class LogoutController extends Controller {
182
+ + private static final Log log = Jdk14LogFactory.getLogger(LogoutController.class);
183
+ +
184
+ + private final UserDao userDao = new UserDao();
185
+ +
186
+ + @Override
187
+ + public Navigation run() throws Exception {
188
+ + UserModel currentUser = userDao.getCurrentUser(request, response);
189
+ + if(currentUser == null){
190
+ + log.debug("not logined");
191
+ + return redirect("/");
192
+ + }
193
+ +
194
+ + currentUser.setAccessToken(null);
195
+ + currentUser.setAccessTokenSecret(null);
196
+ + userDao.put(currentUser);
197
+ +
198
+ + SessionUtil.remove(request, SessionKey.ACCESS_TOKEN);
199
+ +
200
+ + addNoExpiryCookie(CookieUtil.ACCESS_TOKEN);
201
+ + addNoExpiryCookie(CookieUtil.ACCESS_TOKEN_SECRET);
202
+ +
203
+ + log.info("logout success:" + currentUser.getKey());
204
+ +
205
+ + return redirect("/");
206
+ + }
207
+ +
208
+ + /**
209
+ + * ブラウザでcookieを削除させるため、有効期限0秒のcookieをレスポンスに出力する
210
+ + * @param name
211
+ + */
212
+ + private void addNoExpiryCookie(String name) {
213
+ + Cookie cookie = new Cookie(name, "");
214
+ + cookie.setMaxAge(0);
215
+ + response.addCookie(cookie);
216
+ + }
217
+ +}
218
+ diff --git a/src/main/java/net/sue445/azusaar/controller/auth/UserInfoController.java b/src/main/java/net/sue445/azusaar/controller/auth/UserInfoController.java
219
+ new file mode 100644
220
+ index 0000000..ce8a826
221
+ --- /dev/null
222
+ +++ b/src/main/java/net/sue445/azusaar/controller/auth/UserInfoController.java
223
+ @@ -0,0 +1,43 @@
224
+ +package net.sue445.azusaar.controller.auth;
225
+ +
226
+ +import java.io.IOException;
227
+ +import java.util.LinkedHashMap;
228
+ +import java.util.Map;
229
+ +
230
+ +import net.sue445.azusaar.controller.AbstractApiController;
231
+ +import net.sue445.azusaar.dao.UserDao;
232
+ +import net.sue445.azusaar.dto.json.UserInfoDto;
233
+ +import net.sue445.azusaar.model.UserModel;
234
+ +
235
+ +import org.slim3.controller.Navigation;
236
+ +
237
+ +public class UserInfoController extends AbstractApiController {
238
+ + private final UserDao userDao = new UserDao();
239
+ +
240
+ + @Override
241
+ + public Navigation run() throws Exception {
242
+ + UserModel currentUser = userDao.getCurrentUser(request, response);
243
+ + if(currentUser != null){
244
+ + return responseLogined(currentUser);
245
+ + }
246
+ +
247
+ + // Twitter未ログイン
248
+ + Map<String,String> map = new LinkedHashMap<String, String>();
249
+ +
250
+ + String jsonContent = toJsonContent(map);
251
+ + return responseJson(toJsonp(jsonContent));
252
+ + }
253
+ +
254
+ + private Navigation responseLogined(UserModel model) throws IOException {
255
+ + UserInfoDto dto = new UserInfoDto();
256
+ + dto.screenName = model.getScreenName();
257
+ + dto.atndId = model.getAtndId();
258
+ + dto.connpassId = model.getConnpassId();
259
+ + dto.eventAtndId = model.getEventAtndId();
260
+ + dto.partakeId = model.getPartakeId();
261
+ + dto.zusaarId = model.getZusaarId();
262
+ +
263
+ + String jsonContent = toJsonContent(dto);
264
+ + return responseJson(toJsonp(jsonContent));
265
+ + }
266
+ +}
267
+ diff --git a/src/main/java/net/sue445/azusaar/dao/UserDao.java b/src/main/java/net/sue445/azusaar/dao/UserDao.java
268
+ new file mode 100644
269
+ index 0000000..e7d3bf2
270
+ --- /dev/null
271
+ +++ b/src/main/java/net/sue445/azusaar/dao/UserDao.java
272
+ @@ -0,0 +1,136 @@
273
+ +package net.sue445.azusaar.dao;
274
+ +
275
+ +import javax.servlet.http.Cookie;
276
+ +import javax.servlet.http.HttpServletRequest;
277
+ +import javax.servlet.http.HttpServletResponse;
278
+ +
279
+ +import net.sue445.azusaar.meta.UserModelMeta;
280
+ +import net.sue445.azusaar.model.UserModel;
281
+ +import net.sue445.azusaar.util.CookieUtil;
282
+ +import net.sue445.azusaar.util.SessionUtil;
283
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
284
+ +
285
+ +import org.apache.commons.lang.StringUtils;
286
+ +import org.apache.commons.lang.time.DateUtils;
287
+ +import org.slim3.datastore.DaoBase;
288
+ +
289
+ +import twitter4j.auth.AccessToken;
290
+ +
291
+ +import com.google.appengine.api.datastore.Key;
292
+ +
293
+ +public class UserDao extends DaoBase<UserModel>{
294
+ +
295
+ + /**
296
+ + *
297
+ + * @param mailAddress
298
+ + * @return
299
+ + */
300
+ + public UserModel getOrNull(long twitterUserId){
301
+ + Key key = UserModel.createKey(twitterUserId);
302
+ + return super.getOrNull(key);
303
+ + }
304
+ +
305
+ + /**
306
+ + * tokenでユーザ検索する
307
+ + * @param accessToken
308
+ + * @param accessTokenSecret
309
+ + * @return 見つからなければnullを返す
310
+ + */
311
+ + public UserModel findByOAuth(String accessToken, String accessTokenSecret){
312
+ + if(StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(accessTokenSecret)){
313
+ + return null;
314
+ + }
315
+ +
316
+ + UserModelMeta e = UserModelMeta.get();
317
+ + return query().filter(e.accessToken.equal(accessToken), e.accessTokenSecret.equal(accessTokenSecret)).asSingle();
318
+ + }
319
+ +
320
+ + /**
321
+ + *
322
+ + * @param twitterUserId
323
+ + * @return
324
+ + */
325
+ + public UserModel getOrNew(long twitterUserId){
326
+ + UserModel user = getOrNull(twitterUserId);
327
+ + if(user != null){
328
+ + return user;
329
+ + }
330
+ +
331
+ + return new UserModel(twitterUserId);
332
+ + }
333
+ +
334
+ + /**
335
+ + * <ul>
336
+ + * <li>ParamにaccessTokenとaccessTokenSecretがあればそれを元に {@link UserModel} を取得</li>
337
+ + * <li>CookieにaccessTokenとaccessTokenSecretがあればそれを元に {@link UserModel} を取得</li>
338
+ + * <li>Sessionに{@link AccessToken} があればそれを元に {@link UserModel} を取得し、cookieにaccessTokenとaccessTokenSecretを書き出す</li>
339
+ + * </ul>
340
+ + * @param request
341
+ + * @param response
342
+ + * @return cookieとsessionのどっちにもなければnullを返す
343
+ + */
344
+ + public UserModel getCurrentUser(HttpServletRequest request, HttpServletResponse response){
345
+ + UserModel paramUser = getUserWithParam(request);
346
+ + if(paramUser != null){
347
+ + return paramUser;
348
+ + }
349
+ +
350
+ + UserModel cookieUser = getUserWithCookie(request);
351
+ + if(cookieUser != null){
352
+ + return cookieUser;
353
+ + }
354
+ +
355
+ + UserModel sessionUser = getUserWithSession(request);
356
+ + if(sessionUser != null){
357
+ + response.addCookie(createCookie(CookieUtil.ACCESS_TOKEN, sessionUser.getAccessToken()));
358
+ + response.addCookie(createCookie(CookieUtil.ACCESS_TOKEN_SECRET, sessionUser.getAccessTokenSecret()));
359
+ + return sessionUser;
360
+ + }
361
+ +
362
+ + return null;
363
+ + }
364
+ +
365
+ + /**
366
+ + *
367
+ + * @param request
368
+ + * @return
369
+ + */
370
+ + private UserModel getUserWithParam(HttpServletRequest request){
371
+ + String accessToken = request.getParameter(CookieUtil.ACCESS_TOKEN);
372
+ + String accessTokenSecret = request.getParameter(CookieUtil.ACCESS_TOKEN_SECRET);
373
+ +
374
+ + return findByOAuth(accessToken, accessTokenSecret);
375
+ + }
376
+ +
377
+ + /**
378
+ + *
379
+ + * @param request
380
+ + * @return
381
+ + */
382
+ + private UserModel getUserWithCookie(HttpServletRequest request){
383
+ + String accessToken = CookieUtil.findValue(request.getCookies(), CookieUtil.ACCESS_TOKEN);
384
+ + String accessTokenSecret = CookieUtil.findValue(request.getCookies(), CookieUtil.ACCESS_TOKEN_SECRET);
385
+ +
386
+ + return findByOAuth(accessToken, accessTokenSecret);
387
+ + }
388
+ +
389
+ + /**
390
+ + *
391
+ + * @param request
392
+ + * @return
393
+ + */
394
+ + private UserModel getUserWithSession(HttpServletRequest request){
395
+ + AccessToken accessToken = SessionUtil.get(request, SessionKey.ACCESS_TOKEN);
396
+ + if(accessToken == null){
397
+ + return null;
398
+ + }
399
+ +
400
+ + return findByOAuth(accessToken.getToken(), accessToken.getTokenSecret());
401
+ + }
402
+ +
403
+ + private Cookie createCookie(String name, String value) {
404
+ + Cookie cookie = new Cookie(name, value);
405
+ + cookie.setMaxAge((int) DateUtils.MILLIS_PER_DAY / 1000 * 30);
406
+ + return cookie;
407
+ + }
408
+ +}
409
+ diff --git a/src/main/java/net/sue445/azusaar/dao/UserProxyDao.java b/src/main/java/net/sue445/azusaar/dao/UserProxyDao.java
410
+ new file mode 100644
411
+ index 0000000..c993a54
412
+ --- /dev/null
413
+ +++ b/src/main/java/net/sue445/azusaar/dao/UserProxyDao.java
414
+ @@ -0,0 +1,113 @@
415
+ +package net.sue445.azusaar.dao;
416
+ +
417
+ +import net.sue445.azusaar.model.UserModel;
418
+ +import net.sue445.azusaar.util.TwitterUtil;
419
+ +import net.sue445.common.logging.Jdk14LogFactory;
420
+ +import net.sue445.common.logging.Log;
421
+ +import net.sue445.kulib.util.MemcacheUtil;
422
+ +
423
+ +import org.apache.commons.lang.StringUtils;
424
+ +import org.slim3.memcache.Memcache;
425
+ +
426
+ +import twitter4j.Twitter;
427
+ +
428
+ +import com.google.appengine.api.datastore.Key;
429
+ +
430
+ +public class UserProxyDao {
431
+ + private static final Log log = Jdk14LogFactory.getLogger(UserProxyDao.class);
432
+ +
433
+ + /**
434
+ + * 直前にMemcacheからレスポンスを取得したかどうか(テスト用)
435
+ + */
436
+ + // package private
437
+ + boolean wasMemcacheResponse = false;
438
+ +
439
+ + /**
440
+ + *
441
+ + * @param accessToken
442
+ + * @param accessTokenSecret
443
+ + * @return {@link UserModel} のkey
444
+ + */
445
+ + public Key get(String accessToken, String accessTokenSecret){
446
+ + wasMemcacheResponse = false;
447
+ +
448
+ + if(StringUtils.isBlank(accessToken) || StringUtils.isBlank(accessTokenSecret)){
449
+ + return null;
450
+ + }
451
+ +
452
+ + Key key = getFromMemcache(accessToken, accessTokenSecret);
453
+ + if(key != null){
454
+ + wasMemcacheResponse = true;
455
+ + return key;
456
+ + }
457
+ +
458
+ + // tokenが無効だったらcallbackから再度取得させる
459
+ + if(!verifyCredentials(accessToken, accessTokenSecret)){
460
+ + return null;
461
+ + }
462
+ +
463
+ + return getFromDatastore(accessToken, accessTokenSecret);
464
+ + }
465
+ +
466
+ + private boolean verifyCredentials(String accessToken, String accessTokenSecret) {
467
+ + try {
468
+ + Twitter twitter = TwitterUtil.getTwitter(accessToken, accessTokenSecret);
469
+ + twitter.verifyCredentials();
470
+ + return true;
471
+ + } catch (Exception e) {
472
+ + log.warn("can not verifyCredentials", e);
473
+ + return false;
474
+ + }
475
+ + }
476
+ +
477
+ + /**
478
+ + *
479
+ + * @param accessToken
480
+ + * @param accessTokenSecret
481
+ + * @return
482
+ + */
483
+ + private Key getFromMemcache(String accessToken, String accessTokenSecret) {
484
+ + String memcacheKey = createMemcacheKey(accessToken, accessTokenSecret);
485
+ + return Memcache.<Key>get(memcacheKey);
486
+ + }
487
+ +
488
+ + /**
489
+ + *
490
+ + * @param accessToken
491
+ + * @param accessTokenSecret
492
+ + * @return
493
+ + */
494
+ + private String createMemcacheKey(String accessToken, String accessTokenSecret) {
495
+ + return MemcacheUtil.createKeyPrefix(UserProxyDao.class) + accessToken + "_" + accessTokenSecret;
496
+ + }
497
+ +
498
+ + /**
499
+ + *
500
+ + * @param accessToken
501
+ + * @param accessTokenSecret
502
+ + * @return
503
+ + */
504
+ + private Key getFromDatastore(String accessToken, String accessTokenSecret) {
505
+ + UserDao userDao = new UserDao();
506
+ + UserModel userModel = userDao.findByOAuth(accessToken, accessTokenSecret);
507
+ + if(userModel == null){
508
+ + return null;
509
+ + }
510
+ +
511
+ + String memcacheKey = createMemcacheKey(accessToken, accessTokenSecret);
512
+ + Memcache.put(memcacheKey, userModel.getKey());
513
+ +
514
+ + return userModel.getKey();
515
+ + }
516
+ +
517
+ + /**
518
+ + * アクセストークンが有効かどうか
519
+ + * @param accessToken
520
+ + * @param accessTokenSecret
521
+ + * @return
522
+ + */
523
+ + public boolean isValidAccessToken(String accessToken, String accessTokenSecret){
524
+ + return get(accessToken, accessTokenSecret) != null;
525
+ + }
526
+ +
527
+ +}
528
+ diff --git a/src/main/java/net/sue445/azusaar/dto/json/UserInfoDto.java b/src/main/java/net/sue445/azusaar/dto/json/UserInfoDto.java
529
+ new file mode 100644
530
+ index 0000000..3d19769
531
+ --- /dev/null
532
+ +++ b/src/main/java/net/sue445/azusaar/dto/json/UserInfoDto.java
533
+ @@ -0,0 +1,21 @@
534
+ +package net.sue445.azusaar.dto.json;
535
+ +
536
+ +import net.arnx.jsonic.JSONHint;
537
+ +
538
+ +
539
+ +
540
+ +public class UserInfoDto {
541
+ + public String screenName = "";
542
+ +
543
+ + @JSONHint(ignore = true)
544
+ + public String atndId = "";
545
+ +
546
+ + @JSONHint(ignore = true)
547
+ + public String eventAtndId = "";
548
+ +
549
+ + public String zusaarId = "";
550
+ +
551
+ + public String partakeId = "";
552
+ +
553
+ + public String connpassId = "";
554
+ +}
555
+ diff --git a/src/main/java/net/sue445/azusaar/enums/OAuthConsumerKey.java b/src/main/java/net/sue445/azusaar/enums/OAuthConsumerKey.java
556
+ new file mode 100644
557
+ index 0000000..7befaf8
558
+ --- /dev/null
559
+ +++ b/src/main/java/net/sue445/azusaar/enums/OAuthConsumerKey.java
560
+ @@ -0,0 +1,45 @@
561
+ +package net.sue445.azusaar.enums;
562
+ +
563
+ +import org.slim3.util.AppEngineUtil;
564
+ +
565
+ +/**
566
+ + * Consumer KeyとConsumer Secretのペアを管理する列挙体
567
+ + * @author sue445
568
+ + *
569
+ + */
570
+ +public enum OAuthConsumerKey {
571
+ + /**
572
+ + * 開発環境用
573
+ + */
574
+ + DEVELOPMENT("1DLP15qMhRakb9svitB0PA", "WqGJ3SL77s3Bk8XddJMJebUXFtdsZuBPgeXwcSRsl8"),
575
+ +
576
+ + /**
577
+ + * 本番環境用
578
+ + */
579
+ + PRODUCTION( "ez3X2tsu5wB8szXU8kL5qw", "4m3olY0e25ELhJPxrt48mIQ0fMhZ7UH6LeFhaVY"),
580
+ + ;
581
+ +
582
+ +
583
+ + private OAuthConsumerKey(String consumerKey, String consumerSecret){
584
+ + this.consumerKey = consumerKey;
585
+ + this.consumerSecret = consumerSecret;
586
+ + }
587
+ +
588
+ + public final String consumerKey;
589
+ +
590
+ + public final String consumerSecret;
591
+ +
592
+ +
593
+ + /**
594
+ + * 開発環境か本番環境かで返却するKeyを振り分ける
595
+ + * @return
596
+ + */
597
+ + public static OAuthConsumerKey getCurrentKey(){
598
+ + if(AppEngineUtil.isProduction()){
599
+ + return PRODUCTION;
600
+ + }
601
+ +
602
+ + return DEVELOPMENT;
603
+ + }
604
+ +
605
+ +}
606
+ diff --git a/src/main/java/net/sue445/azusaar/filter/TwitterOAuthFilter.java b/src/main/java/net/sue445/azusaar/filter/TwitterOAuthFilter.java
607
+ new file mode 100644
608
+ index 0000000..51f3bb4
609
+ --- /dev/null
610
+ +++ b/src/main/java/net/sue445/azusaar/filter/TwitterOAuthFilter.java
611
+ @@ -0,0 +1,64 @@
612
+ +package net.sue445.azusaar.filter;
613
+ +
614
+ +import java.io.IOException;
615
+ +
616
+ +import javax.servlet.Filter;
617
+ +import javax.servlet.FilterChain;
618
+ +import javax.servlet.FilterConfig;
619
+ +import javax.servlet.ServletException;
620
+ +import javax.servlet.ServletRequest;
621
+ +import javax.servlet.ServletResponse;
622
+ +import javax.servlet.http.HttpServletRequest;
623
+ +import javax.servlet.http.HttpServletResponse;
624
+ +
625
+ +import net.sue445.azusaar.dao.UserDao;
626
+ +import net.sue445.azusaar.model.UserModel;
627
+ +import net.sue445.azusaar.util.SessionUtil;
628
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
629
+ +import net.sue445.azusaar.util.TwitterUtil;
630
+ +import twitter4j.Twitter;
631
+ +import twitter4j.TwitterException;
632
+ +import twitter4j.auth.RequestToken;
633
+ +
634
+ +public class TwitterOAuthFilter implements Filter{
635
+ + private final UserDao userDao = new UserDao();
636
+ +
637
+ +
638
+ + @Override
639
+ + public void init(FilterConfig filterConfig) throws ServletException {
640
+ + }
641
+ +
642
+ + @Override
643
+ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
644
+ + doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);
645
+ + }
646
+ +
647
+ + public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
648
+ + UserModel currentUser = userDao.getCurrentUser(request, response);
649
+ +
650
+ + if(currentUser != null && currentUser.isValidTwitterAccount()){
651
+ + // Twitterの認証が正常取得できたので処理を続行する
652
+ + chain.doFilter(request, response);
653
+ + return;
654
+ + }
655
+ +
656
+ + // Twitterのログインにリダイレクトする
657
+ + try {
658
+ + Twitter twitter = TwitterUtil.getTwitter();
659
+ + RequestToken requestToken = twitter.getOAuthRequestToken();
660
+ + String twitterLoginUrl = requestToken.getAuthenticationURL();
661
+ + SessionUtil.put(request, SessionKey.REQUEST_TOKEN, requestToken);
662
+ +
663
+ + response.sendRedirect(twitterLoginUrl);
664
+ +
665
+ + } catch (TwitterException e) {
666
+ + response.setStatus(e.getStatusCode());
667
+ + throw new ServletException("can not auth twitter", e);
668
+ + }
669
+ + }
670
+ +
671
+ + @Override
672
+ + public void destroy() {
673
+ + }
674
+ +
675
+ +}
676
+ diff --git a/src/main/java/net/sue445/azusaar/model/UserModel.java b/src/main/java/net/sue445/azusaar/model/UserModel.java
677
+ new file mode 100644
678
+ index 0000000..a170a7b
679
+ --- /dev/null
680
+ +++ b/src/main/java/net/sue445/azusaar/model/UserModel.java
681
+ @@ -0,0 +1,308 @@
682
+ +package net.sue445.azusaar.model;
683
+ +
684
+ +import java.io.Serializable;
685
+ +import java.util.Date;
686
+ +
687
+ +import net.sue445.azusaar.dao.UserProxyDao;
688
+ +import net.sue445.azusaar.util.TwitterUtil;
689
+ +
690
+ +import org.slim3.datastore.Attribute;
691
+ +import org.slim3.datastore.CreationDate;
692
+ +import org.slim3.datastore.Datastore;
693
+ +import org.slim3.datastore.Model;
694
+ +import org.slim3.datastore.ModificationDate;
695
+ +import org.slim3.datastore.json.Json;
696
+ +
697
+ +import twitter4j.Twitter;
698
+ +
699
+ +import com.google.appengine.api.datastore.Key;
700
+ +
701
+ +@Model(kind = "User", schemaVersion = 1)
702
+ +public class UserModel implements Serializable {
703
+ + private static final long serialVersionUID = 1L;
704
+ +
705
+ + @Json(ignore = true)
706
+ + @Attribute(primaryKey = true)
707
+ + private Key key;
708
+ +
709
+ + @Attribute(unindexed = true, version = true)
710
+ + private Long version;
711
+ +
712
+ + @Attribute(listener = CreationDate.class)
713
+ + private Date createdAt;
714
+ +
715
+ + @Attribute(listener = ModificationDate.class)
716
+ + private Date updatedAt;
717
+ +
718
+ + private String screenName;
719
+ +
720
+ + @Attribute(unindexed = true)
721
+ + private String atndId = "";
722
+ +
723
+ + @Attribute(unindexed = true)
724
+ + private String eventAtndId = "";
725
+ +
726
+ + @Attribute(unindexed = true)
727
+ + private String zusaarId = "";
728
+ +
729
+ + @Attribute(unindexed = true)
730
+ + private String partakeId = "";
731
+ +
732
+ + @Attribute(unindexed = true)
733
+ + private String connpassId = "";
734
+ +
735
+ + private String accessToken;
736
+ +
737
+ + private String accessTokenSecret;
738
+ +
739
+ +
740
+ + public UserModel(){
741
+ +
742
+ + }
743
+ +
744
+ + public UserModel(long twitterUserId){
745
+ + this.key = createKey(twitterUserId);
746
+ + }
747
+ +
748
+ + public static Key createKey(long twitterUserId){
749
+ + return Datastore.createKey(UserModel.class, twitterUserId);
750
+ + }
751
+ +
752
+ + /**
753
+ + * Returns the key.
754
+ + *
755
+ + * @return the key
756
+ + */
757
+ + public Key getKey() {
758
+ + return key;
759
+ + }
760
+ +
761
+ + /**
762
+ + * Sets the key.
763
+ + *
764
+ + * @param key
765
+ + * the key
766
+ + */
767
+ + public void setKey(Key key) {
768
+ + this.key = key;
769
+ + }
770
+ +
771
+ + /**
772
+ + * Returns the version.
773
+ + *
774
+ + * @return the version
775
+ + */
776
+ + public Long getVersion() {
777
+ + return version;
778
+ + }
779
+ +
780
+ + /**
781
+ + * Sets the version.
782
+ + *
783
+ + * @param version
784
+ + * the version
785
+ + */
786
+ + public void setVersion(Long version) {
787
+ + this.version = version;
788
+ + }
789
+ +
790
+ + @Override
791
+ + public int hashCode() {
792
+ + final int prime = 31;
793
+ + int result = 1;
794
+ + result = prime * result + ((key == null) ? 0 : key.hashCode());
795
+ + return result;
796
+ + }
797
+ +
798
+ + @Override
799
+ + public boolean equals(Object obj) {
800
+ + if (this == obj) {
801
+ + return true;
802
+ + }
803
+ + if (obj == null) {
804
+ + return false;
805
+ + }
806
+ + if (getClass() != obj.getClass()) {
807
+ + return false;
808
+ + }
809
+ + UserModel other = (UserModel) obj;
810
+ + if (key == null) {
811
+ + if (other.key != null) {
812
+ + return false;
813
+ + }
814
+ + } else if (!key.equals(other.key)) {
815
+ + return false;
816
+ + }
817
+ + return true;
818
+ + }
819
+ +
820
+ + /**
821
+ + * @return the createdAt
822
+ + */
823
+ + public Date getCreatedAt() {
824
+ + return createdAt;
825
+ + }
826
+ +
827
+ + /**
828
+ + * @param createdAt the createdAt to set
829
+ + */
830
+ + public void setCreatedAt(Date createdAt) {
831
+ + this.createdAt = createdAt;
832
+ + }
833
+ +
834
+ + /**
835
+ + * @return the updatedAt
836
+ + */
837
+ + public Date getUpdatedAt() {
838
+ + return updatedAt;
839
+ + }
840
+ +
841
+ + /**
842
+ + * @param updatedAt the updatedAt to set
843
+ + */
844
+ + public void setUpdatedAt(Date updatedAt) {
845
+ + this.updatedAt = updatedAt;
846
+ + }
847
+ +
848
+ + /**
849
+ + * @return the atndId
850
+ + */
851
+ + public String getAtndId() {
852
+ + return atndId;
853
+ + }
854
+ +
855
+ + /**
856
+ + * @param atndId the atndId to set
857
+ + */
858
+ + public void setAtndId(String atndId) {
859
+ + this.atndId = atndId;
860
+ + }
861
+ +
862
+ + /**
863
+ + * @return the eventAtndId
864
+ + */
865
+ + public String getEventAtndId() {
866
+ + return eventAtndId;
867
+ + }
868
+ +
869
+ + /**
870
+ + * @param eventAtndId the eventAtndId to set
871
+ + */
872
+ + public void setEventAtndId(String eventAtndId) {
873
+ + this.eventAtndId = eventAtndId;
874
+ + }
875
+ +
876
+ + /**
877
+ + * @return the zusaarId
878
+ + */
879
+ + public String getZusaarId() {
880
+ + return zusaarId;
881
+ + }
882
+ +
883
+ + /**
884
+ + * @param zusaarId the zusaarId to set
885
+ + */
886
+ + public void setZusaarId(String zusaarId) {
887
+ + this.zusaarId = zusaarId;
888
+ + }
889
+ +
890
+ + /**
891
+ + * @return the partakeId
892
+ + */
893
+ + public String getPartakeId() {
894
+ + return partakeId;
895
+ + }
896
+ +
897
+ + /**
898
+ + * @param partakeId the partakeId to set
899
+ + */
900
+ + public void setPartakeId(String partakeId) {
901
+ + this.partakeId = partakeId;
902
+ + }
903
+ +
904
+ + /**
905
+ + * @return the connpassId
906
+ + */
907
+ + public String getConnpassId() {
908
+ + return connpassId;
909
+ + }
910
+ +
911
+ + /**
912
+ + * @param connpassId the connpassId to set
913
+ + */
914
+ + public void setConnpassId(String connpassId) {
915
+ + this.connpassId = connpassId;
916
+ + }
917
+ +
918
+ + /**
919
+ + * @return the accessToken
920
+ + */
921
+ + public String getAccessToken() {
922
+ + return accessToken;
923
+ + }
924
+ +
925
+ + /**
926
+ + * @param accessToken the accessToken to set
927
+ + */
928
+ + public void setAccessToken(String accessToken) {
929
+ + this.accessToken = accessToken;
930
+ + }
931
+ +
932
+ + /**
933
+ + * @return the accessTokenSecret
934
+ + */
935
+ + public String getAccessTokenSecret() {
936
+ + return accessTokenSecret;
937
+ + }
938
+ +
939
+ + /**
940
+ + * @param accessTokenSecret the accessTokenSecret to set
941
+ + */
942
+ + public void setAccessTokenSecret(String accessTokenSecret) {
943
+ + this.accessTokenSecret = accessTokenSecret;
944
+ + }
945
+ +
946
+ + /**
947
+ + * @return the screenName
948
+ + */
949
+ + public String getScreenName() {
950
+ + return screenName;
951
+ + }
952
+ +
953
+ + /**
954
+ + * @param screenName the screenName to set
955
+ + */
956
+ + public void setScreenName(String screenName) {
957
+ + this.screenName = screenName;
958
+ + }
959
+ +
960
+ + public long getTwitterUserId(){
961
+ + return key.getId();
962
+ + }
963
+ +
964
+ + /**
965
+ + * Twitterアカウントが有効かどうか
966
+ + * @param userModel
967
+ + * @return
968
+ + */
969
+ + public boolean isValidTwitterAccount() {
970
+ + UserProxyDao userProxyDao = new UserProxyDao();
971
+ + return userProxyDao.isValidAccessToken(accessToken, accessTokenSecret);
972
+ + }
973
+ +
974
+ + public String getZusaarUrl(){
975
+ + return "http://www.zusaar.com/user/" + zusaarId;
976
+ + }
977
+ +
978
+ + public String getPartakeUrl(){
979
+ + return "http://partake.in/users/" + partakeId;
980
+ + }
981
+ +
982
+ + public String getConnpassUrl(){
983
+ + return "http://connpass.com/user/" + connpassId;
984
+ + }
985
+ +
986
+ + public Twitter getTwitter(){
987
+ + return TwitterUtil.getTwitter(accessToken, accessTokenSecret);
988
+ + }
989
+ +}
990
+ diff --git a/src/main/java/net/sue445/azusaar/page/AbstractPage.java b/src/main/java/net/sue445/azusaar/page/AbstractPage.java
991
+ new file mode 100644
992
+ index 0000000..3c38921
993
+ --- /dev/null
994
+ +++ b/src/main/java/net/sue445/azusaar/page/AbstractPage.java
995
+ @@ -0,0 +1,43 @@
996
+ +package net.sue445.azusaar.page;
997
+ +
998
+ +import org.slim3.controller.ControllerConstants;
999
+ +import org.slim3.controller.Navigation;
1000
+ +
1001
+ +import scenic3.ScenicPage;
1002
+ +
1003
+ +public abstract class AbstractPage extends ScenicPage{
1004
+ + public abstract String getPageName();
1005
+ +
1006
+ + public String getPagePath(){
1007
+ + return "/WEB-INF/view" + getPageName();
1008
+ + }
1009
+ +
1010
+ + @Override
1011
+ + protected Navigation setUp() {
1012
+ + // f:urlでの基準パスを設定する
1013
+ + requestScope(ControllerConstants.BASE_PATH_KEY, getPageName());
1014
+ +
1015
+ + return super.setUp();
1016
+ + }
1017
+ +
1018
+ + /**
1019
+ + * {@inheritDoc}
1020
+ + * <p>
1021
+ + * pathの先頭に "/WEB-INF/view&lt;page-name&gt;" を付加する
1022
+ + * </p>
1023
+ + */
1024
+ + @Override
1025
+ + protected Navigation forward(String path) {
1026
+ + return super.forward(getPagePath() + path);
1027
+ + }
1028
+ +
1029
+ + @Override
1030
+ + protected String param(CharSequence name) throws NullPointerException {
1031
+ + String value = super.param(name);
1032
+ + if(value != null){
1033
+ + value = value.trim();
1034
+ + }
1035
+ + return value;
1036
+ + }
1037
+ +
1038
+ +}
1039
+ diff --git a/src/main/java/net/sue445/azusaar/page/HomePage.java b/src/main/java/net/sue445/azusaar/page/HomePage.java
1040
+ new file mode 100644
1041
+ index 0000000..5f18363
1042
+ --- /dev/null
1043
+ +++ b/src/main/java/net/sue445/azusaar/page/HomePage.java
1044
+ @@ -0,0 +1,64 @@
1045
+ +package net.sue445.azusaar.page;
1046
+ +
1047
+ +import net.sue445.azusaar.dao.UserDao;
1048
+ +import net.sue445.azusaar.meta.UserModelMeta;
1049
+ +import net.sue445.azusaar.model.UserModel;
1050
+ +import net.sue445.common.logging.Jdk14LogFactory;
1051
+ +import net.sue445.common.logging.Log;
1052
+ +
1053
+ +import org.slim3.controller.Navigation;
1054
+ +
1055
+ +import scenic3.annotation.ActionPath;
1056
+ +import scenic3.annotation.Page;
1057
+ +import twitter4j.Twitter;
1058
+ +
1059
+ +@Page("/home/")
1060
+ +public class HomePage extends AbstractPage {
1061
+ + protected static final Log log = Jdk14LogFactory.getLogger(HomePage.class);
1062
+ +
1063
+ + private UserModel currentUser;
1064
+ +
1065
+ + @Override
1066
+ + protected Navigation setUp() {
1067
+ + UserDao userDao = new UserDao();
1068
+ + currentUser = userDao.getCurrentUser(request, response);
1069
+ + requestScope("user", currentUser);
1070
+ +
1071
+ + return super.setUp();
1072
+ + }
1073
+ +
1074
+ + @Override
1075
+ + public String getPageName() {
1076
+ + return "/home/";
1077
+ + }
1078
+ +
1079
+ + @ActionPath("")
1080
+ + public Navigation index() {
1081
+ + return forward("index.jsp");
1082
+ + }
1083
+ +
1084
+ + @ActionPath("edit")
1085
+ + public Navigation edit() {
1086
+ + return forward("edit.jsp");
1087
+ + }
1088
+ +
1089
+ + @ActionPath("update")
1090
+ + public Navigation update() {
1091
+ + UserModelMeta e= UserModelMeta.get();
1092
+ + currentUser.setZusaarId(param(e.zusaarId));
1093
+ + currentUser.setPartakeId(param(e.partakeId));
1094
+ + currentUser.setConnpassId(param(e.connpassId));
1095
+ +
1096
+ + try {
1097
+ + Twitter twitter = currentUser.getTwitter();
1098
+ + currentUser.setScreenName(twitter.getScreenName());
1099
+ + } catch (Exception ex) {
1100
+ + log.warn("can not update screenName", ex);
1101
+ + }
1102
+ +
1103
+ + UserDao userDao = new UserDao();
1104
+ + userDao.put(currentUser);
1105
+ +
1106
+ + return redirect("/home/");
1107
+ + }
1108
+ +}
1109
+ diff --git a/src/main/java/net/sue445/azusaar/util/CookieUtil.java b/src/main/java/net/sue445/azusaar/util/CookieUtil.java
1110
+ new file mode 100644
1111
+ index 0000000..8bc4c0a
1112
+ --- /dev/null
1113
+ +++ b/src/main/java/net/sue445/azusaar/util/CookieUtil.java
1114
+ @@ -0,0 +1,34 @@
1115
+ +package net.sue445.azusaar.util;
1116
+ +
1117
+ +import javax.servlet.http.Cookie;
1118
+ +
1119
+ +import net.sue445.kulib.util.EmptyCheckUtil;
1120
+ +
1121
+ +public final class CookieUtil {
1122
+ + public static final String ACCESS_TOKEN = "accessToken";
1123
+ + public static final String ACCESS_TOKEN_SECRET = "accessTokenSecret";
1124
+ +
1125
+ + private CookieUtil(){
1126
+ +
1127
+ + }
1128
+ +
1129
+ + /**
1130
+ + *
1131
+ + * @param cookies
1132
+ + * @param name
1133
+ + * @return if not found, return null
1134
+ + */
1135
+ + public static String findValue(Cookie[] cookies, String name){
1136
+ + if(EmptyCheckUtil.isEmpty(cookies)){
1137
+ + return null;
1138
+ + }
1139
+ +
1140
+ + for(Cookie cookie : cookies){
1141
+ + if(name.equals(cookie.getName())){
1142
+ + return cookie.getValue();
1143
+ + }
1144
+ + }
1145
+ +
1146
+ + return null;
1147
+ + }
1148
+ +}
1149
+ diff --git a/src/main/java/net/sue445/azusaar/util/SessionUtil.java b/src/main/java/net/sue445/azusaar/util/SessionUtil.java
1150
+ new file mode 100644
1151
+ index 0000000..f2d12eb
1152
+ --- /dev/null
1153
+ +++ b/src/main/java/net/sue445/azusaar/util/SessionUtil.java
1154
+ @@ -0,0 +1,45 @@
1155
+ +package net.sue445.azusaar.util;
1156
+ +
1157
+ +import javax.servlet.http.HttpServletRequest;
1158
+ +
1159
+ +public final class SessionUtil {
1160
+ + public enum SessionKey {
1161
+ + REQUEST_TOKEN,
1162
+ + ACCESS_TOKEN,
1163
+ + }
1164
+ +
1165
+ + private SessionUtil(){
1166
+ +
1167
+ + }
1168
+ +
1169
+ + /**
1170
+ + *
1171
+ + * @param request
1172
+ + * @param key
1173
+ + * @param value
1174
+ + */
1175
+ + public static void put(HttpServletRequest request, SessionKey key, Object value){
1176
+ + request.getSession().setAttribute(key.name(), value);
1177
+ + }
1178
+ +
1179
+ + /**
1180
+ + *
1181
+ + * @param request
1182
+ + * @param key
1183
+ + * @return
1184
+ + */
1185
+ + @SuppressWarnings("unchecked")
1186
+ + public static <T> T get(HttpServletRequest request, SessionKey key) {
1187
+ + return (T) request.getSession().getAttribute(key.name());
1188
+ + }
1189
+ +
1190
+ + /**
1191
+ + *
1192
+ + * @param request
1193
+ + * @param key
1194
+ + */
1195
+ + public static void remove(HttpServletRequest request, SessionKey key) {
1196
+ + request.getSession().removeAttribute(key.name());
1197
+ + }
1198
+ +
1199
+ +}
1200
+ diff --git a/src/main/java/net/sue445/azusaar/util/TwitterUtil.java b/src/main/java/net/sue445/azusaar/util/TwitterUtil.java
1201
+ new file mode 100644
1202
+ index 0000000..6d3ad33
1203
+ --- /dev/null
1204
+ +++ b/src/main/java/net/sue445/azusaar/util/TwitterUtil.java
1205
+ @@ -0,0 +1,102 @@
1206
+ +package net.sue445.azusaar.util;
1207
+ +
1208
+ +import javax.servlet.http.HttpServletRequest;
1209
+ +
1210
+ +import net.sue445.azusaar.enums.OAuthConsumerKey;
1211
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
1212
+ +import net.sue445.common.logging.Jdk14LogFactory;
1213
+ +import net.sue445.common.logging.Log;
1214
+ +
1215
+ +import org.apache.commons.lang.StringUtils;
1216
+ +
1217
+ +import twitter4j.Twitter;
1218
+ +import twitter4j.TwitterFactory;
1219
+ +import twitter4j.auth.AccessToken;
1220
+ +import twitter4j.conf.Configuration;
1221
+ +import twitter4j.conf.ConfigurationBuilder;
1222
+ +
1223
+ +public final class TwitterUtil {
1224
+ + private static final Log log = Jdk14LogFactory.getLogger(TwitterUtil.class);
1225
+ +
1226
+ + private TwitterUtil(){
1227
+ +
1228
+ + }
1229
+ +
1230
+ + /**
1231
+ + * @param accessToken
1232
+ + * @param accessTokenSecret
1233
+ + * @return
1234
+ + */
1235
+ + public static Twitter getTwitter(String accessToken, String accessTokenSecret){
1236
+ + TwitterFactory twitterFactory = getTwitterFactory();
1237
+ + return twitterFactory.getInstance(new AccessToken(accessToken, accessTokenSecret));
1238
+ + }
1239
+ +
1240
+ + /**
1241
+ + *
1242
+ + * @return
1243
+ + */
1244
+ + private static TwitterFactory getTwitterFactory() {
1245
+ + OAuthConsumerKey consumerKey = OAuthConsumerKey.getCurrentKey();
1246
+ +
1247
+ + ConfigurationBuilder builder = new ConfigurationBuilder();
1248
+ + builder.setOAuthConsumerKey(consumerKey.consumerKey);
1249
+ + builder.setOAuthConsumerSecret(consumerKey.consumerSecret);
1250
+ + builder.setUseSSL(true);
1251
+ + builder.setGZIPEnabled(false);
1252
+ +
1253
+ + Configuration conf = builder.build();
1254
+ + TwitterFactory twitterFactory = new TwitterFactory(conf);
1255
+ + return twitterFactory;
1256
+ + }
1257
+ +
1258
+ + /**
1259
+ + * @return
1260
+ + */
1261
+ + public static Twitter getTwitter(){
1262
+ + TwitterFactory twitterFactory = getTwitterFactory();
1263
+ + return twitterFactory.getInstance();
1264
+ + }
1265
+ +
1266
+ + /**
1267
+ + * アクセストークンが有効かどうか(書式だけチェックしてAPIはコールしない)
1268
+ + * @param accessToken
1269
+ + * @param accessTokenSecret
1270
+ + * @return
1271
+ + */
1272
+ + public static boolean isAccessTokenValid(String accessToken, String accessTokenSecret){
1273
+ + if(StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(accessTokenSecret)){
1274
+ + return false;
1275
+ + }
1276
+ +
1277
+ + try {
1278
+ + Twitter twitter = getTwitter(accessToken, accessTokenSecret);
1279
+ + twitter.verifyCredentials();
1280
+ + return true;
1281
+ + } catch (Exception e) {
1282
+ + log.warn("can not verifyCredentials", e);
1283
+ + }
1284
+ + return false;
1285
+ + }
1286
+ +
1287
+ + /**
1288
+ + * cookieかsessionのtokenが有効かどうか調べる
1289
+ + * @param request
1290
+ + * @return
1291
+ + */
1292
+ + public static boolean isAccessTokenValid(HttpServletRequest request){
1293
+ + String accessToken = CookieUtil.findValue(request.getCookies(), CookieUtil.ACCESS_TOKEN);
1294
+ + String accessTokenSecret = CookieUtil.findValue(request.getCookies(), CookieUtil.ACCESS_TOKEN_SECRET);
1295
+ +
1296
+ + if(isAccessTokenValid(accessToken, accessTokenSecret)){
1297
+ + return true;
1298
+ + }
1299
+ +
1300
+ + AccessToken sessionAccessToken = SessionUtil.get(request, SessionKey.ACCESS_TOKEN);
1301
+ + if(sessionAccessToken != null && isAccessTokenValid(sessionAccessToken.getToken(), sessionAccessToken.getTokenSecret())){
1302
+ + return true;
1303
+ + }
1304
+ +
1305
+ + return false;
1306
+ + }
1307
+ +}
1308
+ diff --git a/src/test/java/net/sue445/azusaar/controller/admin/EnvironmentControllerTest.java b/src/test/java/net/sue445/azusaar/controller/admin/EnvironmentControllerTest.java
1309
+ index 5f389c7..6492961 100644
1310
+ --- a/src/test/java/net/sue445/azusaar/controller/admin/EnvironmentControllerTest.java
1311
+ +++ b/src/test/java/net/sue445/azusaar/controller/admin/EnvironmentControllerTest.java
1312
+ @@ -24,2 +23,0 @@ public class EnvironmentControllerTest extends AbstractControllerTestCase {
1313
+ - //System.out.println(getResponse());
1314
+ -
1315
+ diff --git a/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/DetailControllerTest.java b/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/DetailControllerTest.java
1316
+ index 3073d9f..bb9bf91 100644
1317
+ --- a/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/DetailControllerTest.java
1318
+ +++ b/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/DetailControllerTest.java
1319
+ @@ -3,5 +3,2 @@ package net.sue445.azusaar.controller.admin.kokucheese;
1320
+ -import static org.hamcrest.CoreMatchers.is;
1321
+ -import static org.hamcrest.CoreMatchers.notNullValue;
1322
+ -import static org.hamcrest.CoreMatchers.nullValue;
1323
+ -import static org.hamcrest.Matchers.containsString;
1324
+ -import static org.junit.Assert.assertThat;
1325
+ +import static org.hamcrest.Matchers.*;
1326
+ +import static org.junit.Assert.*;
1327
+ @@ -37 +33,0 @@ public class DetailControllerTest extends AbstractControllerTestCase {
1328
+ - System.out.println(actual);
1329
+ diff --git a/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/ListControllerTest.java b/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/ListControllerTest.java
1330
+ index 8a58fa0..415eddc 100644
1331
+ --- a/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/ListControllerTest.java
1332
+ +++ b/src/test/java/net/sue445/azusaar/controller/admin/kokucheese/ListControllerTest.java
1333
+ @@ -3,5 +3,2 @@ package net.sue445.azusaar.controller.admin.kokucheese;
1334
+ -import static org.hamcrest.CoreMatchers.containsString;
1335
+ -import static org.hamcrest.CoreMatchers.is;
1336
+ -import static org.hamcrest.CoreMatchers.notNullValue;
1337
+ -import static org.hamcrest.CoreMatchers.nullValue;
1338
+ -import static org.junit.Assert.assertThat;
1339
+ +import static org.hamcrest.CoreMatchers.*;
1340
+ +import static org.junit.Assert.*;
1341
+ @@ -34 +30,0 @@ public class ListControllerTest extends AbstractControllerTestCase {
1342
+ - System.out.println(actual);
1343
+ diff --git a/src/test/java/net/sue445/azusaar/controller/api/JalanControllerTest.java b/src/test/java/net/sue445/azusaar/controller/api/JalanControllerTest.java
1344
+ index 5b34b5b..0770a42 100644
1345
+ --- a/src/test/java/net/sue445/azusaar/controller/api/JalanControllerTest.java
1346
+ +++ b/src/test/java/net/sue445/azusaar/controller/api/JalanControllerTest.java
1347
+ @@ -24 +23,0 @@ public class JalanControllerTest extends AbstractControllerTestCase {
1348
+ - System.out.println(content);
1349
+ diff --git a/src/test/java/net/sue445/azusaar/controller/api/KokucheeseControllerTest.java b/src/test/java/net/sue445/azusaar/controller/api/KokucheeseControllerTest.java
1350
+ index e0eaabe..770ddc0 100644
1351
+ --- a/src/test/java/net/sue445/azusaar/controller/api/KokucheeseControllerTest.java
1352
+ +++ b/src/test/java/net/sue445/azusaar/controller/api/KokucheeseControllerTest.java
1353
+ @@ -31 +30,0 @@ public class KokucheeseControllerTest extends AbstractControllerTestCase {
1354
+ - //System.out.println(getResponse());
1355
+ diff --git a/src/test/java/net/sue445/azusaar/controller/api/PartakeControllerTest.java b/src/test/java/net/sue445/azusaar/controller/api/PartakeControllerTest.java
1356
+ index ae1c482..589a422 100644
1357
+ --- a/src/test/java/net/sue445/azusaar/controller/api/PartakeControllerTest.java
1358
+ +++ b/src/test/java/net/sue445/azusaar/controller/api/PartakeControllerTest.java
1359
+ @@ -31 +30,0 @@ public class PartakeControllerTest extends AbstractControllerTestCase {
1360
+ - //System.out.println(getResponse());
1361
+ @@ -77 +75,0 @@ public class PartakeControllerTest extends AbstractControllerTestCase {
1362
+ - //System.out.println(getResponse());
1363
+ diff --git a/src/test/java/net/sue445/azusaar/controller/api/ZusaarControllerTest.java b/src/test/java/net/sue445/azusaar/controller/api/ZusaarControllerTest.java
1364
+ index d385925..a8d819a 100644
1365
+ --- a/src/test/java/net/sue445/azusaar/controller/api/ZusaarControllerTest.java
1366
+ +++ b/src/test/java/net/sue445/azusaar/controller/api/ZusaarControllerTest.java
1367
+ @@ -60 +59,0 @@ public class ZusaarControllerTest extends AbstractControllerTestCase {
1368
+ - //System.out.println(getResponse());
1369
+ diff --git a/src/test/java/net/sue445/azusaar/controller/auth/CallbackControllerTest.java b/src/test/java/net/sue445/azusaar/controller/auth/CallbackControllerTest.java
1370
+ new file mode 100644
1371
+ index 0000000..73d42b0
1372
+ --- /dev/null
1373
+ +++ b/src/test/java/net/sue445/azusaar/controller/auth/CallbackControllerTest.java
1374
+ @@ -0,0 +1,73 @@
1375
+ +package net.sue445.azusaar.controller.auth;
1376
+ +
1377
+ +import static org.hamcrest.CoreMatchers.*;
1378
+ +import static org.junit.Assert.*;
1379
+ +import net.sue445.azusaar.model.UserModel;
1380
+ +import net.sue445.azusaar.util.TestUtil;
1381
+ +
1382
+ +import org.junit.Before;
1383
+ +import org.junit.Test;
1384
+ +import org.junit.experimental.runners.Enclosed;
1385
+ +import org.junit.runner.RunWith;
1386
+ +import org.slim3.tester.ControllerTestCase;
1387
+ +
1388
+ +import twitter4j.auth.AccessToken;
1389
+ +
1390
+ +@RunWith(Enclosed.class)
1391
+ +public class CallbackControllerTest{
1392
+ + public static class WhenUserNotRegisted extends ControllerTestCase {
1393
+ + @Before
1394
+ + public void setUpMock() {
1395
+ + CallbackController.mockAccessToken = new MockAccessToken();
1396
+ + }
1397
+ +
1398
+ + @Test
1399
+ + public void run() throws Exception {
1400
+ + tester.param("oauth_verifier", "aaaaaaaaaaa");
1401
+ + tester.start("/auth/callback");
1402
+ + CallbackController controller = tester.getController();
1403
+ +
1404
+ + assertThat(controller, is(notNullValue()));
1405
+ + assertThat(tester.isRedirect(), is(true));
1406
+ + assertThat(tester.getDestinationPath(), is("/home/"));
1407
+ + assertThat(tester.count(UserModel.class), is(1));
1408
+ + }
1409
+ + }
1410
+ +
1411
+ + public static class WhenUserRegisted extends ControllerTestCase {
1412
+ + @Before
1413
+ + public void setUpMock() {
1414
+ + CallbackController.mockAccessToken = new MockAccessToken();
1415
+ + TestUtil.setUpUserModel();
1416
+ + }
1417
+ +
1418
+ + @Test
1419
+ + public void run() throws Exception {
1420
+ + tester.param("oauth_verifier", "aaaaaaaaaaa");
1421
+ + tester.start("/auth/callback");
1422
+ + CallbackController controller = tester.getController();
1423
+ +
1424
+ + assertThat(controller, is(notNullValue()));
1425
+ + assertThat(tester.isRedirect(), is(true));
1426
+ + assertThat(tester.getDestinationPath(), is("/"));
1427
+ + assertThat(tester.count(UserModel.class), is(1));
1428
+ + }
1429
+ + }
1430
+ +
1431
+ + @SuppressWarnings("serial")
1432
+ + private static class MockAccessToken extends AccessToken{
1433
+ + public MockAccessToken(){
1434
+ + super(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1435
+ + }
1436
+ +
1437
+ + @Override
1438
+ + public String getScreenName() {
1439
+ + return TestUtil.SCREEN_NAME;
1440
+ + }
1441
+ +
1442
+ + @Override
1443
+ + public long getUserId() {
1444
+ + return TestUtil.TWITTER_USER_ID;
1445
+ + }
1446
+ + }
1447
+ +}
1448
+ diff --git a/src/test/java/net/sue445/azusaar/controller/auth/LogoutControllerTest.java b/src/test/java/net/sue445/azusaar/controller/auth/LogoutControllerTest.java
1449
+ new file mode 100644
1450
+ index 0000000..73ac1e9
1451
+ --- /dev/null
1452
+ +++ b/src/test/java/net/sue445/azusaar/controller/auth/LogoutControllerTest.java
1453
+ @@ -0,0 +1,56 @@
1454
+ +package net.sue445.azusaar.controller.auth;
1455
+ +
1456
+ +import static org.hamcrest.CoreMatchers.*;
1457
+ +import static org.junit.Assert.*;
1458
+ +
1459
+ +import javax.servlet.http.Cookie;
1460
+ +
1461
+ +import net.sue445.azusaar.model.UserModel;
1462
+ +import net.sue445.azusaar.util.CookieUtil;
1463
+ +import net.sue445.azusaar.util.SessionUtil;
1464
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
1465
+ +import net.sue445.azusaar.util.TestUtil;
1466
+ +
1467
+ +import org.junit.Before;
1468
+ +import org.junit.Test;
1469
+ +import org.slim3.datastore.Datastore;
1470
+ +import org.slim3.tester.ControllerTestCase;
1471
+ +
1472
+ +import twitter4j.auth.AccessToken;
1473
+ +
1474
+ +import com.google.appengine.api.datastore.Key;
1475
+ +
1476
+ +public class LogoutControllerTest extends ControllerTestCase {
1477
+ + @Before
1478
+ + public void before() {
1479
+ + TestUtil.setUpUserModel();
1480
+ + SessionUtil.put(tester.request, SessionKey.ACCESS_TOKEN, TestUtil.getMockAccessToken());
1481
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN));
1482
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN_SECRET, TestUtil.ACCESS_TOKEN_SECRET));
1483
+ + }
1484
+ +
1485
+ + @Test
1486
+ + public void run() throws Exception {
1487
+ + tester.start("/auth/logout");
1488
+ + LogoutController controller = tester.getController();
1489
+ + assertThat(controller, is(notNullValue()));
1490
+ + assertThat(tester.isRedirect(), is(true));
1491
+ + assertThat(tester.getDestinationPath(), is("/"));
1492
+ +
1493
+ + Key userKey = UserModel.createKey(TestUtil.TWITTER_USER_ID);
1494
+ + UserModel actualUser = Datastore.get(UserModel.class, userKey);
1495
+ + assertThat(actualUser.getAccessToken(), is(nullValue()));
1496
+ + assertThat(actualUser.getAccessTokenSecret(), is(nullValue()));
1497
+ +
1498
+ + AccessToken actualSession = SessionUtil.get(tester.request, SessionKey.ACCESS_TOKEN);
1499
+ + assertThat(actualSession, is(nullValue()));
1500
+ +
1501
+ + Cookie[] actualCookies = tester.response.getCookies();
1502
+ +
1503
+ + assertThat(actualCookies.length, is(2));
1504
+ + assertThat(actualCookies[0].getName(), is(CookieUtil.ACCESS_TOKEN));
1505
+ + assertThat(actualCookies[0].getMaxAge(), is(0));
1506
+ + assertThat(actualCookies[1].getName(), is(CookieUtil.ACCESS_TOKEN_SECRET));
1507
+ + assertThat(actualCookies[1].getMaxAge(), is(0));
1508
+ + }
1509
+ +}
1510
+ diff --git a/src/test/java/net/sue445/azusaar/controller/auth/UserInfoControllerTest.java b/src/test/java/net/sue445/azusaar/controller/auth/UserInfoControllerTest.java
1511
+ new file mode 100644
1512
+ index 0000000..34f6a11
1513
+ --- /dev/null
1514
+ +++ b/src/test/java/net/sue445/azusaar/controller/auth/UserInfoControllerTest.java
1515
+ @@ -0,0 +1,92 @@
1516
+ +package net.sue445.azusaar.controller.auth;
1517
+ +
1518
+ +import static org.hamcrest.CoreMatchers.*;
1519
+ +import static org.junit.Assert.*;
1520
+ +
1521
+ +import java.io.IOException;
1522
+ +
1523
+ +import javax.servlet.ServletException;
1524
+ +import javax.servlet.http.Cookie;
1525
+ +
1526
+ +import net.sue445.azusaar.util.CookieUtil;
1527
+ +import net.sue445.azusaar.util.SessionUtil;
1528
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
1529
+ +import net.sue445.azusaar.util.TestUtil;
1530
+ +import net.sue445.s3tiger.rules.ControllerResource;
1531
+ +
1532
+ +import org.junit.Before;
1533
+ +import org.junit.Rule;
1534
+ +import org.junit.Test;
1535
+ +import org.junit.experimental.runners.Enclosed;
1536
+ +import org.junit.runner.RunWith;
1537
+ +import org.slim3.tester.ControllerTester;
1538
+ +
1539
+ +@RunWith(Enclosed.class)
1540
+ +public class UserInfoControllerTest {
1541
+ + public static class WhenNotLogined{
1542
+ + @Rule
1543
+ + public ControllerResource controllerResource = new ControllerResource(UserInfoControllerTest.class);
1544
+ +
1545
+ + private ControllerTester tester;
1546
+ +
1547
+ + @Before
1548
+ + public void setUp() throws Exception {
1549
+ + tester = controllerResource.tester;
1550
+ + TestUtil.setUpUserModel();
1551
+ + }
1552
+ +
1553
+ + @Test
1554
+ + public void run() throws Exception {
1555
+ + runController(tester);
1556
+ +
1557
+ + String actual = tester.response.getOutputAsString();
1558
+ +
1559
+ + assertThat(actual, not(containsString("atndId")));
1560
+ + assertThat(actual, not(containsString("zusaarId")));
1561
+ + assertThat(actual, not(containsString("eventAtndId")));
1562
+ + assertThat(actual, not(containsString("partakeId")));
1563
+ + assertThat(actual, not(containsString("connpassId")));
1564
+ + }
1565
+ + }
1566
+ +
1567
+ + public static class WhenHasSession {
1568
+ + @Rule
1569
+ + public ControllerResource controllerResource = new ControllerResource(UserInfoControllerTest.class);
1570
+ +
1571
+ + private ControllerTester tester;
1572
+ +
1573
+ + @Before
1574
+ + public void setUp() throws Exception {
1575
+ + tester = controllerResource.tester;
1576
+ + TestUtil.setUpUserModel();
1577
+ + SessionUtil.put(tester.request, SessionKey.ACCESS_TOKEN, TestUtil.getMockAccessToken());
1578
+ + }
1579
+ +
1580
+ + @Test
1581
+ + public void run() throws Exception {
1582
+ + runController(tester);
1583
+ +
1584
+ + String actual = tester.response.getOutputAsString();
1585
+ + assertThat(actual, containsString("screenName"));
1586
+ +// assertThat(actual, containsString("atndId"));
1587
+ + assertThat(actual, containsString("zusaarId"));
1588
+ +// assertThat(actual, containsString("eventAtndId"));
1589
+ + assertThat(actual, containsString("partakeId"));
1590
+ + assertThat(actual, containsString("connpassId"));
1591
+ +
1592
+ + Cookie[] cookies = tester.response.getCookies();
1593
+ + assertThat(cookies[0].getName(), is(CookieUtil.ACCESS_TOKEN));
1594
+ + assertThat(cookies[0].getValue(), is(TestUtil.ACCESS_TOKEN));
1595
+ + assertThat(cookies[1].getName(), is(CookieUtil.ACCESS_TOKEN_SECRET));
1596
+ + assertThat(cookies[1].getValue(), is(TestUtil.ACCESS_TOKEN_SECRET));
1597
+ + }
1598
+ + }
1599
+ +
1600
+ + private static void runController(ControllerTester tester) throws IOException, ServletException {
1601
+ + tester.start("/auth/userInfo");
1602
+ + UserInfoController controller = tester.getController();
1603
+ + assertThat(controller, is(notNullValue()));
1604
+ + assertThat(tester.isRedirect(), is(false));
1605
+ + assertThat(tester.getDestinationPath(), is(nullValue()));
1606
+ + }
1607
+ +}
1608
+ diff --git a/src/test/java/net/sue445/azusaar/dao/UserDaoTest.java b/src/test/java/net/sue445/azusaar/dao/UserDaoTest.java
1609
+ new file mode 100644
1610
+ index 0000000..be4e88a
1611
+ --- /dev/null
1612
+ +++ b/src/test/java/net/sue445/azusaar/dao/UserDaoTest.java
1613
+ @@ -0,0 +1,145 @@
1614
+ +package net.sue445.azusaar.dao;
1615
+ +
1616
+ +import static org.hamcrest.CoreMatchers.*;
1617
+ +import static org.junit.Assert.*;
1618
+ +
1619
+ +import javax.servlet.http.Cookie;
1620
+ +
1621
+ +import net.sue445.azusaar.model.UserModel;
1622
+ +import net.sue445.azusaar.util.CookieUtil;
1623
+ +import net.sue445.azusaar.util.SessionUtil;
1624
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
1625
+ +import net.sue445.azusaar.util.TestUtil;
1626
+ +
1627
+ +import org.junit.Before;
1628
+ +import org.junit.Test;
1629
+ +import org.junit.experimental.runners.Enclosed;
1630
+ +import org.junit.runner.RunWith;
1631
+ +import org.slim3.tester.AppEngineTestCase;
1632
+ +import org.slim3.tester.ControllerTestCase;
1633
+ +
1634
+ +@RunWith(Enclosed.class)
1635
+ +public class UserDaoTest {
1636
+ +
1637
+ +
1638
+ + public static class WhenExistsUser extends AppEngineTestCase {
1639
+ + private UserDao dao = new UserDao();
1640
+ +
1641
+ + @Before
1642
+ + public void before(){
1643
+ + TestUtil.setUpUserModel();
1644
+ + }
1645
+ +
1646
+ + @Test
1647
+ + public void getOrNull() throws Exception {
1648
+ + UserModel actual = dao.getOrNull(TestUtil.TWITTER_USER_ID);
1649
+ +
1650
+ + assertThat(actual, is(notNullValue()));
1651
+ + assertThat(actual.getTwitterUserId(), is(TestUtil.TWITTER_USER_ID));
1652
+ + }
1653
+ +
1654
+ + @Test
1655
+ + public void findByOAuth() throws Exception {
1656
+ + UserModel actual = dao.findByOAuth(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1657
+ + assertThat(actual, is(notNullValue()));
1658
+ + assertThat(actual.getTwitterUserId(), is(TestUtil.TWITTER_USER_ID));
1659
+ + }
1660
+ +
1661
+ + @Test
1662
+ + public void getOrNew_Get() throws Exception {
1663
+ + UserModel actual = dao.getOrNew(TestUtil.TWITTER_USER_ID);
1664
+ +
1665
+ + assertThat(actual, is(notNullValue()));
1666
+ + assertThat(actual.getKey().getId(), is(TestUtil.TWITTER_USER_ID));
1667
+ + assertThat(actual.getVersion(), is(1L));
1668
+ + }
1669
+ + }
1670
+ +
1671
+ + public static class WhenNotExistsUser extends AppEngineTestCase {
1672
+ + private UserDao dao = new UserDao();
1673
+ +
1674
+ + @Test
1675
+ + public void getOrNull() throws Exception {
1676
+ + UserModel actual = dao.getOrNull(TestUtil.TWITTER_USER_ID);
1677
+ +
1678
+ + assertThat(actual, is(nullValue()));
1679
+ + }
1680
+ +
1681
+ + @Test
1682
+ + public void findByOAuth() throws Exception {
1683
+ + UserModel actual = dao.findByOAuth(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1684
+ + assertThat(actual, is(nullValue()));
1685
+ + }
1686
+ +
1687
+ + @Test
1688
+ + public void getOrNew_New() throws Exception {
1689
+ + UserModel actual = dao.getOrNew(TestUtil.TWITTER_USER_ID);
1690
+ +
1691
+ + assertThat(actual.getVersion(), is(nullValue()));
1692
+ + }
1693
+ +
1694
+ + }
1695
+ +
1696
+ + public static class WhenHasCookie extends ControllerTestCase {
1697
+ + private UserDao dao = new UserDao();
1698
+ +
1699
+ + @Before
1700
+ + public void before() {
1701
+ + TestUtil.setUpUserModel();
1702
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN));
1703
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN_SECRET, TestUtil.ACCESS_TOKEN_SECRET));
1704
+ + }
1705
+ +
1706
+ + @Test
1707
+ + public void getCurrentUser() throws Exception {
1708
+ + UserModel actual = dao.getCurrentUser(tester.request, tester.response);
1709
+ +
1710
+ + assertThat(actual, is(notNullValue()));
1711
+ + assertThat(actual.getKey().getId(), is(TestUtil.TWITTER_USER_ID));
1712
+ + }
1713
+ + }
1714
+ +
1715
+ + public static class WhenHasSession extends ControllerTestCase {
1716
+ + private UserDao dao = new UserDao();
1717
+ +
1718
+ + @Before
1719
+ + public void before() {
1720
+ + TestUtil.setUpUserModel();
1721
+ + SessionUtil.put(tester.request, SessionKey.ACCESS_TOKEN, TestUtil.getMockAccessToken());
1722
+ + }
1723
+ +
1724
+ + @Test
1725
+ + public void getCurrentUser() throws Exception {
1726
+ + UserModel actual = dao.getCurrentUser(tester.request, tester.response);
1727
+ +
1728
+ + assertThat(actual, is(notNullValue()));
1729
+ + assertThat(actual.getKey().getId(), is(TestUtil.TWITTER_USER_ID));
1730
+ +
1731
+ + Cookie[] cookies = tester.response.getCookies();
1732
+ + assertThat(cookies[0].getName(), is(CookieUtil.ACCESS_TOKEN));
1733
+ + assertThat(cookies[0].getValue(), is(TestUtil.ACCESS_TOKEN));
1734
+ + assertThat(cookies[1].getName(), is(CookieUtil.ACCESS_TOKEN_SECRET));
1735
+ + assertThat(cookies[1].getValue(), is(TestUtil.ACCESS_TOKEN_SECRET));
1736
+ + }
1737
+ + }
1738
+ +
1739
+ + public static class WhenHasParam extends ControllerTestCase {
1740
+ + private UserDao dao = new UserDao();
1741
+ +
1742
+ + @Before
1743
+ + public void before() {
1744
+ + TestUtil.setUpUserModel();
1745
+ + tester.param(CookieUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN);
1746
+ + tester.param(CookieUtil.ACCESS_TOKEN_SECRET, TestUtil.ACCESS_TOKEN_SECRET);
1747
+ + }
1748
+ +
1749
+ + @Test
1750
+ + public void getCurrentUser() throws Exception {
1751
+ + UserModel actual = dao.getCurrentUser(tester.request, tester.response);
1752
+ +
1753
+ + assertThat(actual, is(notNullValue()));
1754
+ + assertThat(actual.getKey().getId(), is(TestUtil.TWITTER_USER_ID));
1755
+ + }
1756
+ + }
1757
+ +
1758
+ +}
1759
+ diff --git a/src/test/java/net/sue445/azusaar/dao/UserProxyDaoTest.java b/src/test/java/net/sue445/azusaar/dao/UserProxyDaoTest.java
1760
+ new file mode 100644
1761
+ index 0000000..73436f2
1762
+ --- /dev/null
1763
+ +++ b/src/test/java/net/sue445/azusaar/dao/UserProxyDaoTest.java
1764
+ @@ -0,0 +1,54 @@
1765
+ +package net.sue445.azusaar.dao;
1766
+ +
1767
+ +import static org.hamcrest.Matchers.*;
1768
+ +import static org.junit.Assert.*;
1769
+ +import net.sue445.azusaar.util.TestUtil;
1770
+ +
1771
+ +import org.junit.Before;
1772
+ +import org.junit.Test;
1773
+ +import org.junit.experimental.runners.Enclosed;
1774
+ +import org.junit.runner.RunWith;
1775
+ +import org.slim3.tester.AppEngineTestCase;
1776
+ +
1777
+ +import com.google.appengine.api.datastore.Key;
1778
+ +
1779
+ +
1780
+ +@RunWith(Enclosed.class)
1781
+ +public class UserProxyDaoTest {
1782
+ +
1783
+ + public static class WhenNoneMemcache extends AppEngineTestCase{
1784
+ + private UserProxyDao dao = new UserProxyDao();
1785
+ +
1786
+ + @Before
1787
+ + public void before() {
1788
+ + TestUtil.setUpUserModel();
1789
+ + }
1790
+ +
1791
+ + @Test
1792
+ + public void get() throws Exception {
1793
+ + Key actual = dao.get(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1794
+ +
1795
+ + assertThat(actual, is(notNullValue()));
1796
+ + assertThat(actual.getId(), is(TestUtil.TWITTER_USER_ID));
1797
+ + assertThat(dao.wasMemcacheResponse, is(false));
1798
+ + }
1799
+ + }
1800
+ +
1801
+ + public static class WhenExistsMemcache extends AppEngineTestCase{
1802
+ + private UserProxyDao dao = new UserProxyDao();
1803
+ +
1804
+ + @Before
1805
+ + public void before() {
1806
+ + TestUtil.setUpUserModel();
1807
+ + dao.get(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1808
+ + }
1809
+ +
1810
+ + @Test
1811
+ + public void get() throws Exception {
1812
+ + Key actual = dao.get(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1813
+ +
1814
+ + assertThat(actual, is(notNullValue()));
1815
+ + assertThat(actual.getId(), is(TestUtil.TWITTER_USER_ID));
1816
+ + }
1817
+ + }
1818
+ +}
1819
+ diff --git a/src/test/java/net/sue445/azusaar/filter/TwitterOAuthFilterTest.java b/src/test/java/net/sue445/azusaar/filter/TwitterOAuthFilterTest.java
1820
+ new file mode 100644
1821
+ index 0000000..5f42fa4
1822
+ --- /dev/null
1823
+ +++ b/src/test/java/net/sue445/azusaar/filter/TwitterOAuthFilterTest.java
1824
+ @@ -0,0 +1,89 @@
1825
+ +package net.sue445.azusaar.filter;
1826
+ +
1827
+ +import static org.hamcrest.Matchers.*;
1828
+ +import static org.junit.Assert.*;
1829
+ +
1830
+ +import java.io.IOException;
1831
+ +
1832
+ +import javax.servlet.FilterChain;
1833
+ +import javax.servlet.ServletException;
1834
+ +import javax.servlet.ServletRequest;
1835
+ +import javax.servlet.ServletResponse;
1836
+ +import javax.servlet.http.Cookie;
1837
+ +
1838
+ +import net.sue445.azusaar.model.UserModel;
1839
+ +import net.sue445.azusaar.util.TestUtil;
1840
+ +
1841
+ +import org.junit.Test;
1842
+ +import org.junit.experimental.runners.Enclosed;
1843
+ +import org.junit.runner.RunWith;
1844
+ +import org.slim3.datastore.Datastore;
1845
+ +import org.slim3.tester.ControllerTestCase;
1846
+ +
1847
+ +
1848
+ +@RunWith(Enclosed.class)
1849
+ +public class TwitterOAuthFilterTest{
1850
+ +
1851
+ + public static class WhenNotExistsCookie extends ControllerTestCase {
1852
+ + private TwitterOAuthFilter filter = new TwitterOAuthFilter();
1853
+ +
1854
+ + @Test
1855
+ + public void doFilter() throws Exception{
1856
+ + // cookieがない時はTwitterのログイン画面にリダイレクトされる
1857
+ + filter.doFilter(tester.request, tester.response, tester.filterChain);
1858
+ +
1859
+ + String actual = tester.response.getRedirectPath();
1860
+ + assertThat(actual, startsWith("http://api.twitter.com/oauth/authenticate?oauth_token="));
1861
+ + }
1862
+ +
1863
+ + }
1864
+ +
1865
+ + public static class WhenExistsCookie extends ControllerTestCase {
1866
+ + private TwitterOAuthFilter filter = new TwitterOAuthFilter();
1867
+ +
1868
+ + private MockFilterChain mockFilterChain = new MockFilterChain();
1869
+ +
1870
+ +
1871
+ + private void setUpOAuth(String accessToken, String accessTokenSecret) {
1872
+ + tester.request.addCookie(new Cookie("accessToken", accessToken));
1873
+ + tester.request.addCookie(new Cookie("accessTokenSecret", accessTokenSecret));
1874
+ +
1875
+ + UserModel model = new UserModel(1);
1876
+ + model.setAccessToken(accessToken);
1877
+ + model.setAccessTokenSecret(accessTokenSecret);
1878
+ + Datastore.put(model);
1879
+ + }
1880
+ +
1881
+ + @Test
1882
+ + public void doFilter_Success() throws Exception{
1883
+ + setUpOAuth(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
1884
+ +
1885
+ + filter.doFilter(tester.request, tester.response, mockFilterChain);
1886
+ +
1887
+ + assertThat(mockFilterChain.called, is(true));
1888
+ + }
1889
+ +
1890
+ + // OAuthでエラーになったらログインにとばす
1891
+ + @Test
1892
+ + public void doFilter_Failed() throws Exception{
1893
+ + // secretの最後1文字だけ違う
1894
+ + setUpOAuth(TestUtil.ACCESS_TOKEN, "JOChFP1uXcnLO6cPN2kSLzbZg64qVJBYjxHVTUVn");
1895
+ +
1896
+ + filter.doFilter(tester.request, tester.response, mockFilterChain);
1897
+ +
1898
+ + assertThat(mockFilterChain.called, is(false));
1899
+ +
1900
+ + String actual = tester.response.getRedirectPath();
1901
+ + assertThat(actual, startsWith("http://api.twitter.com/oauth/authenticate?oauth_token="));
1902
+ + }
1903
+ + }
1904
+ +
1905
+ + private static class MockFilterChain implements FilterChain{
1906
+ + public boolean called = false;
1907
+ +
1908
+ + @Override
1909
+ + public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
1910
+ + called = true;
1911
+ + }
1912
+ + }
1913
+ +}
1914
+ diff --git a/src/test/java/net/sue445/azusaar/model/UserModelTest.java b/src/test/java/net/sue445/azusaar/model/UserModelTest.java
1915
+ new file mode 100644
1916
+ index 0000000..1a71227
1917
+ --- /dev/null
1918
+ +++ b/src/test/java/net/sue445/azusaar/model/UserModelTest.java
1919
+ @@ -0,0 +1,52 @@
1920
+ +package net.sue445.azusaar.model;
1921
+ +
1922
+ +import static org.hamcrest.CoreMatchers.*;
1923
+ +import static org.junit.Assert.*;
1924
+ +import net.sue445.azusaar.util.TestUtil;
1925
+ +
1926
+ +import org.junit.Test;
1927
+ +import org.slim3.datastore.Datastore;
1928
+ +import org.slim3.tester.AppEngineTestCase;
1929
+ +
1930
+ +import com.google.appengine.api.datastore.Key;
1931
+ +
1932
+ +public class UserModelTest extends AppEngineTestCase {
1933
+ +
1934
+ + private UserModel model = new UserModel();
1935
+ +
1936
+ + @Test
1937
+ + public void test() throws Exception {
1938
+ + assertThat(model, is(notNullValue()));
1939
+ + }
1940
+ +
1941
+ + @Test
1942
+ + public void createKey() throws Exception {
1943
+ + long twitterUserId = 1;
1944
+ +
1945
+ + Key actual = UserModel.createKey(twitterUserId);
1946
+ +
1947
+ + assertThat(actual.getId(), is(twitterUserId));
1948
+ + }
1949
+ +
1950
+ + @Test
1951
+ + public void isValidTwitterAccount_OK() throws Exception {
1952
+ + model.setAccessToken(TestUtil.ACCESS_TOKEN);
1953
+ + model.setAccessTokenSecret(TestUtil.ACCESS_TOKEN_SECRET);
1954
+ + Datastore.put(model);
1955
+ +
1956
+ + boolean actual = model.isValidTwitterAccount();
1957
+ + assertThat(actual, is(true));
1958
+ + }
1959
+ +
1960
+ + @Test
1961
+ + public void isValidTwitterAccount_NG() throws Exception {
1962
+ + model.setAccessToken(TestUtil.ACCESS_TOKEN);
1963
+ +
1964
+ + // 最後1文字だけ違う
1965
+ + model.setAccessTokenSecret("JOChFP1uXcnLO6cPN2kSLzbZg64qVJBYjxHVTUVm");
1966
+ + Datastore.put(model);
1967
+ +
1968
+ + boolean actual = model.isValidTwitterAccount();
1969
+ + assertThat(actual, is(false));
1970
+ + }
1971
+ +}
1972
+ diff --git a/src/test/java/net/sue445/azusaar/page/AbstractPageTest.java b/src/test/java/net/sue445/azusaar/page/AbstractPageTest.java
1973
+ new file mode 100644
1974
+ index 0000000..e3eb787
1975
+ --- /dev/null
1976
+ +++ b/src/test/java/net/sue445/azusaar/page/AbstractPageTest.java
1977
+ @@ -0,0 +1,28 @@
1978
+ +package net.sue445.azusaar.page;
1979
+ +
1980
+ +import static org.hamcrest.Matchers.*;
1981
+ +import static org.junit.Assert.*;
1982
+ +
1983
+ +import java.io.IOException;
1984
+ +
1985
+ +import javax.servlet.ServletException;
1986
+ +
1987
+ +import scenic3.ScenicPage;
1988
+ +import scenic3.UrlsImpl;
1989
+ +import scenic3.tester.PageTestCase;
1990
+ +
1991
+ +public abstract class AbstractPageTest extends PageTestCase{
1992
+ +
1993
+ + protected AbstractPageTest(Class<? extends UrlsImpl> appUrlClass, Class<? extends ScenicPage> pageClass){
1994
+ + super(appUrlClass, pageClass);
1995
+ + }
1996
+ +
1997
+ + protected AbstractPage startPage(String path) throws IOException, ServletException {
1998
+ + tester.start(path);
1999
+ +
2000
+ + AbstractPage page = (AbstractPage) tester.getPage();
2001
+ + assertThat(page, is(notNullValue()));
2002
+ +
2003
+ + return page;
2004
+ + }
2005
+ +}
2006
+ diff --git a/src/test/java/net/sue445/azusaar/page/HomePageTest.java b/src/test/java/net/sue445/azusaar/page/HomePageTest.java
2007
+ new file mode 100644
2008
+ index 0000000..09c29fc
2009
+ --- /dev/null
2010
+ +++ b/src/test/java/net/sue445/azusaar/page/HomePageTest.java
2011
+ @@ -0,0 +1,72 @@
2012
+ +package net.sue445.azusaar.page;
2013
+ +
2014
+ +import static org.hamcrest.Matchers.*;
2015
+ +import static org.junit.Assert.*;
2016
+ +
2017
+ +import javax.servlet.http.Cookie;
2018
+ +
2019
+ +import net.sue445.azusaar.controller.AppUrls;
2020
+ +import net.sue445.azusaar.meta.UserModelMeta;
2021
+ +import net.sue445.azusaar.model.UserModel;
2022
+ +import net.sue445.azusaar.util.CookieUtil;
2023
+ +import net.sue445.azusaar.util.TestUtil;
2024
+ +
2025
+ +import org.junit.Before;
2026
+ +import org.junit.Test;
2027
+ +import org.slim3.datastore.Datastore;
2028
+ +
2029
+ +public class HomePageTest extends AbstractPageTest{
2030
+ +
2031
+ + public HomePageTest(){
2032
+ + super(AppUrls.class, HomePage.class);
2033
+ + }
2034
+ +
2035
+ + @Before
2036
+ + public void before() {
2037
+ + TestUtil.setUpUserModel();
2038
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN));
2039
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN_SECRET, TestUtil.ACCESS_TOKEN_SECRET));
2040
+ + }
2041
+ +
2042
+ + @Test
2043
+ + public void index() throws Exception{
2044
+ + AbstractPage page = startPage("/home/");
2045
+ +
2046
+ + assertThat(tester.getActionMethodName(), is("index"));
2047
+ + assertThat(tester.getDestinationPath(), is(page.getPagePath() + "index.jsp"));
2048
+ + assertThat(tester.isRedirect(), is(false));
2049
+ + }
2050
+ +
2051
+ + @Test
2052
+ + public void edit() throws Exception{
2053
+ + AbstractPage page = startPage("/home/edit");
2054
+ +
2055
+ + assertThat(tester.getActionMethodName(), is("edit"));
2056
+ + assertThat(tester.getDestinationPath(), is(page.getPagePath() + "edit.jsp"));
2057
+ + assertThat(tester.isRedirect(), is(false));
2058
+ + }
2059
+ +
2060
+ + @Test
2061
+ + public void update() throws Exception {
2062
+ + UserModelMeta e= UserModelMeta.get();
2063
+ + String zusaarId = "zusaarId";
2064
+ + String partakeId = "partakeId";
2065
+ + String connpassId = "connpassId";
2066
+ +
2067
+ + tester.param(e.zusaarId, zusaarId);
2068
+ + tester.param(e.partakeId, partakeId);
2069
+ + tester.param(e.connpassId, connpassId);
2070
+ +
2071
+ + AbstractPage page = startPage("/home/update");
2072
+ +
2073
+ + assertThat(tester.getActionMethodName(), is("update"));
2074
+ + assertThat(tester.getDestinationPath(), is("/home/"));
2075
+ + assertThat(tester.isRedirect(), is(true));
2076
+ +
2077
+ + UserModel actual = Datastore.get(UserModel.class, UserModel.createKey(TestUtil.TWITTER_USER_ID));
2078
+ + assertThat(actual.getZusaarId(), is(zusaarId));
2079
+ + assertThat(actual.getPartakeId(), is(partakeId));
2080
+ + assertThat(actual.getConnpassId(), is(connpassId));
2081
+ + assertThat(actual.getVersion(), is(2L));
2082
+ + }
2083
+ +}
2084
+ diff --git a/src/test/java/net/sue445/azusaar/service/KeywordCountServiceTest.java b/src/test/java/net/sue445/azusaar/service/KeywordCountServiceTest.java
2085
+ index a49b638..9705c85 100644
2086
+ --- a/src/test/java/net/sue445/azusaar/service/KeywordCountServiceTest.java
2087
+ +++ b/src/test/java/net/sue445/azusaar/service/KeywordCountServiceTest.java
2088
+ @@ -127 +126,0 @@ public class KeywordCountServiceTest extends AppEngineTestCase {
2089
+ - System.out.println(actual);
2090
+ diff --git a/src/test/java/net/sue445/azusaar/service/KokucheeseFeedServiceTest.java b/src/test/java/net/sue445/azusaar/service/KokucheeseFeedServiceTest.java
2091
+ index 58989f9..1b5c314 100644
2092
+ --- a/src/test/java/net/sue445/azusaar/service/KokucheeseFeedServiceTest.java
2093
+ +++ b/src/test/java/net/sue445/azusaar/service/KokucheeseFeedServiceTest.java
2094
+ @@ -36 +35,0 @@ public class KokucheeseFeedServiceTest extends AppEngineTestCase {
2095
+ - //System.out.println(actual);
2096
+ @@ -39 +37,0 @@ public class KokucheeseFeedServiceTest extends AppEngineTestCase {
2097
+ - //System.out.println(dto);
2098
+ diff --git a/src/test/java/net/sue445/azusaar/util/CookieUtilTest.java b/src/test/java/net/sue445/azusaar/util/CookieUtilTest.java
2099
+ new file mode 100644
2100
+ index 0000000..a95c208
2101
+ --- /dev/null
2102
+ +++ b/src/test/java/net/sue445/azusaar/util/CookieUtilTest.java
2103
+ @@ -0,0 +1,42 @@
2104
+ +package net.sue445.azusaar.util;
2105
+ +
2106
+ +import static org.hamcrest.Matchers.*;
2107
+ +import static org.junit.Assert.*;
2108
+ +
2109
+ +import javax.servlet.http.Cookie;
2110
+ +
2111
+ +import org.junit.Before;
2112
+ +import org.junit.Test;
2113
+ +
2114
+ +public class CookieUtilTest {
2115
+ +
2116
+ + private Cookie[] cookies;
2117
+ +
2118
+ +
2119
+ + @Before
2120
+ + public void setUp() throws Exception {
2121
+ + cookies = new Cookie[]{
2122
+ + new Cookie("name1", "value1"),
2123
+ + new Cookie("name2", "value2"),
2124
+ + new Cookie("name3", "value3"),
2125
+ + };
2126
+ + }
2127
+ +
2128
+ + @Test
2129
+ + public void findValue_Found() throws Exception {
2130
+ + String name = "name2";
2131
+ +
2132
+ + String actual = CookieUtil.findValue(cookies, name);
2133
+ +
2134
+ + assertThat(actual, is("value2"));
2135
+ + }
2136
+ +
2137
+ + @Test
2138
+ + public void findValue_NotFound() throws Exception {
2139
+ + String name = "name4";
2140
+ +
2141
+ + String actual = CookieUtil.findValue(cookies, name);
2142
+ +
2143
+ + assertThat(actual, is(nullValue()));
2144
+ + }
2145
+ +}
2146
+ diff --git a/src/test/java/net/sue445/azusaar/util/SessionUtilTest.java b/src/test/java/net/sue445/azusaar/util/SessionUtilTest.java
2147
+ new file mode 100644
2148
+ index 0000000..193d964
2149
+ --- /dev/null
2150
+ +++ b/src/test/java/net/sue445/azusaar/util/SessionUtilTest.java
2151
+ @@ -0,0 +1,22 @@
2152
+ +package net.sue445.azusaar.util;
2153
+ +
2154
+ +import static org.hamcrest.Matchers.*;
2155
+ +import static org.junit.Assert.*;
2156
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
2157
+ +
2158
+ +import org.junit.Test;
2159
+ +import org.slim3.tester.ControllerTestCase;
2160
+ +
2161
+ +public class SessionUtilTest extends ControllerTestCase{
2162
+ +
2163
+ + @Test
2164
+ + public void putAndGet() {
2165
+ + String value = "aaaa";
2166
+ +
2167
+ + SessionUtil.put(tester.request, SessionKey.REQUEST_TOKEN, value);
2168
+ +
2169
+ + String actual = SessionUtil.get(tester.request, SessionKey.REQUEST_TOKEN);
2170
+ + assertThat(actual, is(value));
2171
+ + }
2172
+ +
2173
+ +}
2174
+ diff --git a/src/test/java/net/sue445/azusaar/util/TestUtil.java b/src/test/java/net/sue445/azusaar/util/TestUtil.java
2175
+ new file mode 100644
2176
+ index 0000000..248b648
2177
+ --- /dev/null
2178
+ +++ b/src/test/java/net/sue445/azusaar/util/TestUtil.java
2179
+ @@ -0,0 +1,38 @@
2180
+ +package net.sue445.azusaar.util;
2181
+ +
2182
+ +import net.sue445.azusaar.model.UserModel;
2183
+ +
2184
+ +import org.slim3.datastore.Datastore;
2185
+ +
2186
+ +import twitter4j.auth.AccessToken;
2187
+ +
2188
+ +public final class TestUtil {
2189
+ + public static String ACCESS_TOKEN = "14540215-QYmH8zti6DVMrhe9EuIII3bdgZ1C3WDghvpF8U6Zo";
2190
+ + public static String ACCESS_TOKEN_SECRET = "JOChFP1uXcnLO6cPN2kSLzbZg64qVJBYjxHVTUVM";
2191
+ + public static final long TWITTER_USER_ID = 14540215;
2192
+ + public static final String SCREEN_NAME = "sue445";
2193
+ +
2194
+ +
2195
+ + public static AccessToken getMockAccessToken(){
2196
+ + return new AccessToken(ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
2197
+ + }
2198
+ +
2199
+ + public static UserModel createUserModel(){
2200
+ + UserModel model = new UserModel(TWITTER_USER_ID);
2201
+ +
2202
+ + model.setScreenName(SCREEN_NAME);
2203
+ + model.setAccessToken(ACCESS_TOKEN);
2204
+ + model.setAccessTokenSecret(ACCESS_TOKEN_SECRET);
2205
+ + model.setAtndId("26669");
2206
+ + model.setZusaarId("agxzfnp1c2Fhci1ocmRyFQsSBFVzZXIiCzE0NTQwMjE1X3R3DA");
2207
+ + model.setEventAtndId("C00000012128");
2208
+ + model.setConnpassId("sue445");
2209
+ + model.setPartakeId("247fe915-dc36-4a9a-a01a-0f6347105633");
2210
+ +
2211
+ + return model;
2212
+ + }
2213
+ +
2214
+ + public static void setUpUserModel(){
2215
+ + Datastore.put(createUserModel());
2216
+ + }
2217
+ +}
2218
+ diff --git a/src/test/java/net/sue445/azusaar/util/TwitterUtilTest.java b/src/test/java/net/sue445/azusaar/util/TwitterUtilTest.java
2219
+ new file mode 100644
2220
+ index 0000000..20120f5
2221
+ --- /dev/null
2222
+ +++ b/src/test/java/net/sue445/azusaar/util/TwitterUtilTest.java
2223
+ @@ -0,0 +1,95 @@
2224
+ +package net.sue445.azusaar.util;
2225
+ +
2226
+ +import static org.hamcrest.CoreMatchers.*;
2227
+ +import static org.junit.Assert.*;
2228
+ +
2229
+ +import javax.servlet.http.Cookie;
2230
+ +
2231
+ +import net.sue445.azusaar.util.SessionUtil.SessionKey;
2232
+ +
2233
+ +import org.junit.Before;
2234
+ +import org.junit.Test;
2235
+ +import org.junit.experimental.runners.Enclosed;
2236
+ +import org.junit.experimental.theories.DataPoints;
2237
+ +import org.junit.experimental.theories.Theories;
2238
+ +import org.junit.experimental.theories.Theory;
2239
+ +import org.junit.runner.RunWith;
2240
+ +import org.slim3.tester.AppEngineTestCase;
2241
+ +import org.slim3.tester.ControllerTestCase;
2242
+ +
2243
+ +import twitter4j.Twitter;
2244
+ +
2245
+ +
2246
+ +@RunWith(Enclosed.class)
2247
+ +public class TwitterUtilTest{
2248
+ + public static class GetTwitter extends AppEngineTestCase {
2249
+ + @Test
2250
+ + public void getTwitter() throws Exception {
2251
+ + Twitter actual = TwitterUtil.getTwitter(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET);
2252
+ + assertThat(actual, is(notNullValue()));
2253
+ + assertThat(actual.verifyCredentials().getScreenName(), is("sue445"));
2254
+ + }
2255
+ + }
2256
+ +
2257
+ + @RunWith(Theories.class)
2258
+ + public static class IsAccessTokenValid extends AppEngineTestCase{
2259
+ + @DataPoints
2260
+ + public static Fixture[] FIXTURES = {
2261
+ + new Fixture(TestUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN_SECRET, true),
2262
+ + new Fixture("", "", false),
2263
+ + new Fixture("aaa", "bbb", false),
2264
+ + };
2265
+ +
2266
+ + static class Fixture{
2267
+ + String accessToken;
2268
+ + String accessTokenSecret;
2269
+ + boolean expected;
2270
+ +
2271
+ + public Fixture(String accessToken, String accessTokenSecret, boolean expected) {
2272
+ + this.accessToken = accessToken;
2273
+ + this.accessTokenSecret = accessTokenSecret;
2274
+ + this.expected = expected;
2275
+ + }
2276
+ + }
2277
+ +
2278
+ + @Theory
2279
+ + public void isAccessTokenValid(Fixture fixture) throws Exception {
2280
+ + boolean actual = TwitterUtil.isAccessTokenValid(fixture.accessToken, fixture.accessTokenSecret);
2281
+ +
2282
+ + String message = "accessToken=" + fixture.accessToken + ", accessTokenSecret=" + fixture.accessTokenSecret;
2283
+ + assertThat(message, actual, is(fixture.expected));
2284
+ + }
2285
+ + }
2286
+ +
2287
+ + public static class WhenHasCookie extends ControllerTestCase {
2288
+ + @Before
2289
+ + public void before() {
2290
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN, TestUtil.ACCESS_TOKEN));
2291
+ + tester.request.addCookie(new Cookie(CookieUtil.ACCESS_TOKEN_SECRET, TestUtil.ACCESS_TOKEN_SECRET));
2292
+ + }
2293
+ +
2294
+ + @Test
2295
+ + public void isAccessTokenValid() throws Exception {
2296
+ + boolean actual = TwitterUtil.isAccessTokenValid(tester.request);
2297
+ +
2298
+ + assertThat(actual, is(true));
2299
+ + }
2300
+ + }
2301
+ +
2302
+ + public static class WhenHasSession extends ControllerTestCase {
2303
+ + @Before
2304
+ + public void before() {
2305
+ + SessionUtil.put(tester.request, SessionKey.ACCESS_TOKEN, TestUtil.getMockAccessToken());
2306
+ + }
2307
+ +
2308
+ + @Test
2309
+ + public void isAccessTokenValid() throws Exception {
2310
+ + boolean actual = TwitterUtil.isAccessTokenValid(tester.request);
2311
+ +
2312
+ + assertThat(actual, is(true));
2313
+ + }
2314
+ + }
2315
+ +
2316
+ +
2317
+ +}
2318
+ diff --git a/war/WEB-INF/appengine-web.xml b/war/WEB-INF/appengine-web.xml
2319
+ index 876aeb7..0fcd3a8 100644
2320
+ --- a/war/WEB-INF/appengine-web.xml
2321
+ +++ b/war/WEB-INF/appengine-web.xml
2322
+ @@ -4 +4 @@
2323
+ - <version>20120611</version>
2324
+ + <version>20120812</version>
2325
+ @@ -24 +24 @@
2326
+ - <sessions-enabled>false</sessions-enabled>
2327
+ + <sessions-enabled>true</sessions-enabled>
2328
+ diff --git a/war/WEB-INF/lib/jstl-1.2.jar b/war/WEB-INF/lib/jstl-1.2.jar
2329
+ new file mode 100644
2330
+ index 0000000..0fd275e
2331
+ Binary files /dev/null and b/war/WEB-INF/lib/jstl-1.2.jar differ
2332
+ diff --git a/war/WEB-INF/lib/s3tiger-0.0.3.jar b/war/WEB-INF/lib/s3tiger-0.0.3.jar
2333
+ deleted file mode 100644
2334
+ index ba4248e..0000000
2335
+ Binary files a/war/WEB-INF/lib/s3tiger-0.0.3.jar and /dev/null differ
2336
+ diff --git a/war/WEB-INF/lib/scenic3-0.5.1.jar b/war/WEB-INF/lib/scenic3-0.5.1.jar
2337
+ new file mode 100644
2338
+ index 0000000..3d65267
2339
+ Binary files /dev/null and b/war/WEB-INF/lib/scenic3-0.5.1.jar differ
2340
+ diff --git a/war/WEB-INF/lib/twitter4j-appengine-2.2.5.jar b/war/WEB-INF/lib/twitter4j-appengine-2.2.5.jar
2341
+ deleted file mode 100644
2342
+ index 4f3da6b..0000000
2343
+ Binary files a/war/WEB-INF/lib/twitter4j-appengine-2.2.5.jar and /dev/null differ
2344
+ diff --git a/war/WEB-INF/lib/twitter4j-appengine-2.2.6.jar b/war/WEB-INF/lib/twitter4j-appengine-2.2.6.jar
2345
+ new file mode 100644
2346
+ index 0000000..86f67aa
2347
+ Binary files /dev/null and b/war/WEB-INF/lib/twitter4j-appengine-2.2.6.jar differ
2348
+ diff --git a/war/WEB-INF/lib/twitter4j-core-2.2.5.jar b/war/WEB-INF/lib/twitter4j-core-2.2.5.jar
2349
+ deleted file mode 100644
2350
+ index 7e9ee6b..0000000
2351
+ Binary files a/war/WEB-INF/lib/twitter4j-core-2.2.5.jar and /dev/null differ
2352
+ diff --git a/war/WEB-INF/lib/twitter4j-core-2.2.6.jar b/war/WEB-INF/lib/twitter4j-core-2.2.6.jar
2353
+ new file mode 100644
2354
+ index 0000000..930183c
2355
+ Binary files /dev/null and b/war/WEB-INF/lib/twitter4j-core-2.2.6.jar differ
2356
+ diff --git a/war/WEB-INF/view/common/common.jsp b/war/WEB-INF/view/common/common.jsp
2357
+ new file mode 100644
2358
+ index 0000000..342d501
2359
+ --- /dev/null
2360
+ +++ b/war/WEB-INF/view/common/common.jsp
2361
+ @@ -0,0 +1,6 @@
2362
+ +<%@page trimDirectiveWhitespaces="true"%>
2363
+ +<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
2364
+ +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
2365
+ +<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
2366
+ +<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
2367
+ +<%@taglib prefix="f" uri="http://www.slim3.org/functions"%>
2368
+
2369
+ diff --git a/war/WEB-INF/view/home/edit.jsp b/war/WEB-INF/view/home/edit.jsp
2370
+ new file mode 100644
2371
+ index 0000000..9835a38
2372
+ --- /dev/null
2373
+ +++ b/war/WEB-INF/view/home/edit.jsp
2374
+ @@ -0,0 +1,55 @@
2375
+ +<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
2376
+ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2377
+ +<html>
2378
+ +<head>
2379
+ +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
2380
+ +
2381
+ +<link rel="stylesheet" href="/css/global.css?20120420" type="text/css"/>
2382
+ +<title>AZusaar! / Home</title>
2383
+ +</head>
2384
+ +<body>
2385
+ +
2386
+ +<!-- header -->
2387
+ +<div class="header">
2388
+ +登録
2389
+ +</div>
2390
+ +<!-- /header -->
2391
+ +
2392
+ +
2393
+ +<!-- main_contents -->
2394
+ +<div class="main_contents">
2395
+ + <form action="${f:url('update')}" method="post">
2396
+ + <dl>
2397
+ + <dt><span class="zusaar">Zusaar</span></dt>
2398
+ + <dd><input type="text" value="${f:h(user.zusaarId)}" name="zusaarId" /></dd>
2399
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://www.zusaar.com/user/&lt;ユーザー名&gt;)</dd>
2400
+ + <dd>例:http://www.zusaar.com/user/agxzfnp1c2Fhci1ocmRyFQsSBFVzZXIiCzE0NTQwMjE1X3R3DA → agxzfnp1c2Fhci1ocmRyFQsSBFVzZXIiCzE0NTQwMjE1X3R3DA</dd>
2401
+ +
2402
+ + <dt><span class="partake">PARTAKE</span></dt>
2403
+ + <dd><input type="text" value="${f:h(user.partakeId)}" name="partakeId" /></dd>
2404
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://partake.in/users/&lt;ユーザー名&gt;)</dd>
2405
+ + <dd>例:http://partake.in/users/247fe915-dc36-4a9a-a01a-0f6347105633 → 247fe915-dc36-4a9a-a01a-0f6347105633</dd>
2406
+ +
2407
+ + <dt><span class="connpass">connpass</span></dt>
2408
+ + <dd><input type="text" value="${f:h(user.connpassId)}" name="connpassId" /></dd>
2409
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://connpass.com/user/&lt;ユーザー名&gt;/)</dd>
2410
+ + <dd>例:http://connpass.com/user/sue445/ → sue445</dd>
2411
+ + </dl>
2412
+ + <input type="submit" value="送信">
2413
+ + </form>
2414
+ + <ul>
2415
+ + <li>ATND, eventATNDのIDはTwitterIDから自動的に設定します</li>
2416
+ + </ul>
2417
+ +</div>
2418
+ +<!-- /main_contents -->
2419
+ +
2420
+ +<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
2421
+ +<script type="text/javascript">
2422
+ +(function($){
2423
+ + $(document).ready(function(){
2424
+ + });
2425
+ +})(jQuery);
2426
+ +</script>
2427
+ +
2428
+ +</body>
2429
+ +</html>
2430
+ diff --git a/war/WEB-INF/view/home/index.jsp b/war/WEB-INF/view/home/index.jsp
2431
+ new file mode 100644
2432
+ index 0000000..fa8700a
2433
+ --- /dev/null
2434
+ +++ b/war/WEB-INF/view/home/index.jsp
2435
+ @@ -0,0 +1,74 @@
2436
+ +<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
2437
+ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2438
+ +<html>
2439
+ +<head>
2440
+ +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
2441
+ +
2442
+ +<link rel="stylesheet" href="/css/global.css?20120420" type="text/css"/>
2443
+ +<title>AZusaar! / Home</title>
2444
+ +</head>
2445
+ +<body>
2446
+ +
2447
+ +<!-- header -->
2448
+ +<div class="header">
2449
+ +<a href="/">トップに戻る</a>
2450
+ +</div>
2451
+ +<!-- /header -->
2452
+ +
2453
+ +
2454
+ +<!-- main_contents -->
2455
+ +<div class="main_contents">
2456
+ + <dl>
2457
+ + <dt><span class="zusaar">Zusaar</span></dt>
2458
+ + <dd>
2459
+ + <c:choose>
2460
+ + <c:when test="${empty user.zusaarId}">
2461
+ + 未登録
2462
+ + </c:when>
2463
+ + <c:otherwise>
2464
+ + <a href="${user.zusaarUrl}">${f:h(user.zusaarId)}</a>
2465
+ + </c:otherwise>
2466
+ + </c:choose>
2467
+ + </dd>
2468
+ +
2469
+ + <dt><span class="partake">PARTAKE</span></dt>
2470
+ + <dd>
2471
+ + <c:choose>
2472
+ + <c:when test="${empty user.partakeId}">
2473
+ + 未登録
2474
+ + </c:when>
2475
+ + <c:otherwise>
2476
+ + <a href="${user.partakeUrl}">${f:h(user.partakeId)}</a>
2477
+ + </c:otherwise>
2478
+ + </c:choose>
2479
+ + </dd>
2480
+ +
2481
+ + <dt><span class="connpass">connpass</span></dt>
2482
+ + <dd>
2483
+ + <c:choose>
2484
+ + <c:when test="${empty user.connpassId}">
2485
+ + 未登録
2486
+ + </c:when>
2487
+ + <c:otherwise>
2488
+ + <a href="${user.connpassUrl}">${f:h(user.connpassId)}</a>
2489
+ + </c:otherwise>
2490
+ + </c:choose>
2491
+ + </dd>
2492
+ + </dl>
2493
+ +
2494
+ + <a href="${f:url('edit')}">ZusaarなどのユーザーIDを登録する</a><br/>
2495
+ + (検索結果のカレンダーに登録済のイベントがハイライトされるようになります)
2496
+ +</div>
2497
+ +<!-- /main_contents -->
2498
+ +
2499
+ +<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
2500
+ +<script type="text/javascript" src="/js/userinfo.js?20120701"></script>
2501
+ +<script type="text/javascript">
2502
+ +(function($){
2503
+ + $(document).ready(function(){
2504
+ + });
2505
+ +})(jQuery);
2506
+ +</script>
2507
+ +
2508
+ +</body>
2509
+ +</html>
2510
+ diff --git a/war/WEB-INF/web.xml b/war/WEB-INF/web.xml
2511
+ index 184a3f6..3dfd91b 100644
2512
+ --- a/war/WEB-INF/web.xml
2513
+ +++ b/war/WEB-INF/web.xml
2514
+ @@ -49,0 +50,4 @@
2515
+ + <filter-name>TwitterOAuthFilter</filter-name>
2516
+ + <filter-class>net.sue445.azusaar.filter.TwitterOAuthFilter</filter-class>
2517
+ + </filter>
2518
+ + <filter>
2519
+ @@ -51 +55 @@
2520
+ - <filter-class>org.slim3.controller.FrontController</filter-class>
2521
+ + <filter-class>org.slim3.controller.ScenicFrontController</filter-class>
2522
+ @@ -74,0 +79,5 @@
2523
+ + <filter-name>TwitterOAuthFilter</filter-name>
2524
+ + <url-pattern>/home/*</url-pattern>
2525
+ + <dispatcher>REQUEST</dispatcher>
2526
+ + </filter-mapping>
2527
+ + <filter-mapping>
2528
+ @@ -142,0 +152,10 @@
2529
+ +
2530
+ + <jsp-config>
2531
+ + <jsp-property-group>
2532
+ + <url-pattern>*.jsp</url-pattern>
2533
+ + <el-ignored>false</el-ignored>
2534
+ + <page-encoding>UTF-8</page-encoding>
2535
+ + <scripting-invalid>false</scripting-invalid>
2536
+ + <include-prelude>/WEB-INF/view/common/common.jsp</include-prelude>
2537
+ + </jsp-property-group>
2538
+ + </jsp-config>
2539
+ diff --git a/war/_home/edit.html b/war/_home/edit.html
2540
+ new file mode 100644
2541
+ index 0000000..001f87c
2542
+ --- /dev/null
2543
+ +++ b/war/_home/edit.html
2544
+ @@ -0,0 +1,61 @@
2545
+ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2546
+ +<html>
2547
+ +<head>
2548
+ +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
2549
+ +
2550
+ +<link rel="stylesheet" href="../css/global.css?20120420" type="text/css"/>
2551
+ +<title>AZusaar! / Home</title>
2552
+ +</head>
2553
+ +<body>
2554
+ +
2555
+ +<!-- header -->
2556
+ +<div class="header">
2557
+ +登録
2558
+ +</div>
2559
+ +<!-- /header -->
2560
+ +
2561
+ +
2562
+ +<!-- main_contents -->
2563
+ +<div class="main_contents">
2564
+ + <form action="regist" method="post">
2565
+ + <dl>
2566
+ + <dt><img src="../img/atnd_ico.png" />ATND BETA</dt>
2567
+ + <dd><input type="text" value="" id="atnd" name="atnd" /></dd>
2568
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://atnd.org/users/&lt;ユーザー名&gt;)</dd>
2569
+ + <dd>例:http://atnd.org/users/26669 → 26669</dd>
2570
+ +
2571
+ + <dt><img src="../img/eventatnd_ico.png" />eventATND</dt>
2572
+ + <dd><input type="text" value="" id="eventatnd" name="eventatnd" /></dd>
2573
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://atnd.org/event/profile/&lt;ユーザー名&gt;)</dd>
2574
+ + <dd>例:http://atnd.org/event/profile/C00000012128 → C00000012128</dd>
2575
+ +
2576
+ + <dt><img src="../img/zusaar_ico.png" />Zusaar</dt>
2577
+ + <dd><input type="text" value="" id="zusaar" name="zusaar" /></dd>
2578
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://www.zusaar.com/user/&lt;ユーザー名&gt;)</dd>
2579
+ + <dd>例:http://www.zusaar.com/user/agxzfnp1c2Fhci1ocmRyFQsSBFVzZXIiCzE0NTQwMjE1X3R3DA → agxzfnp1c2Fhci1ocmRyFQsSBFVzZXIiCzE0NTQwMjE1X3R3DA</dd>
2580
+ +
2581
+ + <dt><img src="../img/partake_ico.png" />PARTAKE</dt>
2582
+ + <dd><input type="text" value="" id="partake" name="partake" /></dd>
2583
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://partake.in/users/&lt;ユーザー名&gt;)</dd>
2584
+ + <dd>例:http://partake.in/users/247fe915-dc36-4a9a-a01a-0f6347105633 → 247fe915-dc36-4a9a-a01a-0f6347105633</dd>
2585
+ +
2586
+ + <dt><img src="../img/connpass_ico.png" />connpass</dt>
2587
+ + <dd><input type="text" value="" id="connpass" name="connpass" /></dd>
2588
+ + <dd>プロフィールページのURL中のユーザー名を入れてください (http://connpass.com/user/&lt;ユーザー名&gt;/)</dd>
2589
+ + <dd>例:http://connpass.com/user/sue445/ → sue445</dd>
2590
+ + </dl>
2591
+ + <input type="submit" value="送信">
2592
+ + </form>
2593
+ +</div>
2594
+ +<!-- /main_contents -->
2595
+ +
2596
+ +<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
2597
+ +<script type="text/javascript">
2598
+ +(function($){
2599
+ + $(document).ready(function(){
2600
+ + });
2601
+ +})(jQuery);
2602
+ +</script>
2603
+ +
2604
+ +</body>
2605
+ +</html>
2606
+ diff --git a/war/css/global.css b/war/css/global.css
2607
+ index 2d05131..e64eaa3 100644
2608
+ --- a/war/css/global.css
2609
+ +++ b/war/css/global.css
2610
+ @@ -0,0 +1 @@
2611
+ +
2612
+ @@ -248,0 +250,36 @@ label.connpass {
2613
+ +span.atnd {
2614
+ + background-image: url(../img/atnd_ico.png);
2615
+ + background-repeat: no-repeat;
2616
+ + padding-left: 16px;
2617
+ +}
2618
+ +
2619
+ +span.eventatnd {
2620
+ + background-image: url(../img/eventatnd_ico.png);
2621
+ + background-repeat: no-repeat;
2622
+ + padding-left: 16px;
2623
+ +}
2624
+ +
2625
+ +span.zusaar {
2626
+ + background-image: url(../img/zusaar_ico.png);
2627
+ + background-repeat: no-repeat;
2628
+ + padding-left: 16px;
2629
+ +}
2630
+ +
2631
+ +span.kokucheese {
2632
+ + background-image: url(../img/kokucheese_ico.png);
2633
+ + background-repeat: no-repeat;
2634
+ + padding-left: 16px;
2635
+ +}
2636
+ +
2637
+ +span.partake {
2638
+ + background-image: url(../img/partake_ico.png);
2639
+ + background-repeat: no-repeat;
2640
+ + padding-left: 16px;
2641
+ +}
2642
+ +
2643
+ +span.connpass {
2644
+ + background-image: url(../img/connpass_ico.png);
2645
+ + background-repeat: no-repeat;
2646
+ + padding-left: 16px;
2647
+ +}
2648
+ +
2649
+ diff --git a/war/index.html b/war/index.html
2650
+ index 19db41c..110d3b7 100644
2651
+ --- a/war/index.html
2652
+ +++ b/war/index.html
2653
+ @@ -48,6 +48,6 @@ if(userAgent && userAgent.match(/(iPod|iPhone|Android)/i)){
2654
+ - <a href="http://atnd.org/beta/"><img src="./img/atnd_ico.png" />ATND</a>
2655
+ - <a href="http://atnd.org/"><img src="./img/eventatnd_ico.png" />eventATND</a>
2656
+ - <a href="http://www.zusaar.com/"><img src="./img/zusaar_ico.png" />Zusaar</a>
2657
+ - <a href="http://kokucheese.com/"><img src="./img/kokucheese_ico.png" />こくちーず</a>
2658
+ - <a href="http://partake.in/"><img src="./img/partake_ico.png" />PARTAKE</a>
2659
+ - <a href="http://connpass.com/"><img src="./img/connpass_ico.png" />connpass</a>
2660
+ + <a href="http://atnd.org/beta/"><span class="atnd">ATND</span></a>
2661
+ + <a href="http://atnd.org/"><span class="eventatnd">eventATND</span></a>
2662
+ + <a href="http://www.zusaar.com/"><span class="zusaar">Zusaar</span></a>
2663
+ + <a href="http://kokucheese.com/"><span class="kokucheese">こくちーず</span></a>
2664
+ + <a href="http://partake.in/"><span class="partake">PARTAKE</span></a>
2665
+ + <a href="http://connpass.com/"><span class="connpass">connpass</span></a>
2666
+ diff --git a/war/js/userinfo.js b/war/js/userinfo.js
2667
+ new file mode 100644
2668
+ index 0000000..a8c996b
2669
+ --- /dev/null
2670
+ +++ b/war/js/userinfo.js
2671
+ @@ -0,0 +1,44 @@
2672
+ +if (!this.azusaar) {
2673
+ + var azusaar = {};
2674
+ +}
2675
+ +
2676
+ +azusaar.userinfo = (function() {
2677
+ + // public methods
2678
+ + function dispHeader(){
2679
+ + $.ajax({
2680
+ + async : true,
2681
+ + type : "POST",
2682
+ + url : "/auth/userInfo",
2683
+ + dataType : "json"
2684
+ + }).done(function(res, status){
2685
+ + if(status != "success"){
2686
+ + return;
2687
+ + }
2688
+ +
2689
+ + if(res.screenName){
2690
+ + // logined
2691
+ + $("#userInfoArea").append(
2692
+ + $("<b/>").text(res.screenName).after( $("<span/>").text("でログイン中") )
2693
+ + );
2694
+ + $("#userInfoArea").append("&nbsp;");
2695
+ + $("#userInfoArea").append(
2696
+ + $("<a/>").attr("href", "/home/").text("ホーム")
2697
+ + );
2698
+ + $("#userInfoArea").append("&nbsp;");
2699
+ + $("#userInfoArea").append(
2700
+ + $("<a/>").attr("href", "/auth/logout").text("ログアウト")
2701
+ + );
2702
+ + } else{
2703
+ + // not logined
2704
+ + $("#userInfoArea").append(
2705
+ + $("<a/>").attr("href", "/home/").text("Twitterアカウントでログイン")
2706
+ + );
2707
+ + }
2708
+ + });
2709
+ +
2710
+ + }
2711
+ +
2712
+ + return {
2713
+ + dispHeader : dispHeader
2714
+ + };
2715
+ +}());