/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fujitsu.dc.test.jersey.cell.auth; import static org.junit.Assert.assertEquals; import java.util.HashMap; import javax.ws.rs.core.HttpHeaders; import org.apache.http.HttpStatus; import org.json.simple.JSONObject; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import com.fujitsu.dc.common.auth.token.AbstractOAuth2Token.TokenParseException; import com.fujitsu.dc.common.utils.DcCoreUtils; import com.fujitsu.dc.core.auth.OAuth2Helper; import com.fujitsu.dc.test.categories.Integration; import com.fujitsu.dc.test.categories.Regression; import com.fujitsu.dc.test.categories.Unit; import com.fujitsu.dc.test.jersey.AbstractCase; import com.fujitsu.dc.test.jersey.DcException; import com.fujitsu.dc.test.jersey.DcResponse; import com.fujitsu.dc.test.jersey.DcRestAdapter; import com.fujitsu.dc.test.jersey.DcRunner; import com.fujitsu.dc.test.setup.Setup; import com.fujitsu.dc.test.unit.core.UrlUtils; import com.fujitsu.dc.test.utils.AccountUtils; import com.fujitsu.dc.test.utils.CellUtils; import com.fujitsu.dc.test.utils.DavResourceUtils; import com.fujitsu.dc.test.utils.Http; import com.fujitsu.dc.test.utils.ResourceUtils; import com.fujitsu.dc.test.utils.TResponse; import com.sun.jersey.test.framework.JerseyTest; /** * パスワード変更APIのテスト. */ @RunWith(DcRunner.class) @Category({Unit.class, Integration.class, Regression.class }) public class MyPasswordTest extends JerseyTest { private static final String MASTER_TOKEN = AbstractCase.MASTER_TOKEN_NAME; private static final String UNIT_USER_CELL = "UnitUserCell"; /** * コンストラクタ. */ public MyPasswordTest() { super("com.fujitsu.dc.core.rs"); } /** * 自分セルローカルトークン認証でパスワード変更を実行し204が返ること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 自分セルローカルトークン認証でパスワード変更を実行し204が返ること() throws TokenParseException { try { // Account作成 AccountUtils.create(MASTER_TOKEN, Setup.TEST_CELL1, "PasswordTest", "password", 201); // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "PasswordTest", "password", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); Long lastAuthenticatedTime = AuthTestCommon.getAccountLastAuthenticated(Setup.TEST_CELL1, "PasswordTest"); DcResponse res = requesttoMypassword(tokenStr, "newPassword", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); AuthTestCommon.accountLastAuthenticatedNotUpdatedCheck( Setup.TEST_CELL1, "PasswordTest", lastAuthenticatedTime); // 確認 // TODO 仕様の問題で変更前のトークンが有効となっているため確認未実施 // 1.変更前のパスワードのセルローカルトークンを使用して403となること // res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); // assertEquals(403, res.getStatusCode()); // 2.変更後のパスワードのセルローカルトークンでアカウントの取得を実行して200となること // 認証 resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "PasswordTest", "newPassword", -1); // セルローカルトークンを取得する tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); } finally { AccountUtils.delete(Setup.TEST_CELL1, MASTER_TOKEN, "PasswordTest", 204); } } /** * 記号を含むアカウントの自分セルローカルトークン認証でパスワード変更を実行し204が返ること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 記号を含むアカウントの自分セルローカルトークン認証でパスワード変更を実行し204が返ること() throws TokenParseException { // エスケープする前のNameは、abcde12345-_!$*=^`{|}~.@ String testAccountName = "abcde12345\\-\\_\\!\\$\\*\\=\\^\\`\\{\\|\\}\\~.\\@"; String encodedtestAccountName = "abcde12345-_%21%24%2A%3D%5E%60%7B%7C%7D%7E.%40"; try { // Account作成 AccountUtils.create(MASTER_TOKEN, Setup.TEST_CELL1, testAccountName, "password", 201); // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, testAccountName, "password", HttpStatus.SC_OK); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, "newPassword", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); // 確認 // TODO 仕様の問題で変更前のトークンが有効となっているため確認未実施 // 1.変更前のパスワードのセルローカルトークンを使用して403となること // res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); // assertEquals(403, res.getStatusCode()); // 2.変更後のパスワードのセルローカルトークンでアカウントの取得を実行して200となること // 認証 resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, testAccountName, "newPassword", HttpStatus.SC_OK); // セルローカルトークンを取得する tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); } finally { AccountUtils.delete(Setup.TEST_CELL1, MASTER_TOKEN, encodedtestAccountName, 204); } } /** * 他人セルローカルトークン認証でパスワード変更を実行し403が返ること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 他人セルローカルトークン認証でパスワード変更を実行し403が返ること() throws TokenParseException { // 他人セルローカルトークン取得 TResponse res = Http.request("authn/password-tc-c0.txt") .with("remoteCell", Setup.TEST_CELL1) .with("username", "account1") .with("password", "password1") .with("dc_target", UrlUtils.cellRoot(Setup.TEST_CELL2)) .returns() .statusCode(HttpStatus.SC_OK); JSONObject json = res.bodyAsJson(); String transCellAccessToken = (String) json.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse response = requesttoMypassword(transCellAccessToken, "newPassword", Setup.TEST_CELL1); assertEquals(403, response.getStatusCode()); } /** * ユニットローカルユニットユーザトークン認証でパスワード変更を実行し403が返ること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void ユニットローカルユニットユーザトークン認証でパスワード変更を実行し403が返ること() throws TokenParseException { // 認証 // アカウントにユニット昇格権限付与 DavResourceUtils.setProppatch(Setup.TEST_CELL1, MASTER_TOKEN, "cell/proppatch-uluut.txt", HttpStatus.SC_MULTI_STATUS); // パスワード認証でのユニット昇格 TResponse tokenResponse = Http.request("authnUnit/password-uluut.txt") .with("remoteCell", Setup.TEST_CELL1) .with("username", "account1") .with("password", "password1") .returns() .statusCode(HttpStatus.SC_OK); JSONObject json = tokenResponse.bodyAsJson(); String uluut = (String) json.get(OAuth2Helper.Key.ACCESS_TOKEN); // ユニットローカルユニットユーザトークンを取得する DcResponse res = requesttoMypassword(uluut, "password3", Setup.TEST_CELL1); assertEquals(403, res.getStatusCode()); } /** * ユニットユーザトークン認証でパスワード変更を実行し403が返ること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void ユニットユーザトークン認証でパスワード変更を実行し403が返ること() throws TokenParseException { try { // 本テスト用セルの作成 CellUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_CREATED); // アカウント追加 AccountUtils.create(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL, "Account", "AccountPass", HttpStatus.SC_CREATED); // 認証(ユニットユーザートークン取得) TResponse res = Http.request("authn/password-tc-c0.txt") .with("remoteCell", UNIT_USER_CELL) .with("username", "Account") .with("password", "AccountPass") .with("dc_target", UrlUtils.unitRoot()) .returns() .statusCode(HttpStatus.SC_OK); JSONObject json = res.bodyAsJson(); String unitUserToken = (String) json.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse response = requesttoMypassword(unitUserToken, "newPassword", Setup.TEST_CELL1); assertEquals(403, response.getStatusCode()); } finally { // アカウント削除 AccountUtils.delete(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, "Account", -1); // 本テスト用セルの削除 CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL, -1); } } /** * マスタトークン認証でパスワード変更を実行し403が返ること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void マスタトークン認証でパスワード変更を実行し403が返ること() throws TokenParseException { DcResponse res = requesttoMypassword(MASTER_TOKEN, "password3", Setup.TEST_CELL1); assertEquals(403, res.getStatusCode()); } /** * 不正なトークンでパスワード変更を実行し401が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 不正なトークンでパスワード変更を実行し401が返却されること() throws TokenParseException { DcResponse res = requesttoMypassword("passwordhoge", "accountpass", Setup.TEST_CELL1); assertEquals(401, res.getStatusCode()); } /** * 新しいパスワードが5文字の時にパスワード変更を実行し400が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 新しいパスワードが5文字の時にパスワード変更を実行し400が返却されること() throws TokenParseException { // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "account10", "password10", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, "hogea", Setup.TEST_CELL1); assertEquals(400, res.getStatusCode()); } /** * 新しいパスワードが6文字の時にパスワード変更を実行し204が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 新しいパスワードが6文字の時にパスワード変更を実行し204が返却されること() throws TokenParseException { try { // Account作成 AccountUtils.create(MASTER_TOKEN, Setup.TEST_CELL1, "PasswordTest", "password", 201); // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "PasswordTest", "password", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, "hogeaa", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); // 確認 // TODO 仕様の問題で変更前のトークンが有効となっているため確認未実施 // 1.変更前のパスワードのセルローカルトークンを使用して403となること // res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); // assertEquals(403, res.getStatusCode()); // 2.変更後のパスワードのセルローカルトークンでアカウントの取得を実行して200となること // 認証 resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "PasswordTest", "hogeaa", -1); // セルローカルトークンを取得する tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); } finally { AccountUtils.delete(Setup.TEST_CELL1, MASTER_TOKEN, "PasswordTest", 204); } } /** * 新しいパスワードが32文字の時にパスワード変更を実行し204が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 新しいパスワードが32文字の時にパスワード変更を実行し204が返却されること() throws TokenParseException { try { // Account作成 AccountUtils.create(MASTER_TOKEN, Setup.TEST_CELL1, "PasswordTest", "password", 201); // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "PasswordTest", "password", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, "12345678901234567890123456789012", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); // 変更前のパスワードのセルローカルトークンを使用して403となること // 確認 // TODO 仕様の問題で変更前のトークンが有効となっているため確認未実施 // 1.変更前のパスワードのセルローカルトークンを使用して403となること // res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); // assertEquals(403, res.getStatusCode()); // 2.変更後のパスワードのセルローカルトークンでアカウントの取得を実行して200となること // 認証 resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "PasswordTest", "12345678901234567890123456789012", -1); // セルローカルトークンを取得する tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); res = requesttoMypassword(tokenStr, "newPassword1", Setup.TEST_CELL1); assertEquals(204, res.getStatusCode()); } finally { AccountUtils.delete(Setup.TEST_CELL1, MASTER_TOKEN, "PasswordTest", 204); } } /** * 新しいパスワードが33文字の時にパスワード変更を実行し400が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 新しいパスワードが33文字の時にパスワード変更を実行し400が返却されること() throws TokenParseException { // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "account10", "password10", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, "123456789012345678901234567890123", Setup.TEST_CELL1); assertEquals(400, res.getStatusCode()); } /** * 他セルの同名アカウントのパスワードでパスワード変更を実行し401が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void 他セルの同名アカウントのパスワードでパスワード変更を実行し401が返却されること() throws TokenParseException { String cellName1 = "passcell1"; String cellName2 = "passcell2"; try { // Cell作成 CellUtils.create(cellName1, MASTER_TOKEN, 201); CellUtils.create(cellName2, MASTER_TOKEN, 201); // Account作成 AccountUtils.create(MASTER_TOKEN, cellName1, "PasswordTest", "password", 201); AccountUtils.create(MASTER_TOKEN, cellName2, "PasswordTest", "password", 201); // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(cellName2, "PasswordTest", "password", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, "password1", cellName1); assertEquals(401, res.getStatusCode()); } finally { AccountUtils.delete(cellName1, MASTER_TOKEN, "PasswordTest", 204); AccountUtils.delete(cellName2, MASTER_TOKEN, "PasswordTest", 204); CellUtils.delete(MASTER_TOKEN, cellName1); CellUtils.delete(MASTER_TOKEN, cellName2); } } /** * Credentialヘッダのキーが空でパスワード変更を実行し400が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void Credentialヘッダのキーが空でパスワード変更を実行し400が返却されること() throws TokenParseException { // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "account10", "password10", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcResponse res = requesttoMypassword(tokenStr, null, Setup.TEST_CELL1); assertEquals(400, res.getStatusCode()); } /** * Credentialヘッダの指定なしでパスワード変更を実行し400が返却されること. * @throws TokenParseException 認証用トークンのパースエラー */ @Test public final void Credentialヘッダの指定なしでパスワード変更を実行し400が返却されること() throws TokenParseException { // 認証 JSONObject resBody = ResourceUtils.getLocalTokenByPassAuth(Setup.TEST_CELL1, "account10", "password10", -1); // セルローカルトークンを取得する String tokenStr = (String) resBody.get(OAuth2Helper.Key.ACCESS_TOKEN); DcRestAdapter rest = new DcRestAdapter(); DcResponse res = null; // リクエストヘッダをセット HashMap<String, String> requestheaders = new HashMap<String, String>(); requestheaders.put(HttpHeaders.AUTHORIZATION, "Bearer " + tokenStr); try { res = rest.put(UrlUtils.cellRoot(Setup.TEST_CELL1) + "__mypassword", "", requestheaders); } catch (DcException e) { e.printStackTrace(); } assertEquals(400, res.getStatusCode()); } /** * __mypasswordへのリクエストする. * @param headerAuthorization トークン * @param headerCredential 変更後のパスワード * @param requestCellName cell名 * @return レスポンス */ private DcResponse requesttoMypassword(String headerAuthorization, String headerCredential, String requestCellName) { DcRestAdapter rest = new DcRestAdapter(); DcResponse res = null; if (headerAuthorization == null) { headerAuthorization = ""; } if (headerCredential == null) { headerCredential = ""; } // リクエストヘッダをセット HashMap<String, String> requestheaders = new HashMap<String, String>(); requestheaders.put(HttpHeaders.AUTHORIZATION, "Bearer " + headerAuthorization); requestheaders.put(DcCoreUtils.HttpHeaders.X_DC_CREDENTIAL, headerCredential); try { res = rest.put(UrlUtils.cellRoot(requestCellName) + "__mypassword", "", requestheaders); } catch (DcException e) { e.printStackTrace(); } return res; } }