diff options
Diffstat (limited to 'juick-server-web')
7 files changed, 362 insertions, 21 deletions
diff --git a/juick-server-web/build.gradle b/juick-server-web/build.gradle index 9a5e97a9..0cf63313 100644 --- a/juick-server-web/build.gradle +++ b/juick-server-web/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'java' -apply plugin: 'war' +apply plugin: 'io.spring.dependency-management' sourceCompatibility = 1.8 @@ -11,38 +11,41 @@ dependencies { compile "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${rootProject.jacksonVersion}" compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${rootProject.jacksonVersion}" - providedCompile "ch.qos.logback:logback-classic:${rootProject.logbackVersion}" - providedCompile "ch.qos.logback:logback-core:${rootProject.logbackVersion}" - providedCompile "ch.qos.logback:logback-access:${rootProject.logbackVersion}" + compile "ch.qos.logback:logback-classic:${rootProject.logbackVersion}" + compile "ch.qos.logback:logback-core:${rootProject.logbackVersion}" + compile "ch.qos.logback:logback-access:${rootProject.logbackVersion}" - providedCompile "org.slf4j:slf4j-api:${rootProject.slf4jVersion}" - providedCompile "org.slf4j:jcl-over-slf4j:${rootProject.slf4jVersion}" - providedCompile "org.slf4j:log4j-over-slf4j:${rootProject.slf4jVersion}" - providedCompile "org.slf4j:jul-to-slf4j:${rootProject.slf4jVersion}" + compile "org.slf4j:slf4j-api:${rootProject.slf4jVersion}" + compile "org.slf4j:jcl-over-slf4j:${rootProject.slf4jVersion}" + compile "org.slf4j:log4j-over-slf4j:${rootProject.slf4jVersion}" + compile "org.slf4j:jul-to-slf4j:${rootProject.slf4jVersion}" compile 'com.github.ben-manes.caffeine:caffeine:2.6.2' - - compile "org.springframework:spring-webmvc:${rootProject.springFrameworkVersion}" - compile "org.springframework:spring-context-support:${rootProject.springFrameworkVersion}" - compile "org.springframework:spring-websocket:${rootProject.springFrameworkVersion}" - - compile "org.springframework.security:spring-security-web:${rootProject.springSecurityVersion}" - compile "org.springframework.security:spring-security-config:${rootProject.springSecurityVersion}" + compile("org.springframework.boot:spring-boot-starter-cache") + compile("org.springframework.boot:spring-boot-starter-web") + compile("org.springframework.boot:spring-boot-starter-websocket") + compile("org.springframework.boot:spring-boot-starter-security") compile "javax.inject:javax.inject:1" compile 'org.imgscalr:imgscalr-lib:4.2' compile "org.apache.commons:commons-imaging:1.0-SNAPSHOT" - providedCompile "javax.servlet:javax.servlet-api:3.1.0" + runtime "commons-fileupload:commons-fileupload:1.3.3" - providedRuntime "commons-fileupload:commons-fileupload:1.3.3" + compile ('com.github.juick:com.juick.xmpp:658f8cf751') { + exclude group: 'xmlpull' + } + compile 'xpp3:xpp3:1.1.4c' testCompile "junit:junit:${rootProject.junitVersion}" testCompile "org.hamcrest:hamcrest-all:${rootProject.hamcrestVersion}" testCompile "org.mockito:mockito-core:${rootProject.mockitoVersion}" - testCompile "org.springframework:spring-test:${rootProject.springFrameworkVersion}" - testCompile "org.springframework.security:spring-security-test:${rootProject.springSecurityVersion}" + testCompile "org.springframework.boot:spring-boot-starter-test" + testCompile "org.springframework.security:spring-security-test" +} +dependencyManagement { + imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${rootProject.springBootVersion}") } } compileJava.options.encoding = 'UTF-8' diff --git a/juick-server-web/src/main/java/com/juick/server/configuration/BaseWebConfiguration.java b/juick-server-web/src/main/java/com/juick/server/configuration/BaseWebConfiguration.java index 3ceee3eb..d9b842af 100644 --- a/juick-server-web/src/main/java/com/juick/server/configuration/BaseWebConfiguration.java +++ b/juick-server-web/src/main/java/com/juick/server/configuration/BaseWebConfiguration.java @@ -21,8 +21,13 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.juick.server.xmpp.JidConverter; +import com.juick.server.xmpp.s2s.BasicXmppSession; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.ConversionService; +import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.scheduling.annotation.SchedulingConfigurer; @@ -31,9 +36,13 @@ import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import rocks.xmpp.core.session.Extension; +import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.session.debug.LogbackDebugger; import java.util.List; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** @@ -81,4 +90,25 @@ public class BaseWebConfiguration implements WebMvcConfigurer, SchedulingConfigu public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } + @Value("${hostname:localhost}") + private String hostname; + + @Bean + public ExecutorService service() { + return Executors.newCachedThreadPool(); + } + @Bean + public BasicXmppSession session() { + XmppSessionConfiguration configuration = XmppSessionConfiguration.builder() + .extensions(Extension.of(com.juick.Message.class)) + .debugger(LogbackDebugger.class) + .build(); + return BasicXmppSession.create(hostname, configuration); + } + @Bean + public static ConversionService conversionService() { + DefaultFormattingConversionService cs = new DefaultFormattingConversionService(); + cs.addConverter(new JidConverter()); + return cs; + } } diff --git a/juick-server-web/src/main/java/com/juick/server/xmpp/JidConverter.java b/juick-server-web/src/main/java/com/juick/server/xmpp/JidConverter.java new file mode 100644 index 00000000..e9a9707e --- /dev/null +++ b/juick-server-web/src/main/java/com/juick/server/xmpp/JidConverter.java @@ -0,0 +1,13 @@ +package com.juick.server.xmpp; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; +import rocks.xmpp.addr.Jid; + +public class JidConverter implements Converter<String, Jid> { + @Nullable + @Override + public Jid convert(String jidStr) { + return Jid.of(jidStr); + } +} diff --git a/juick-server-web/src/main/java/com/juick/server/xmpp/extensions/JuickMessage.java b/juick-server-web/src/main/java/com/juick/server/xmpp/extensions/JuickMessage.java new file mode 100644 index 00000000..6956a99a --- /dev/null +++ b/juick-server-web/src/main/java/com/juick/server/xmpp/extensions/JuickMessage.java @@ -0,0 +1,162 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ +package com.juick.server.xmpp.extensions; + +import com.juick.Tag; +import com.juick.xmpp.StanzaChild; +import com.juick.xmpp.utils.XmlUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StringEscapeUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +/** + * + * @author Ugnich Anton + */ +public class JuickMessage extends com.juick.Message implements StanzaChild { + public final static String XMLNS = "http://juick.com/message"; + public final static String TagName = "juick"; + private SimpleDateFormat df; + public JuickMessage() { + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + @Override + public String getXMLNS() { + return XMLNS; + } + @Override + public JuickMessage parse(XmlPullParser parser) throws XmlPullParserException, IOException, ParseException { + JuickMessage jmsg = new JuickMessage(); + final String sMID = parser.getAttributeValue(null, "mid"); + if (sMID != null) { + jmsg.setMid(Integer.parseInt(sMID)); + } + final String sRID = parser.getAttributeValue(null, "rid"); + if (sRID != null) { + jmsg.setRid(Integer.parseInt(sRID)); + } + final String sReplyTo = parser.getAttributeValue(null, "replyto"); + if (sReplyTo != null) { + jmsg.setReplyto(Integer.parseInt(sReplyTo)); + } + final String sPrivacy = parser.getAttributeValue(null, "privacy"); + if (sPrivacy != null) { + jmsg.setPrivacy(Integer.parseInt(sPrivacy)); + } + final String sFriendsOnly = parser.getAttributeValue(null, "friendsonly"); + if (sFriendsOnly != null) { + jmsg.FriendsOnly = true; + } + final String sReadOnly = parser.getAttributeValue(null, "readonly"); + if (sReadOnly != null) { + jmsg.ReadOnly = true; + } + jmsg.setTimestamp(df.parse(parser.getAttributeValue(null, "ts")).toInstant()); + jmsg.setAttachmentType(parser.getAttributeValue(null, "attach")); + while (parser.next() == XmlPullParser.START_TAG) { + final String tag = parser.getName(); + final String xmlns = parser.getNamespace(); + if (tag.equals("body")) { + jmsg.setText(XmlUtils.getTagText(parser)); + } else if (tag.equals(JuickUser.TagName) && xmlns != null && xmlns.equals(JuickUser.XMLNS)) { + jmsg.setUser(new JuickUser().parse(parser)); + } else if (tag.equals("tag")) { + jmsg.getTags().add(new Tag(XmlUtils.getTagText(parser))); + } else { + XmlUtils.skip(parser); + } + } + return jmsg; + } + @Override + public String toString() { + StringBuilder ret = new StringBuilder("<").append(TagName).append(" xmlns=\"").append(XMLNS).append("\""); + if (getMid() > 0) { + ret.append(" mid=\"").append(getMid()).append("\""); + } + if (getRid() > 0) { + ret.append(" rid=\"").append(getRid()).append("\""); + } + if (getReplyto() > 0) { + ret.append(" replyto=\"").append(getReplyto()).append("\""); + } + ret.append(" privacy=\"").append(getPrivacy()).append("\""); + if (FriendsOnly) { + ret.append(" friendsonly=\"1\""); + } + if (ReadOnly) { + ret.append(" readonly=\"1\""); + } + if (getTimestamp() != null) { + ret.append(" ts=\"").append(df.format(Date.from(getTimestamp()))).append("\""); + } + if (getAttachmentType() != null) { + ret.append(" attach=\"").append(getAttachmentType()).append("\""); + } + ret.append(">"); + if (getUser() != null) { + ret.append(JuickUser.toString(getUser())); + } + if (getText() != null) { + ret.append("<body>").append(StringEscapeUtils.escapeXml10(StringUtils.defaultString(getText()))).append("</body>"); + } + for (Tag Tag : getTags()) { + ret.append("<tag>").append(StringEscapeUtils.escapeXml10(Tag.getName())).append("</tag>"); + } + ret.append("</").append(TagName).append(">"); + return ret.toString(); + } + @Override + public boolean equals(Object obj) { + if (!(obj instanceof JuickMessage)) { + return false; + } + JuickMessage jmsg = (JuickMessage) obj; + return (this.getMid() == jmsg.getMid() && this.getRid() == jmsg.getRid()); + } + @Override + public int compareTo(Object obj) throws ClassCastException { + if (!(obj instanceof JuickMessage)) { + throw new ClassCastException(); + } + JuickMessage jmsg = (JuickMessage) obj; + if (this.getMid() != jmsg.getMid()) { + if (this.getMid() > jmsg.getMid()) { + return -1; + } else { + return 1; + } + } + if (this.getRid() != jmsg.getRid()) { + if (this.getRid() < jmsg.getRid()) { + return -1; + } else { + return 1; + } + } + return 0; + } +}
\ No newline at end of file diff --git a/juick-server-web/src/main/java/com/juick/server/xmpp/extensions/JuickUser.java b/juick-server-web/src/main/java/com/juick/server/xmpp/extensions/JuickUser.java new file mode 100644 index 00000000..534efcc9 --- /dev/null +++ b/juick-server-web/src/main/java/com/juick/server/xmpp/extensions/JuickUser.java @@ -0,0 +1,65 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ +package com.juick.server.xmpp.extensions; +import com.juick.xmpp.StanzaChild; +import com.juick.xmpp.utils.XmlUtils; +import org.apache.commons.text.StringEscapeUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +/** + * + * @author Ugnich Anton + */ +public class JuickUser extends com.juick.User implements StanzaChild { + public final static String XMLNS = "http://juick.com/user"; + public final static String TagName = "user"; + public JuickUser() { + } + @Override + public String getXMLNS() { + return XMLNS; + } + @Override + public JuickUser parse(final XmlPullParser parser) throws XmlPullParserException, IOException { + JuickUser juser = new JuickUser(); + String strUID = parser.getAttributeValue(null, "uid"); + if (strUID != null) { + juser.setUid(Integer.parseInt(strUID)); + } + juser.setName(parser.getAttributeValue(null, "uname")); + XmlUtils.skip(parser); + return juser; + } + public static String toString(com.juick.User user) { + String str = "<" + TagName + " xmlns='" + XMLNS + "'"; + if (user.getUid() > 0) { + str += " uid='" + user.getUid() + "'"; + } + if (user.getName() != null && user.getName().length() > 0) { + str += " uname='" + StringEscapeUtils.escapeXml10(user.getName()) + "'"; + } + str += "/>"; + return str; + } + @Override + public String toString() { + return toString(this); + } +}
\ No newline at end of file diff --git a/juick-server-web/src/main/java/com/juick/server/xmpp/s2s/BasicXmppSession.java b/juick-server-web/src/main/java/com/juick/server/xmpp/s2s/BasicXmppSession.java new file mode 100644 index 00000000..647f2717 --- /dev/null +++ b/juick-server-web/src/main/java/com/juick/server/xmpp/s2s/BasicXmppSession.java @@ -0,0 +1,69 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +package com.juick.server.xmpp.s2s; + +import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.XmppException; +import rocks.xmpp.core.session.ConnectionConfiguration; +import rocks.xmpp.core.session.XmppSession; +import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.stanza.model.IQ; +import rocks.xmpp.core.stanza.model.Message; +import rocks.xmpp.core.stanza.model.Presence; +import rocks.xmpp.core.stanza.model.server.ServerIQ; +import rocks.xmpp.core.stanza.model.server.ServerMessage; +import rocks.xmpp.core.stanza.model.server.ServerPresence; +import rocks.xmpp.core.stream.model.StreamElement; + +/** + * Created by vitalyster on 06.02.2017. + */ +public class BasicXmppSession extends XmppSession { + protected BasicXmppSession(String xmppServiceDomain, XmppSessionConfiguration configuration, ConnectionConfiguration... connectionConfigurations) { + super(xmppServiceDomain, configuration, connectionConfigurations); + } + + public static BasicXmppSession create(String xmppServiceDomain, XmppSessionConfiguration configuration) { + BasicXmppSession session = new BasicXmppSession(xmppServiceDomain, configuration); + notifyCreationListeners(session); + return session; + } + + @Override + public void connect(Jid from) throws XmppException { + + } + + @Override + public Jid getConnectedResource() { + return null; + } + + @Override + protected StreamElement prepareElement(StreamElement element) { + if (element instanceof Message) { + element = ServerMessage.from((Message) element); + } else if (element instanceof Presence) { + element = ServerPresence.from((Presence) element); + } else if (element instanceof IQ) { + element = ServerIQ.from((IQ) element); + } + + return element; + } +} diff --git a/juick-server-web/src/main/java/com/juick/service/security/NotAuthorizedAuthenticationEntryPoint.java b/juick-server-web/src/main/java/com/juick/service/security/NotAuthorizedAuthenticationEntryPoint.java index 133ec3e5..b9bdcaa9 100644 --- a/juick-server-web/src/main/java/com/juick/service/security/NotAuthorizedAuthenticationEntryPoint.java +++ b/juick-server-web/src/main/java/com/juick/service/security/NotAuthorizedAuthenticationEntryPoint.java @@ -30,8 +30,7 @@ import java.io.IOException; */ public class NotAuthorizedAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) - throws IOException, ServletException { + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } } |