package org.ntlab.tampoposerver.resources;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.ntlab.tampoposerver.models.FriendPair;
import org.ntlab.tampoposerver.models.UserDTO;
import org.ntlab.tampoposerver.repositories.UserRepository;
import org.ntlab.tampoposerver.models.User;
import org.ntlab.tampoposerver.services.FriendService;
import org.ntlab.tampoposerver.utils.Base64Decode;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
//import static io.micrometer.common.util.StringUtils.isBlank;
import static org.apache.logging.log4j.util.Strings.isBlank;
/*
//6/10報告:全部できた(friendまで)、UserRepositoryとの連携ができていない(updateあります?)、responseがない
//6/17報告:すべてのユーザーの情報を持ってくるところ、フレンドペアの自分じゃない方のuidを返すところ、フレンドペアの削除はもらったものを連携できていない
マスタからこのブランチへと取り込む
ブランチ checkout
masterからブランチへ引き込む
Git → Merge → git merge origin/master
別のクラスへのアクセス方法
コンストラクタを作る
import class
コンストラクタの上に@Autowired これを入れるとspring bootが管理しているuserRepositoryのインスタンスを渡してくれる
Repository側の説明 Repositoryをつけるとspring bootがインスタンスを1個だけ勝手に作ってくれる シングルトン
変数名は先頭小文字
未コミットの編集→スタッシュで書き換えてしまったコードを退避させることができる
ポストマンでテスト
1.
*/
@Path("/users")
@Component
public class UsersResource implements ApplicationContextAware {
private org.springframework.context.ApplicationContext applicationContext;
public void setApplicationContext(org.springframework.context.ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
private final UserRepository userRepository;
private final FriendService friendService;
@Autowired
public UsersResource(UserRepository userRepository,
FriendService friendService) { //インスタンスを作るときに呼び出されるメソッドであるコンストラクタを書く
this.userRepository = userRepository;
this.friendService = friendService;
}
//@Path("/{uid}/..")などパスを指定する
//アカウントの基本情報
@GET
@Produces(MediaType.APPLICATION_JSON)
/*関数の名前を適切なものに変更する
関数の引数に@PathParam("uid") String uidのような形でパラメーターを定義しておく
Queryの場合は@QueryParam("filter") String filter
repositoryのメソッド名:add, get, delete
本来の流れはインターフェースだけ決めておく メソッド名と引数名*/
public Response getUsers() {
List<String> users = userRepository.getAllUsers();
if (users.isEmpty()) {
return Response.noContent().build();
}
return Response.ok(users).build();
}
//新規アカウントを作る
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createUser(@FormParam("user-id") String userId, @FormParam("password") String password) {
if (isBlank(userId) || isBlank(password)) {
throw new WebApplicationException(
Response.status(Response.Status.BAD_REQUEST)
.entity("ユーザーIDおよびパスワードを入力してください")
.build());
}
//ユーザーIDが存在しているか調べる
// ArrayList userIdList = new ArrayList();
// userIdList.add(userRepository.getAllUsers());
// for (int i = 0; i < userIdList.size(); i++) {
// if(userId.equals(userIdList.get(i).toString())) {
// throw new WebApplicationException(Response.Status.CONFLICT);
// }
// }
User existingUser = userRepository.getUser(userId);
if (existingUser != null) {
return Response.status(Response.Status.CONFLICT)
.entity("ユーザーIDが重複しています")
.build();
}
User newUser = userRepository.addUser(userId, password);
//6/12ここはswaggerではなくコードを仕様にすると決定しました。
//return Response.ok(user.login(), MediaType.APPLICATION_JSON).build();
return Response.status(Response.Status.CREATED)
.entity(newUser) // 仮に JSON を返したい場合
.build();
}
//単一アカウントの情報を返す
@GET
@Path("/{user-id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response getUser(@PathParam("user-id") String userId) {
//取得
User user = userRepository.getUser(userId);
//存在の確認
if (user == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
UserDTO userDTO = new UserDTO(user);
return Response.ok(userDTO, MediaType.APPLICATION_JSON).build();
}
//ユーザの削除 ok
@DELETE
//deleteはquery parameter
@Path("/{user-id}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteUser(@PathParam("user-id") String userId, @QueryParam("token") String token) {
//取得
User user = userRepository.getUser(userId);
//存在チェック
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("404 IDが存在しません")
.build()
);
}
if (!token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("401 認証失敗")
.build()
);
}
//削除処理
userRepository.deleteUser(userId);
return Response.noContent().build();
}
//ログイン
@POST
@Path("/{user-id}/login")
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response login(@PathParam("user-id") String userId, @FormParam("password") String password) {
if (userId == null || userId.isBlank()) {
throw new WebApplicationException(
Response.status(Response.Status.BAD_REQUEST)
.entity("user-id は必須です")
.build());
}
if (password == null || password.isBlank()) {
throw new WebApplicationException(
Response.status(Response.Status.BAD_REQUEST)
.entity("password は必須です")
.build());
}
//存在チェック
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("IDが存在しません")
.build()
);
}
//パスワードチェック 適切なステータスはなんですか?
if (!password.equals(user.getPassword())) {
throw new WebApplicationException(
Response.status(Response.Status.UNAUTHORIZED)
.entity("パスワードが間違っています")
.build()
);
}
//トークン発行
String token = user.login();
return Response.ok(token).build();
}
//アカウントのニックネームの取得 ok
@GET
@Path("/{user-id}/name")
@Produces(MediaType.TEXT_PLAIN)
public Response getName(@PathParam("user-id") String userId) {
//取得
User user = userRepository.getUser(userId);
//存在チェック
if (user == null) {
throw new WebApplicationException(
Response.Status.NOT_FOUND
);
}
return Response.ok(user.getName(), MediaType.TEXT_PLAIN).build();
}
//ニックネームの変更
@PUT
@Path("/{user-id}/name")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response updateName(@PathParam("user-id") String userId, @FormParam("new-name") String newName, @FormParam("token") String token) {
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("ユーザーが存在しません")
.build()
);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
//ニックネームアップデート
user.setName(newName);
return Response.ok(user.getName(), MediaType.TEXT_PLAIN).build();
}
//単一アカウントのパスワードの取得 ok
@GET
@Path("/{user-id}/password")
@Produces(MediaType.TEXT_PLAIN)
public Response getPassword(@PathParam("user-id") String userId, @QueryParam("token") String token) {
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
return Response.ok(user.getPassword(), MediaType.TEXT_PLAIN).build();
}
//指定されたIDのパスワードを変更する
@PUT
@Path("/{user-id}/password")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response updatePassword(@PathParam("user-id") String userId, @FormParam("new-password") String newPassword, @FormParam("token") String token) {
if (newPassword == null || newPassword.isBlank()) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("ユーザーが存在しません")
.build()
);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
//パスワードのアップデート
user.setPassword(newPassword);
return Response.ok().build();
}
//単一アカウントのemailの取得
@GET
@Path("/{user-id}/email")
@Produces(MediaType.TEXT_PLAIN)
public Response getEmail(@PathParam("user-id") String userId, @QueryParam("token") String token) {
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
return Response.ok(user.getEmail(), MediaType.TEXT_PLAIN).build();
}
//指定されたIDのemailを変更する
@PUT
@Path("/{user-id}/email")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_PLAIN)
public Response updateEmail(@PathParam("user-id") String userId, @FormParam("new-email") String newEmail, @FormParam("token") String token) {
if (newEmail == null || newEmail.isBlank()) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("ユーザーが存在しません")
.build()
);
}
//メールアドレスの重複チェック
ArrayList<String> userEmailLists = userRepository.getAllEmails();
for (String userEmailList : userEmailLists) {
if (userEmailList != null && userEmailList.equals(newEmail)) {
throw new WebApplicationException(Response.status(Response.Status.CONFLICT).entity("emailが重複しています").build());
//return Response.status(Response.Status.CONFLICT).entity("emailが重複しています").build();
}
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
//emailアップデート
user.setEmail(newEmail);
return Response.ok(user.getEmail(), MediaType.TEXT_PLAIN).build();
}
//指定されたIDのアイコンを返す
@GET
@Path("/{user-id}/icon")
@Produces(MediaType.TEXT_PLAIN)
public Response getIcon(@PathParam("user-id") String userId) {
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return Response.ok(user.getIcon(), MediaType.TEXT_PLAIN).build();
}
//アイコンを変更する
@PUT
@Path("/{user-id}/icon")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String updateIcon(@PathParam("user-id") String userId, @FormParam("new-icon") String newIcon, @FormParam("token") String token) {
if (newIcon == null || newIcon.isBlank()) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
User user = userRepository.getUser(userId);
String pathDirectory = "";
String iconPath = "";
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("ユーザーが存在しません")
.build()
);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
//アイコンを変更する
try {
String currentDirectory = System.getProperty("user.dir");
java.nio.file.Path root = Paths.get(currentDirectory);
//binFolder内のstartup.shから起動した場合、起動ディレクトリがbinになるので、親ディレクトリに戻る
if(root.endsWith("bin")){
root = root.getParent();
}
//今まではnitta-labが起動ディレクトリだったので、その場合にtomcatディレクトリに移動する
else if(root.endsWith("nitta-lab")){
root = root.resolve("apache-tomcat-9.0.10");
}
File webappsFolder = new File(root.toFile(),"webapps");
File dataFolder = new File(webappsFolder,"tampopo-data");
pathDirectory = dataFolder.getAbsolutePath();
System.out.println(pathDirectory);
//pathDirectory = applicationContext.getResource("file:").getFile().getAbsolutePath() + "/apache-tomcat-9.0.10/webapps/tampopo-data";
iconPath = Base64Decode.saveIcon(userId, pathDirectory, newIcon);
user.setIcon("http://nitta-lab-www.is.konan-u.ac.jp/tampopo-data/" + iconPath);
} catch (IOException e){
e.printStackTrace();
throw new WebApplicationException(500);
}
return Response.ok(user.getIcon(), MediaType.TEXT_PLAIN).build().toString();
}
//フレンド相手の情報を一覧取得
@GET
@Path("/{user-id}/friends")
@Produces(MediaType.APPLICATION_JSON)
public Response getFriends(@PathParam("user-id") String userId, @QueryParam("token") String token) {
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("ユーザーが存在しません")
.build()
);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
//pairIdを取ってきて自分じゃない方のuserIdを渡す
List<String> friendIds = friendService.getFriendIds(token, userId);
if (friendIds == null) { // 認証失敗 or ユーザ無し
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗またはユーザ不一致")
.build());
}
return Response
.ok(friendIds, MediaType.APPLICATION_JSON)
.build();
}
//特定のペアの自分以外のuidを返す
@GET
@Path("/{user-id}/friends/{pair-id}")
@Produces(MediaType.TEXT_PLAIN)
public Response getPairId(@PathParam("user-id") String userId, @QueryParam("token") String token, @PathParam("pair-id") String pairId) {
if (pairId == null || pairId.isBlank()) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
User user = userRepository.getUser(userId);
if (user == null) {
throw new WebApplicationException(
Response.status(Response.Status.NOT_FOUND)
.entity("ユーザーが存在しません")
.build()
);
}
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
ArrayList<FriendPair> pairIds = user.getFriendPairs();
//pairIdsの中からparameterのpair-idで完全一致させてそれをreturnする
int pairIdInt;
try {
pairIdInt = Integer.parseInt(pairId);
} catch (NumberFormatException e) {
throw new WebApplicationException(
Response.status(Response.Status.BAD_REQUEST)
.entity("pair-id は整数で指定してください")
.build());
}
FriendPair pair = friendService.getFriendPair(token, pairIdInt);
if (pair == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
String otherUserId = pair.getUser0Id().equals(userId) ? pair.getUser1Id() : pair.getUser0Id();
// JSON で返す
return Response.ok(otherUserId, MediaType.TEXT_PLAIN).build();
}
//ペアの削除
@DELETE
@Path("/{user-id}/friends/{pair-id}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteFriends(@PathParam("user-id") String userId, @PathParam("pair-id") Integer pairId, @QueryParam("token") String token) {
if (pairId == null || pairId <= 0) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
User user = userRepository.getUser(userId);
if (user == null) {
throw new NotFoundException("IDが存在しません");
}
//トークン認証
if (token == null || !token.equals(user.getToken())) {
throw new WebApplicationException(
Response.status(Response.Status.FORBIDDEN)
.entity("認証失敗")
.build()
);
}
boolean removed = friendService.removeFriendPair(token, pairId);
if (!removed) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return Response.noContent().build();
}
}