From a4897522174fb48864a4ef7d6276167f9da61f3b Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 31 Oct 2015 01:36:15 +0300 Subject: moved to Gradle --- src/conf/MANIFEST.MF | 2 - src/java/com/juick/api/Main.java | 231 ------------------------------ src/java/com/juick/api/Messages.java | 89 ------------ src/java/com/juick/api/Others.java | 45 ------ src/java/com/juick/api/PM.java | 101 ------------- src/java/com/juick/api/Users.java | 120 ---------------- src/java/com/juick/api/Utils.java | 149 ------------------- src/main/java/com/juick/api/Main.java | 231 ++++++++++++++++++++++++++++++ src/main/java/com/juick/api/Messages.java | 89 ++++++++++++ src/main/java/com/juick/api/Others.java | 45 ++++++ src/main/java/com/juick/api/PM.java | 101 +++++++++++++ src/main/java/com/juick/api/Users.java | 120 ++++++++++++++++ src/main/java/com/juick/api/Utils.java | 149 +++++++++++++++++++ src/main/webapp/WEB-INF/web.xml | 16 +++ 14 files changed, 751 insertions(+), 737 deletions(-) delete mode 100644 src/conf/MANIFEST.MF delete mode 100644 src/java/com/juick/api/Main.java delete mode 100644 src/java/com/juick/api/Messages.java delete mode 100644 src/java/com/juick/api/Others.java delete mode 100644 src/java/com/juick/api/PM.java delete mode 100644 src/java/com/juick/api/Users.java delete mode 100644 src/java/com/juick/api/Utils.java create mode 100644 src/main/java/com/juick/api/Main.java create mode 100644 src/main/java/com/juick/api/Messages.java create mode 100644 src/main/java/com/juick/api/Others.java create mode 100644 src/main/java/com/juick/api/PM.java create mode 100644 src/main/java/com/juick/api/Users.java create mode 100644 src/main/java/com/juick/api/Utils.java create mode 100644 src/main/webapp/WEB-INF/web.xml (limited to 'src') diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF deleted file mode 100644 index 59499bce..00000000 --- a/src/conf/MANIFEST.MF +++ /dev/null @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 - diff --git a/src/java/com/juick/api/Main.java b/src/java/com/juick/api/Main.java deleted file mode 100644 index 5ee4027b..00000000 --- a/src/java/com/juick/api/Main.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Juick - * Copyright (C) 2008-2013, Ugnich Anton - * - * 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.api; - -import com.juick.xmpp.JID; -import com.juick.xmpp.Stream; -import com.juick.xmpp.StreamComponent; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.Socket; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; -import javax.servlet.ServletException; -import javax.servlet.annotation.MultipartConfig; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author Ugnich Anton - */ -@WebServlet(name = "Main", urlPatterns = {"/"}) -@MultipartConfig -public class Main extends HttpServlet implements Stream.StreamListener { - - Connection sql; - Connection sqlSearch; - Stream xmpp; - Messages messages; - Users users; - PM pm; - Others others; - - @Override - public void init() throws ServletException { - super.init(); - try { - Properties conf = new Properties(); - conf.load(new FileInputStream("/etc/juick/api.conf")); - - Class.forName("com.mysql.jdbc.Driver"); - sql = DriverManager.getConnection("jdbc:mysql://localhost/juick?autoReconnect=true&user=" + conf.getProperty("mysql_username", "") + "&password=" + conf.getProperty("mysql_password", "")); - sqlSearch = DriverManager.getConnection("jdbc:mysql://127.0.0.1:9306/juick?autoReconnect=true&characterEncoding=utf8&maxAllowedPacket=512000&relaxAutoCommit=true&user=root&password="); - - messages = new Messages(sql); - users = new Users(sql); - pm = new PM(sql); - others = new Others(sql); - - setupXmppComponent(conf.getProperty("xmpp_password")); - - } catch (Exception e) { - log(null, e); - } - } - - public void setupXmppComponent(final String password) { - Thread thr = new Thread(new Runnable() { - - @Override - public void run() { - try { - Socket socket = new Socket("localhost", 5347); - xmpp = new StreamComponent(new JID("", "api.juick.com", ""), socket.getInputStream(), socket.getOutputStream(), password); - xmpp.addListener(Main.this); - xmpp.startParsing(); - } catch (IOException e) { - System.err.println(e); - } - } - }); - thr.start(); - } - - @Override - public void onStreamFail(String msg) { - System.err.println("XMPP STREAM FAIL: " + msg); - } - - @Override - public void onStreamReady() { - System.err.println("XMPP STREAM READY"); - } - - @Override - public void destroy() { - super.destroy(); - if (sql != null) { - try { - sql.close(); - sql = null; - } catch (SQLException e) { - log(null, e); - } - } - if (sqlSearch != null) { - try { - sqlSearch.close(); - sqlSearch = null; - } catch (SQLException e) { - log(null, e); - } - } - } - - /** - * Handles the HTTP GET method. - * @param request servlet request - * @param response servlet response - * @throws ServletException if a servlet-specific error occurs - * @throws IOException if an I/O error occurs - */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (request.getCharacterEncoding() == null) { - request.setCharacterEncoding("UTF-8"); - } - - int vuid = Utils.getHttpAuthUID(sql, request); - if (vuid == 0) { - vuid = Utils.getVisitorQueryStringUID(sql, request); - } - - String uri = request.getRequestURI(); - if (uri.equals("/home")) { - if (vuid > 0) { - messages.doGetHome(request, response, vuid); - } else { - response.sendError(401); - } - } else if (uri.equals("/users")) { - users.doGetUsers(request, response, vuid); - } else if (uri.equals("/users/read")) { - users.doGetUserRead(request, response, vuid); - } else if (uri.equals("/users/readers")) { - users.doGetUserReaders(request, response, vuid); - } else if (uri.equals("/pm")) { - if (vuid > 0) { - pm.doGetPM(request, response, vuid); - } else { - response.sendError(401); - } - } else if (uri.equals("/groups_pms")) { - if (vuid > 0) { - others.doGetGroupsPMs(request, response, vuid); - } else { - response.sendError(401); - } - } else if (uri.equals("/messages/set_popular") && vuid == 1) { - messages.doSetPopular(request, response, xmpp); - } else if (uri.equals("/messages/set_privacy") && vuid > 0) { - messages.doSetPrivacy(request, response, xmpp, vuid); - } else { - response.sendError(404); - } - } - - /** - * Handles the HTTP POST method. - * @param request servlet request - * @param response servlet response - * @throws ServletException if a servlet-specific error occurs - * @throws IOException if an I/O error occurs - */ - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (request.getCharacterEncoding() == null) { - request.setCharacterEncoding("UTF-8"); - } - - int vuid = Utils.getHttpAuthUID(sql, request); - if (vuid == 0) { - vuid = Utils.getVisitorQueryStringUID(sql, request); - } - if (vuid == 0) { - response.sendError(401); - return; - } - - String uri = request.getRequestURI(); - if (uri.equals("/post")) { - } else if (uri.equals("/pm")) { - pm.doPostPM(request, response, xmpp, vuid); - } else { - response.sendError(405); - } - } - - public static void replyJSON(HttpServletRequest request, HttpServletResponse response, String json) throws IOException { - response.setContentType("application/json; charset=UTF-8"); - response.setHeader("Access-Control-Allow-Origin", "*"); - - String callback = request.getParameter("callback"); - if (callback != null && (callback.length() > 64 || !callback.matches("[a-zA-Z0-9\\-\\_]+"))) { - callback = null; - } - - PrintWriter out = response.getWriter(); - try { - if (callback != null) { - out.print(callback + "("); - out.print(json); - out.print(")"); - } else { - out.print(json); - } - } finally { - out.close(); - } - } -} diff --git a/src/java/com/juick/api/Messages.java b/src/java/com/juick/api/Messages.java deleted file mode 100644 index b5462258..00000000 --- a/src/java/com/juick/api/Messages.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.juick.api; - -import com.juick.server.MessagesQueries; -import com.juick.xmpp.JID; -import com.juick.xmpp.Message; -import com.juick.xmpp.Stream; -import com.juick.xmpp.extensions.JuickMessage; -import java.io.IOException; -import java.sql.Connection; -import java.util.ArrayList; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author ugnich - */ -public class Messages { - - Connection sql; - - public Messages(Connection sql) { - this.sql = sql; - } - - public void doGetHome(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { - int before_mid = Utils.parseInt(request.getParameter("before_mid"), 0); - - ArrayList mids = MessagesQueries.getMyFeed(sql, vuid, before_mid); - if (mids != null && !mids.isEmpty()) { - ArrayList msgs = MessagesQueries.getMessages(sql, mids); - if (msgs != null && !msgs.isEmpty()) { - String json = com.juick.json.Messages.arrayToString(msgs); - Main.replyJSON(request, response, json); - } else { - response.sendError(404); - } - } else { - response.sendError(404); - } - } - - public void doSetPrivacy(HttpServletRequest request, HttpServletResponse response, Stream xmpp, int vuid) throws ServletException, IOException { - int mid = Utils.parseInt(request.getParameter("mid"), 0); - com.juick.User user = MessagesQueries.getMessageAuthor(sql, mid); - if (user != null && user.UID == vuid && MessagesQueries.setMessagePrivacy(sql, mid)) { - Main.replyJSON(request, response, "{\"status\":\"ok\"}"); - } else { - response.sendError(400); - } - } - - public void doSetPopular(HttpServletRequest request, HttpServletResponse response, Stream xmpp) throws ServletException, IOException { - int mid = Utils.parseInt(request.getParameter("mid"), 0); - int popular = Utils.parseInt(request.getParameter("popular"), 0); - - if (mid > 0) { - boolean ret = MessagesQueries.setMessagePopular(sql, mid, popular); - - if (ret && popular == 2) { - try { - com.juick.Message m = MessagesQueries.getMessage(sql, mid); - if (m != null) { - Message msg = new Message(); - msg.from = new JID("juick", "juick.com", null); - msg.to = new JID(null, "crosspost.juick.com", null); - JuickMessage jmsg = new JuickMessage(m); - jmsg.User.UID = 11574; - msg.childs.add(jmsg); - - msg.to.Username = "twitter"; - xmpp.send(msg); - msg.to.Username = "fb"; - xmpp.send(msg); - msg.to.Username = "vk"; - xmpp.send(msg); - } else { - throw new Exception("Message not found"); - } - } catch (Exception e) { - System.err.println("SETPOPULAR ERROR: " + e.toString()); - } - } - - Main.replyJSON(request, response, "{\"status\":\"ok\"}"); - } - } -} diff --git a/src/java/com/juick/api/Others.java b/src/java/com/juick/api/Others.java deleted file mode 100644 index 25df5bf4..00000000 --- a/src/java/com/juick/api/Others.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.juick.api; - -import com.juick.server.PMQueries; -import java.io.IOException; -import java.sql.Connection; -import java.util.ArrayList; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author ugnich - */ -public class Others { - - Connection sql; - - public Others(Connection sql) { - this.sql = sql; - } - - public void doGetGroupsPMs(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { - int cnt = 5; - try { - String cntStr = request.getParameter("cnt"); - cnt = Integer.parseInt(cntStr); - if (cnt < 3) { - cnt = 3; - } - if (cnt > 10) { - cnt = 10; - } - } catch (Exception e) { - } - - ArrayList lastconv = PMQueries.getPMLastConversationsUsers(sql, vuid, cnt); - if (lastconv != null && !lastconv.isEmpty()) { - String json = "{\"pms\":" + com.juick.json.Users.arrayToString(lastconv) + "}"; - Main.replyJSON(request, response, json); - } else { - response.sendError(404); - } - } -} diff --git a/src/java/com/juick/api/PM.java b/src/java/com/juick/api/PM.java deleted file mode 100644 index 2722526d..00000000 --- a/src/java/com/juick/api/PM.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.juick.api; - -import com.juick.server.PMQueries; -import com.juick.server.UserQueries; -import com.juick.xmpp.JID; -import com.juick.xmpp.Message; -import com.juick.xmpp.Stream; -import com.juick.xmpp.extensions.JuickMessage; -import java.io.IOException; -import java.sql.Connection; -import java.util.ArrayList; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author ugnich - */ -public class PM { - - Connection sql; - - public PM(Connection sql) { - this.sql = sql; - } - - public void doGetPM(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { - String uname = request.getParameter("uname"); - int uid = 0; - if (uname != null && uname.matches("^[a-zA-Z0-9\\-]{2,16}$")) { - uid = UserQueries.getUIDbyName(sql, uname); - } - - if (uid == 0) { - response.sendError(400); - return; - } - - ArrayList msgs = PMQueries.getPMMessages(sql, vuid, uid); - if (msgs != null && !msgs.isEmpty()) { - String json = com.juick.json.Messages.arrayToString(msgs); - Main.replyJSON(request, response, json); - } else { - response.sendError(404); - } - } - - public void doPostPM(HttpServletRequest request, HttpServletResponse response, Stream xmpp, int vuid) throws ServletException, IOException { - String uname = request.getParameter("uname"); - int uid = 0; - if (UserQueries.checkUserNameValid(uname)) { - uid = UserQueries.getUIDbyName(sql, uname); - } - - String body = request.getParameter("body"); - if (uid == 0 || body == null || body.length() < 1 || body.length() > 10240) { - response.sendError(400); - return; - } - - if (UserQueries.isInBLAny(sql, uid, vuid)) { - response.sendError(403); - return; - } - - if (PMQueries.createPM(sql, vuid, uid, body)) { - Message msg = new Message(); - msg.from = new JID("juick", "juick.com", null); - msg.to = new JID(Integer.toString(uid), "push.juick.com", null); - JuickMessage jmsg = new JuickMessage(); - jmsg.User = UserQueries.getUserByUID(sql, vuid); - jmsg.Text = body; - msg.childs.add(jmsg); - xmpp.send(msg); - - msg.to.Host = "ws.juick.com"; - xmpp.send(msg); - - Main.replyJSON(request, response, com.juick.json.Message.toJSON(jmsg).toString()); - - String jid = UserQueries.getJIDbyUID(sql, uid); - if (jid != null) { - Message mm = new Message(); - mm.to = new JID(jid); - mm.type = Message.Type.chat; - if (PMQueries.havePMinRoster(sql, vuid, jid)) { - mm.from = new JID(jmsg.User.UName, "juick.com", "Juick"); - mm.body = body; - } else { - mm.from = new JID("juick", "juick.com", "Juick"); - mm.body = "Private message from @" + jmsg.User.UName + ":\n" + body; - } - xmpp.send(mm); - } - - } else { - response.sendError(500); - } - } -} diff --git a/src/java/com/juick/api/Users.java b/src/java/com/juick/api/Users.java deleted file mode 100644 index cdd48fd6..00000000 --- a/src/java/com/juick/api/Users.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.juick.api; - -import com.juick.User; -import com.juick.server.UserQueries; -import java.io.IOException; -import java.sql.Connection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author ugnich - */ -public class Users { - - Connection sql; - - public Users(Connection sql) { - this.sql = sql; - } - - public void doGetUsers(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { - ArrayList users = new ArrayList(); - - String punames[] = request.getParameterValues("uname"); - if (punames != null) { - ArrayList unames = new ArrayList(Arrays.asList(punames)); - Iterator i = unames.iterator(); - while (i.hasNext()) { - if (!i.next().matches("^[a-zA-Z0-9\\-]{2,16}$")) { - i.remove(); - } - } - if (!unames.isEmpty() && unames.size() < 20) { - users.addAll(UserQueries.getUsersByName(sql, unames)); - } - } - - String pjids[] = request.getParameterValues("jid"); - if (pjids != null) { - ArrayList jids = new ArrayList(Arrays.asList(pjids)); - Iterator ii = jids.iterator(); - while (ii.hasNext()) { - if (!ii.next().matches("^[a-zA-Z0-9\\-\\_\\@\\.]{6,64}$")) { - ii.remove(); - } - } - if (!jids.isEmpty() && jids.size() < 20) { - users.addAll(UserQueries.getUsersByJID(sql, jids)); - } - } - - if (!users.isEmpty()) { - String json = com.juick.json.Users.arrayToString(users); - Main.replyJSON(request, response, json); - } else { - response.sendError(404); - } - } - - public void doGetUserRead(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { - int uid = 0; - String uname = request.getParameter("uname"); - if (uname == null) { - uid = vuid; - } else { - if (UserQueries.checkUserNameValid(uname)) { - com.juick.User u = UserQueries.getUserByName(sql, uname); - if (u != null && u.UID > 0) { - uid = u.UID; - } - } - } - - if (uid > 0) { - ArrayList uids = UserQueries.getUserRead(sql, uid); - if (uids.size() > 0) { - ArrayList users = UserQueries.getUsersByID(sql, uids); - if (users.size() > 0) { - String json = com.juick.json.Users.arrayToString(users); - Main.replyJSON(request, response, json); - return; - } - } - } - response.sendError(404); - } - - public void doGetUserReaders(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { - int uid = 0; - String uname = request.getParameter("uname"); - if (uname == null) { - uid = vuid; - } else { - if (UserQueries.checkUserNameValid(uname)) { - com.juick.User u = UserQueries.getUserByName(sql, uname); - if (u != null && u.UID > 0) { - uid = u.UID; - } - } - } - - if (uid > 0) { - ArrayList uids = UserQueries.getUserReaders(sql, uid); - if (uids.size() > 0) { - ArrayList users = UserQueries.getUsersByID(sql, uids); - if (users.size() > 0) { - String json = com.juick.json.Users.arrayToString(users); - Main.replyJSON(request, response, json); - return; - } - } - } - response.sendError(404); - } -} diff --git a/src/java/com/juick/api/Utils.java b/src/java/com/juick/api/Utils.java deleted file mode 100644 index 10e0cccb..00000000 --- a/src/java/com/juick/api/Utils.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Juick - * Copyright (C) 2008-2011, Ugnich Anton - * - * 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.api; - -import com.juick.server.UserQueries; -import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import sun.misc.BASE64Decoder; - -/** - * - * @author Ugnich Anton - */ -public class Utils { - - public static String getCookie(HttpServletRequest request, String name) { - Cookie cookies[] = request.getCookies(); - if (cookies != null) { - for (int i = 0; i < cookies.length; i++) { - if (cookies[i].getName().equals(name)) { - return cookies[i].getValue(); - } - } - } - return null; - } - - public static com.juick.User getVisitorUser(Connection sql, HttpServletRequest request) { - String hash = getCookie(request, "hash"); - if (hash != null) { - return com.juick.server.UserQueries.getUserByHash(sql, hash); - } else { - return null; - } - } - - public static int getVisitorUID(Connection sql, HttpServletRequest request) { - Cookie cookies[] = request.getCookies(); - if (cookies != null) { - for (int i = 0; i < cookies.length; i++) { - if (cookies[i].getName().equals("hash")) { - String hash = cookies[i].getValue(); - return com.juick.server.UserQueries.getUIDbyHash(sql, hash); - } - } - } - return 0; - } - - public static int getHttpAuthUID(Connection sql, HttpServletRequest request) { - String auth = request.getHeader("Authorization"); - if (auth != null && auth.length() > 8 && auth.startsWith("Basic ")) { - try { - BASE64Decoder dec = new BASE64Decoder(); - String loginpassw[] = new String(dec.decodeBuffer(auth.substring(6))).split(":", 2); - if (loginpassw.length == 2 && loginpassw[0].length() > 1 && loginpassw[0].length() < 16 && loginpassw[0].matches("[a-zA-Z0-9\\-]+") && !loginpassw[1].isEmpty()) { - return UserQueries.checkPassword(sql, loginpassw[0], loginpassw[1]); - } - } catch (IOException e) { - } - } - return 0; - } - - public static int getVisitorQueryStringUID(Connection sql, HttpServletRequest request) { - String hash = request.getParameter("hash"); - if (hash != null && hash.length() == 16) { - return com.juick.server.UserQueries.getUIDbyHash(sql, hash); - } - return 0; - } - - public static void sendPermanentRedirect(HttpServletResponse response, String location) { - response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); - response.setHeader("Location", location); - } - - public static void finishSQL(ResultSet rs, Statement stmt) { - if (rs != null) { - try { - rs.close(); - } catch (SQLException e) { - } - } - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException e) { - } - } - } - - public static String convertArray2String(ArrayList mids) { - String q = ""; - for (int i = 0; i < mids.size(); i++) { - if (i > 0) { - q += ","; - } - q += mids.get(i); - } - return q; - } - - public static String encodeHTML(String str) { - String ret = str; - ret = ret.replaceAll("<", "<"); - ret = ret.replaceAll(">", ">"); - return str; - } - - public static String encodeSphinx(String str) { - String ret = str; - ret = ret.replaceAll("@", "\\\\@"); - return ret; - } - - public static int parseInt(String str, int def) { - int ret = def; - if (str != null) { - try { - ret = Integer.parseInt(str); - } catch (Exception e) { - } - } - return ret; - } -} diff --git a/src/main/java/com/juick/api/Main.java b/src/main/java/com/juick/api/Main.java new file mode 100644 index 00000000..5ee4027b --- /dev/null +++ b/src/main/java/com/juick/api/Main.java @@ -0,0 +1,231 @@ +/* + * Juick + * Copyright (C) 2008-2013, Ugnich Anton + * + * 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.api; + +import com.juick.xmpp.JID; +import com.juick.xmpp.Stream; +import com.juick.xmpp.StreamComponent; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.Socket; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; +import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Ugnich Anton + */ +@WebServlet(name = "Main", urlPatterns = {"/"}) +@MultipartConfig +public class Main extends HttpServlet implements Stream.StreamListener { + + Connection sql; + Connection sqlSearch; + Stream xmpp; + Messages messages; + Users users; + PM pm; + Others others; + + @Override + public void init() throws ServletException { + super.init(); + try { + Properties conf = new Properties(); + conf.load(new FileInputStream("/etc/juick/api.conf")); + + Class.forName("com.mysql.jdbc.Driver"); + sql = DriverManager.getConnection("jdbc:mysql://localhost/juick?autoReconnect=true&user=" + conf.getProperty("mysql_username", "") + "&password=" + conf.getProperty("mysql_password", "")); + sqlSearch = DriverManager.getConnection("jdbc:mysql://127.0.0.1:9306/juick?autoReconnect=true&characterEncoding=utf8&maxAllowedPacket=512000&relaxAutoCommit=true&user=root&password="); + + messages = new Messages(sql); + users = new Users(sql); + pm = new PM(sql); + others = new Others(sql); + + setupXmppComponent(conf.getProperty("xmpp_password")); + + } catch (Exception e) { + log(null, e); + } + } + + public void setupXmppComponent(final String password) { + Thread thr = new Thread(new Runnable() { + + @Override + public void run() { + try { + Socket socket = new Socket("localhost", 5347); + xmpp = new StreamComponent(new JID("", "api.juick.com", ""), socket.getInputStream(), socket.getOutputStream(), password); + xmpp.addListener(Main.this); + xmpp.startParsing(); + } catch (IOException e) { + System.err.println(e); + } + } + }); + thr.start(); + } + + @Override + public void onStreamFail(String msg) { + System.err.println("XMPP STREAM FAIL: " + msg); + } + + @Override + public void onStreamReady() { + System.err.println("XMPP STREAM READY"); + } + + @Override + public void destroy() { + super.destroy(); + if (sql != null) { + try { + sql.close(); + sql = null; + } catch (SQLException e) { + log(null, e); + } + } + if (sqlSearch != null) { + try { + sqlSearch.close(); + sqlSearch = null; + } catch (SQLException e) { + log(null, e); + } + } + } + + /** + * Handles the HTTP GET method. + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (request.getCharacterEncoding() == null) { + request.setCharacterEncoding("UTF-8"); + } + + int vuid = Utils.getHttpAuthUID(sql, request); + if (vuid == 0) { + vuid = Utils.getVisitorQueryStringUID(sql, request); + } + + String uri = request.getRequestURI(); + if (uri.equals("/home")) { + if (vuid > 0) { + messages.doGetHome(request, response, vuid); + } else { + response.sendError(401); + } + } else if (uri.equals("/users")) { + users.doGetUsers(request, response, vuid); + } else if (uri.equals("/users/read")) { + users.doGetUserRead(request, response, vuid); + } else if (uri.equals("/users/readers")) { + users.doGetUserReaders(request, response, vuid); + } else if (uri.equals("/pm")) { + if (vuid > 0) { + pm.doGetPM(request, response, vuid); + } else { + response.sendError(401); + } + } else if (uri.equals("/groups_pms")) { + if (vuid > 0) { + others.doGetGroupsPMs(request, response, vuid); + } else { + response.sendError(401); + } + } else if (uri.equals("/messages/set_popular") && vuid == 1) { + messages.doSetPopular(request, response, xmpp); + } else if (uri.equals("/messages/set_privacy") && vuid > 0) { + messages.doSetPrivacy(request, response, xmpp, vuid); + } else { + response.sendError(404); + } + } + + /** + * Handles the HTTP POST method. + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (request.getCharacterEncoding() == null) { + request.setCharacterEncoding("UTF-8"); + } + + int vuid = Utils.getHttpAuthUID(sql, request); + if (vuid == 0) { + vuid = Utils.getVisitorQueryStringUID(sql, request); + } + if (vuid == 0) { + response.sendError(401); + return; + } + + String uri = request.getRequestURI(); + if (uri.equals("/post")) { + } else if (uri.equals("/pm")) { + pm.doPostPM(request, response, xmpp, vuid); + } else { + response.sendError(405); + } + } + + public static void replyJSON(HttpServletRequest request, HttpServletResponse response, String json) throws IOException { + response.setContentType("application/json; charset=UTF-8"); + response.setHeader("Access-Control-Allow-Origin", "*"); + + String callback = request.getParameter("callback"); + if (callback != null && (callback.length() > 64 || !callback.matches("[a-zA-Z0-9\\-\\_]+"))) { + callback = null; + } + + PrintWriter out = response.getWriter(); + try { + if (callback != null) { + out.print(callback + "("); + out.print(json); + out.print(")"); + } else { + out.print(json); + } + } finally { + out.close(); + } + } +} diff --git a/src/main/java/com/juick/api/Messages.java b/src/main/java/com/juick/api/Messages.java new file mode 100644 index 00000000..b5462258 --- /dev/null +++ b/src/main/java/com/juick/api/Messages.java @@ -0,0 +1,89 @@ +package com.juick.api; + +import com.juick.server.MessagesQueries; +import com.juick.xmpp.JID; +import com.juick.xmpp.Message; +import com.juick.xmpp.Stream; +import com.juick.xmpp.extensions.JuickMessage; +import java.io.IOException; +import java.sql.Connection; +import java.util.ArrayList; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author ugnich + */ +public class Messages { + + Connection sql; + + public Messages(Connection sql) { + this.sql = sql; + } + + public void doGetHome(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { + int before_mid = Utils.parseInt(request.getParameter("before_mid"), 0); + + ArrayList mids = MessagesQueries.getMyFeed(sql, vuid, before_mid); + if (mids != null && !mids.isEmpty()) { + ArrayList msgs = MessagesQueries.getMessages(sql, mids); + if (msgs != null && !msgs.isEmpty()) { + String json = com.juick.json.Messages.arrayToString(msgs); + Main.replyJSON(request, response, json); + } else { + response.sendError(404); + } + } else { + response.sendError(404); + } + } + + public void doSetPrivacy(HttpServletRequest request, HttpServletResponse response, Stream xmpp, int vuid) throws ServletException, IOException { + int mid = Utils.parseInt(request.getParameter("mid"), 0); + com.juick.User user = MessagesQueries.getMessageAuthor(sql, mid); + if (user != null && user.UID == vuid && MessagesQueries.setMessagePrivacy(sql, mid)) { + Main.replyJSON(request, response, "{\"status\":\"ok\"}"); + } else { + response.sendError(400); + } + } + + public void doSetPopular(HttpServletRequest request, HttpServletResponse response, Stream xmpp) throws ServletException, IOException { + int mid = Utils.parseInt(request.getParameter("mid"), 0); + int popular = Utils.parseInt(request.getParameter("popular"), 0); + + if (mid > 0) { + boolean ret = MessagesQueries.setMessagePopular(sql, mid, popular); + + if (ret && popular == 2) { + try { + com.juick.Message m = MessagesQueries.getMessage(sql, mid); + if (m != null) { + Message msg = new Message(); + msg.from = new JID("juick", "juick.com", null); + msg.to = new JID(null, "crosspost.juick.com", null); + JuickMessage jmsg = new JuickMessage(m); + jmsg.User.UID = 11574; + msg.childs.add(jmsg); + + msg.to.Username = "twitter"; + xmpp.send(msg); + msg.to.Username = "fb"; + xmpp.send(msg); + msg.to.Username = "vk"; + xmpp.send(msg); + } else { + throw new Exception("Message not found"); + } + } catch (Exception e) { + System.err.println("SETPOPULAR ERROR: " + e.toString()); + } + } + + Main.replyJSON(request, response, "{\"status\":\"ok\"}"); + } + } +} diff --git a/src/main/java/com/juick/api/Others.java b/src/main/java/com/juick/api/Others.java new file mode 100644 index 00000000..25df5bf4 --- /dev/null +++ b/src/main/java/com/juick/api/Others.java @@ -0,0 +1,45 @@ +package com.juick.api; + +import com.juick.server.PMQueries; +import java.io.IOException; +import java.sql.Connection; +import java.util.ArrayList; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author ugnich + */ +public class Others { + + Connection sql; + + public Others(Connection sql) { + this.sql = sql; + } + + public void doGetGroupsPMs(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { + int cnt = 5; + try { + String cntStr = request.getParameter("cnt"); + cnt = Integer.parseInt(cntStr); + if (cnt < 3) { + cnt = 3; + } + if (cnt > 10) { + cnt = 10; + } + } catch (Exception e) { + } + + ArrayList lastconv = PMQueries.getPMLastConversationsUsers(sql, vuid, cnt); + if (lastconv != null && !lastconv.isEmpty()) { + String json = "{\"pms\":" + com.juick.json.Users.arrayToString(lastconv) + "}"; + Main.replyJSON(request, response, json); + } else { + response.sendError(404); + } + } +} diff --git a/src/main/java/com/juick/api/PM.java b/src/main/java/com/juick/api/PM.java new file mode 100644 index 00000000..2722526d --- /dev/null +++ b/src/main/java/com/juick/api/PM.java @@ -0,0 +1,101 @@ +package com.juick.api; + +import com.juick.server.PMQueries; +import com.juick.server.UserQueries; +import com.juick.xmpp.JID; +import com.juick.xmpp.Message; +import com.juick.xmpp.Stream; +import com.juick.xmpp.extensions.JuickMessage; +import java.io.IOException; +import java.sql.Connection; +import java.util.ArrayList; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author ugnich + */ +public class PM { + + Connection sql; + + public PM(Connection sql) { + this.sql = sql; + } + + public void doGetPM(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { + String uname = request.getParameter("uname"); + int uid = 0; + if (uname != null && uname.matches("^[a-zA-Z0-9\\-]{2,16}$")) { + uid = UserQueries.getUIDbyName(sql, uname); + } + + if (uid == 0) { + response.sendError(400); + return; + } + + ArrayList msgs = PMQueries.getPMMessages(sql, vuid, uid); + if (msgs != null && !msgs.isEmpty()) { + String json = com.juick.json.Messages.arrayToString(msgs); + Main.replyJSON(request, response, json); + } else { + response.sendError(404); + } + } + + public void doPostPM(HttpServletRequest request, HttpServletResponse response, Stream xmpp, int vuid) throws ServletException, IOException { + String uname = request.getParameter("uname"); + int uid = 0; + if (UserQueries.checkUserNameValid(uname)) { + uid = UserQueries.getUIDbyName(sql, uname); + } + + String body = request.getParameter("body"); + if (uid == 0 || body == null || body.length() < 1 || body.length() > 10240) { + response.sendError(400); + return; + } + + if (UserQueries.isInBLAny(sql, uid, vuid)) { + response.sendError(403); + return; + } + + if (PMQueries.createPM(sql, vuid, uid, body)) { + Message msg = new Message(); + msg.from = new JID("juick", "juick.com", null); + msg.to = new JID(Integer.toString(uid), "push.juick.com", null); + JuickMessage jmsg = new JuickMessage(); + jmsg.User = UserQueries.getUserByUID(sql, vuid); + jmsg.Text = body; + msg.childs.add(jmsg); + xmpp.send(msg); + + msg.to.Host = "ws.juick.com"; + xmpp.send(msg); + + Main.replyJSON(request, response, com.juick.json.Message.toJSON(jmsg).toString()); + + String jid = UserQueries.getJIDbyUID(sql, uid); + if (jid != null) { + Message mm = new Message(); + mm.to = new JID(jid); + mm.type = Message.Type.chat; + if (PMQueries.havePMinRoster(sql, vuid, jid)) { + mm.from = new JID(jmsg.User.UName, "juick.com", "Juick"); + mm.body = body; + } else { + mm.from = new JID("juick", "juick.com", "Juick"); + mm.body = "Private message from @" + jmsg.User.UName + ":\n" + body; + } + xmpp.send(mm); + } + + } else { + response.sendError(500); + } + } +} diff --git a/src/main/java/com/juick/api/Users.java b/src/main/java/com/juick/api/Users.java new file mode 100644 index 00000000..cdd48fd6 --- /dev/null +++ b/src/main/java/com/juick/api/Users.java @@ -0,0 +1,120 @@ +package com.juick.api; + +import com.juick.User; +import com.juick.server.UserQueries; +import java.io.IOException; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author ugnich + */ +public class Users { + + Connection sql; + + public Users(Connection sql) { + this.sql = sql; + } + + public void doGetUsers(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { + ArrayList users = new ArrayList(); + + String punames[] = request.getParameterValues("uname"); + if (punames != null) { + ArrayList unames = new ArrayList(Arrays.asList(punames)); + Iterator i = unames.iterator(); + while (i.hasNext()) { + if (!i.next().matches("^[a-zA-Z0-9\\-]{2,16}$")) { + i.remove(); + } + } + if (!unames.isEmpty() && unames.size() < 20) { + users.addAll(UserQueries.getUsersByName(sql, unames)); + } + } + + String pjids[] = request.getParameterValues("jid"); + if (pjids != null) { + ArrayList jids = new ArrayList(Arrays.asList(pjids)); + Iterator ii = jids.iterator(); + while (ii.hasNext()) { + if (!ii.next().matches("^[a-zA-Z0-9\\-\\_\\@\\.]{6,64}$")) { + ii.remove(); + } + } + if (!jids.isEmpty() && jids.size() < 20) { + users.addAll(UserQueries.getUsersByJID(sql, jids)); + } + } + + if (!users.isEmpty()) { + String json = com.juick.json.Users.arrayToString(users); + Main.replyJSON(request, response, json); + } else { + response.sendError(404); + } + } + + public void doGetUserRead(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { + int uid = 0; + String uname = request.getParameter("uname"); + if (uname == null) { + uid = vuid; + } else { + if (UserQueries.checkUserNameValid(uname)) { + com.juick.User u = UserQueries.getUserByName(sql, uname); + if (u != null && u.UID > 0) { + uid = u.UID; + } + } + } + + if (uid > 0) { + ArrayList uids = UserQueries.getUserRead(sql, uid); + if (uids.size() > 0) { + ArrayList users = UserQueries.getUsersByID(sql, uids); + if (users.size() > 0) { + String json = com.juick.json.Users.arrayToString(users); + Main.replyJSON(request, response, json); + return; + } + } + } + response.sendError(404); + } + + public void doGetUserReaders(HttpServletRequest request, HttpServletResponse response, int vuid) throws ServletException, IOException { + int uid = 0; + String uname = request.getParameter("uname"); + if (uname == null) { + uid = vuid; + } else { + if (UserQueries.checkUserNameValid(uname)) { + com.juick.User u = UserQueries.getUserByName(sql, uname); + if (u != null && u.UID > 0) { + uid = u.UID; + } + } + } + + if (uid > 0) { + ArrayList uids = UserQueries.getUserReaders(sql, uid); + if (uids.size() > 0) { + ArrayList users = UserQueries.getUsersByID(sql, uids); + if (users.size() > 0) { + String json = com.juick.json.Users.arrayToString(users); + Main.replyJSON(request, response, json); + return; + } + } + } + response.sendError(404); + } +} diff --git a/src/main/java/com/juick/api/Utils.java b/src/main/java/com/juick/api/Utils.java new file mode 100644 index 00000000..10e0cccb --- /dev/null +++ b/src/main/java/com/juick/api/Utils.java @@ -0,0 +1,149 @@ +/* + * Juick + * Copyright (C) 2008-2011, Ugnich Anton + * + * 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.api; + +import com.juick.server.UserQueries; +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import sun.misc.BASE64Decoder; + +/** + * + * @author Ugnich Anton + */ +public class Utils { + + public static String getCookie(HttpServletRequest request, String name) { + Cookie cookies[] = request.getCookies(); + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + if (cookies[i].getName().equals(name)) { + return cookies[i].getValue(); + } + } + } + return null; + } + + public static com.juick.User getVisitorUser(Connection sql, HttpServletRequest request) { + String hash = getCookie(request, "hash"); + if (hash != null) { + return com.juick.server.UserQueries.getUserByHash(sql, hash); + } else { + return null; + } + } + + public static int getVisitorUID(Connection sql, HttpServletRequest request) { + Cookie cookies[] = request.getCookies(); + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + if (cookies[i].getName().equals("hash")) { + String hash = cookies[i].getValue(); + return com.juick.server.UserQueries.getUIDbyHash(sql, hash); + } + } + } + return 0; + } + + public static int getHttpAuthUID(Connection sql, HttpServletRequest request) { + String auth = request.getHeader("Authorization"); + if (auth != null && auth.length() > 8 && auth.startsWith("Basic ")) { + try { + BASE64Decoder dec = new BASE64Decoder(); + String loginpassw[] = new String(dec.decodeBuffer(auth.substring(6))).split(":", 2); + if (loginpassw.length == 2 && loginpassw[0].length() > 1 && loginpassw[0].length() < 16 && loginpassw[0].matches("[a-zA-Z0-9\\-]+") && !loginpassw[1].isEmpty()) { + return UserQueries.checkPassword(sql, loginpassw[0], loginpassw[1]); + } + } catch (IOException e) { + } + } + return 0; + } + + public static int getVisitorQueryStringUID(Connection sql, HttpServletRequest request) { + String hash = request.getParameter("hash"); + if (hash != null && hash.length() == 16) { + return com.juick.server.UserQueries.getUIDbyHash(sql, hash); + } + return 0; + } + + public static void sendPermanentRedirect(HttpServletResponse response, String location) { + response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); + response.setHeader("Location", location); + } + + public static void finishSQL(ResultSet rs, Statement stmt) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + } + } + } + + public static String convertArray2String(ArrayList mids) { + String q = ""; + for (int i = 0; i < mids.size(); i++) { + if (i > 0) { + q += ","; + } + q += mids.get(i); + } + return q; + } + + public static String encodeHTML(String str) { + String ret = str; + ret = ret.replaceAll("<", "<"); + ret = ret.replaceAll(">", ">"); + return str; + } + + public static String encodeSphinx(String str) { + String ret = str; + ret = ret.replaceAll("@", "\\\\@"); + return ret; + } + + public static int parseInt(String str, int def) { + int ret = def; + if (str != null) { + try { + ret = Integer.parseInt(str); + } catch (Exception e) { + } + } + return ret; + } +} diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..533a6882 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,16 @@ + + + + Main + com.juick.api.Main + + + Main + / + + + + 30 + + + -- cgit v1.2.3