/* * Copyright (C) 2008-2017, Juick * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package com.juick.server.api; import com.juick.Message; import com.juick.Status; import com.juick.ExternalToken; import com.juick.User; import com.juick.server.helpers.AnonymousUser; import com.juick.server.util.HttpBadRequestException; import com.juick.server.util.HttpForbiddenException; import com.juick.service.MessagesService; import com.juick.service.PushQueriesService; import com.juick.service.SubscriptionService; import com.juick.server.util.UserUtils; import com.juick.service.UserService; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import javax.inject.Inject; import java.io.IOException; import java.security.Principal; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; /** * Created by vitalyster on 24.10.2016. */ @RestController public class Notifications { @Inject private PushQueriesService pushQueriesService; @Inject private MessagesService messagesService; @Inject private SubscriptionService subscriptionService; @Inject private UserService userService; private User collectTokens(Integer uid) { User user = userService.getUserByUID(uid).orElse(AnonymousUser.INSTANCE); user.setUnreadCount(messagesService.getUnread(user).size()); pushQueriesService.getGCMRegID(uid).forEach(t -> user.getTokens().add(new ExternalToken(null, "gcm", t, null))); pushQueriesService.getAPNSToken(uid).forEach(t -> user.getTokens().add(new ExternalToken(null, "apns", t, null))); pushQueriesService.getMPNSURL(uid).forEach(t -> user.getTokens().add(new ExternalToken(null, "mpns", t, null))); return user; } @ApiIgnore @RequestMapping(value = "/notifications", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public ResponseEntity> doGet( @RequestParam(required = false, defaultValue = "0") int uid, @RequestParam(required = false, defaultValue = "0") int mid, @RequestParam(required = false, defaultValue = "0") int rid) { User visitor = UserUtils.getCurrentUser(); if (visitor.isAnonymous() || !(visitor.getName().equals("juick"))) { throw new HttpForbiddenException(); } if (uid > 0 && mid == 0) { // PM return ResponseEntity.ok(Collections.singletonList(collectTokens(uid))); } else { if (mid > 0) { Message msg = messagesService.getMessage(mid); if (msg != null) { List users; if (rid > 0) { Message op = messagesService.getMessage(mid); Message reply = messagesService.getReply(mid, rid); users = subscriptionService.getUsersSubscribedToComments(op, reply); } else { users = subscriptionService.getSubscribedUsers(msg.getUser().getUid(), mid); } return ResponseEntity.ok(users.stream().map(User::getUid) .map(this::collectTokens).collect(Collectors.toList())); } } } throw new HttpBadRequestException(); } @ApiIgnore @RequestMapping(value = "/notifications", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Status doDelete( @RequestBody List list) { User visitor = UserUtils.getCurrentUser(); // FIXME: it is possible to delete other user's tokens if ((visitor.isAnonymous()) || !(visitor.getName().equals("juick"))) { throw new HttpForbiddenException(); } list.forEach(t -> { switch (t.getType()) { case "gcm": pushQueriesService.deleteGCMToken(t.getToken()); break; case "apns": pushQueriesService.deleteAPNSToken(t.getToken()); break; case "mpns": pushQueriesService.deleteMPNSToken(t.getToken()); break; default: throw new HttpBadRequestException(); } }); return Status.OK; } @ApiIgnore @RequestMapping(value = "/notifications", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Status doPut( @RequestBody List list) throws IOException { User visitor = UserUtils.getCurrentUser(); if (visitor.isAnonymous()) { throw new HttpForbiddenException(); } list.forEach(t -> { switch (t.getType()) { case "gcm": pushQueriesService.addGCMToken(visitor.getUid(), t.getToken()); break; case "apns": pushQueriesService.addAPNSToken(visitor.getUid(), t.getToken()); break; case "mpns": pushQueriesService.addMPNSToken(visitor.getUid(), t.getToken()); break; default: throw new HttpBadRequestException(); } }); return Status.OK; } @Deprecated @RequestMapping(value = "/android/register", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Status doAndroidRegister( @RequestParam(name = "regid") String regId) { User visitor = UserUtils.getCurrentUser(); if (visitor.isAnonymous()) { throw new HttpForbiddenException(); } pushQueriesService.addGCMToken(visitor.getUid(), regId); return Status.OK; } @Deprecated @RequestMapping(value = "/android/unregister", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Status doAndroidUnRegister(@RequestParam(name = "regid") String regId) { pushQueriesService.deleteGCMToken(regId); return Status.OK; } @Deprecated @RequestMapping(value = "/winphone/register", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Status doWinphoneRegister( Principal principal, @RequestParam(name = "url") String regId) { User visitor = UserUtils.getCurrentUser(); pushQueriesService.addMPNSToken(visitor.getUid(), regId); return Status.OK; } @Deprecated @RequestMapping(value = "/winphone/unregister", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Status doWinphoneUnRegister(@RequestParam(name = "url") String regId) { pushQueriesService.deleteMPNSToken(regId); return Status.OK; } }