Compare commits

...

117 Commits

Author SHA1 Message Date
Ahmed Salah Tawfik Ibrahim 97eae29a93 3.0.1 2024-05-17 11:34:46 +02:00
Ahmed Salah Tawfik Ibrahim 5a2f00813b maven parent 1.2.0 2024-05-17 11:16:13 +02:00
Ahmed Salah Tawfik Ibrahim 88d35fce91 removed logs 2024-04-22 11:19:17 +02:00
Ahmed Salah Tawfik Ibrahim 8509f8cc91 removed logs 2024-04-22 11:16:20 +02:00
Ahmed Salah Tawfik Ibrahim fc04f95b45 removed noisy logs 2024-04-22 10:55:27 +02:00
Ahmed Salah Tawfik Ibrahim 364b076af2 SNL new version 2024-04-16 15:20:37 +02:00
Ahmed Salah Tawfik Ibrahim bd932d3fc6 fix dependency 2024-04-15 15:09:07 +02:00
Ahmed Salah Tawfik Ibrahim ae4f4e593c bug fix 2024-04-12 16:52:08 +02:00
Ahmed Salah Tawfik Ibrahim ccb52f1770 bug fix 2024-04-12 16:39:56 +02:00
Ahmed Salah Tawfik Ibrahim 24fba77a4f bug fix 2024-04-12 16:34:24 +02:00
Ahmed Salah Tawfik Ibrahim 0419a89420 debugging logs added 2024-04-12 16:00:56 +02:00
Ahmed Salah Tawfik Ibrahim f65486e9c0 trigger build 2024-04-11 12:47:26 +02:00
Ahmed Salah Tawfik Ibrahim f46bbbc0c0 Fixed Version 2024-01-29 17:46:55 +01:00
Ahmed Salah Tawfik Ibrahim 1dad8e8eb8 fixed notification method 2024-01-29 15:46:21 +01:00
Ahmed Salah Tawfik Ibrahim 1254246b0d small test 2024-01-15 14:39:24 +01:00
Ahmed Salah Tawfik Ibrahim c5e0bb84e8 Method fix 2023-12-13 14:07:11 +01:00
Ahmed Salah Tawfik Ibrahim 16228bb5b0 Ignore Lib Path 2023-12-07 12:08:01 +01:00
Massimiliano Assante 6242694d8d trying fix for search posts missing deps 2023-12-07 09:31:50 +01:00
Massimiliano Assante bfc98ba8c0 ready to release 2023-12-06 19:03:26 +01:00
Massimiliano Assante 5ddd78cbdd Feature 25766, new impl for get users by role in a VRE 2023-12-06 18:57:33 +01:00
Massimiliano Assante 9067e8ad7e alpha 2023-12-06 18:45:29 +01:00
Massimiliano Assante bc4892af73 made it more robust 2023-12-06 18:38:33 +01:00
Massimiliano Assante 0232f2c9b8 test 2023-12-06 17:48:06 +01:00
Massimiliano Assante 239d7a69c0 test 2023-12-06 17:28:44 +01:00
Massimiliano Assante 5dd5497cf0 test get Roles new 2023-12-06 17:28:03 +01:00
Ahmed Salah Tawfik Ibrahim a7bd85ec57 Working Service 2023-12-06 12:18:22 +01:00
Ahmed Salah Tawfik Ibrahim f6e40e2bbf Working Service 2023-12-05 17:05:38 +01:00
Ahmed Salah Tawfik Ibrahim f5633760d9 Working Service 2023-12-05 17:01:17 +01:00
Ahmed Salah Tawfik Ibrahim bfa2fa36aa Working Service 2023-12-05 16:42:51 +01:00
Ahmed Salah Tawfik Ibrahim 675f509712 Working Service 2023-12-05 16:40:59 +01:00
Ahmed Salah Tawfik Ibrahim 89649a0308 Working Service 2023-12-05 16:32:04 +01:00
Massimiliano Assante 851df04a13 ready to release 2023-12-04 18:42:40 +01:00
Massimiliano Assante d77def7a98 Add REST resources for all the functions in social networking library 2023-12-04 18:39:10 +01:00
Ahmed Salah Tawfik Ibrahim 85a9f1d82c Working Service 2023-12-04 18:28:53 +01:00
Ahmed Salah Tawfik Ibrahim 9ac252085b Working Service 2023-12-04 18:28:07 +01:00
Ahmed Salah Tawfik Ibrahim ef568759ea Working Service 2023-12-04 18:24:55 +01:00
Ahmed Salah Tawfik Ibrahim 1861f0a4d6 Working Service 2023-12-04 17:34:47 +01:00
Ahmed Salah Tawfik Ibrahim d20bb95b1a New Endpoint - attachment path 2023-11-28 19:39:34 +01:00
Ahmed Salah Tawfik Ibrahim fe5e4c7884 New Endpoint 2023-11-28 11:27:20 +01:00
Ahmed Salah Tawfik Ibrahim 26cefd0ac0 Added Author 2023-11-24 11:53:20 +01:00
Ahmed Salah Tawfik Ibrahim a55ba31d9a Social service - More REST API resoruces 2023-11-22 19:52:25 +01:00
Ahmed Salah Tawfik Ibrahim 0551ee95f3 Social service - More REST API resoruces 2023-11-21 18:38:57 +01:00
Ahmed Salah Tawfik Ibrahim ef25c80d68 Social service - cassandra 4 - New POM 2023-11-14 11:32:37 +01:00
Ahmed Salah Tawfik Ibrahim cd1e77e4fc Social service - cassandra 4 2023-11-13 11:33:37 +01:00
Massimiliano Assante 6fce7cf11f ready to release 2023-09-29 18:17:56 +02:00
Massimiliano Assante 23e6026ef4 removed memcached 2023-09-29 18:07:47 +02:00
Massimiliano Assante 522e04d50e removed memcached 2023-09-29 18:07:24 +02:00
Massimiliano Assante 0c4c8d61d1 minor fix 2023-09-29 17:52:51 +02:00
Massimiliano Assante cf100591eb minor fix 2023-09-29 17:44:32 +02:00
Massimiliano Assante 2cd6c13712 updated pom version 2023-09-29 15:12:33 +02:00
Massimiliano Assante 599ac563b8 bug fix #25760 2023-09-29 11:34:01 +02:00
Massimiliano Assante b86d5501fe bugfix 25760 2023-09-29 11:32:16 +02:00
Massimiliano Assante 2e6d0c7521 ready to release 2023-02-09 17:38:26 +01:00
Massimiliano Assante c5382532e5 for CD 2023-02-09 17:16:09 +01:00
Massimiliano Assante 5adae80a1a added the comment in the result object 2023-02-09 17:08:54 +01:00
Massimiliano Assante 628e74258e ready to release 2023-02-09 15:48:51 +01:00
Massimiliano Assante 80aed8b486 renamed postid for coherence 2023-02-09 15:40:56 +01:00
Massimiliano Assante 8b58a29d9f fixed unlike method 2023-02-09 15:31:11 +01:00
Massimiliano Assante 2ebd2b7f8f fixed postid param 2023-02-09 15:09:38 +01:00
Massimiliano Assante 735bb8149b merged conflicts 2023-02-09 12:55:34 +01:00
Massimiliano Assante 77b1c20854 Merge remote-tracking branch 'origin/Feature/24456' 2023-02-09 12:53:16 +01:00
Massimiliano Assante 7bb985500c like and unlike added, to be tested 2023-02-09 12:47:01 +01:00
Massimiliano Assante ef4d5b22ca fix 2023-02-08 16:29:00 +01:00
Massimiliano Assante 09ca845311 found the bug 2023-02-08 16:21:17 +01:00
Massimiliano Assante 5af56a039a trying fix 2023-02-08 16:08:16 +01:00
Massimiliano Assante f67c38ef2d revised writeComment method 2023-02-08 15:37:24 +01:00
Massimiliano Assante cb583b0a50 added comment method with notification, still need testing 2023-02-08 14:29:57 +01:00
Massimiliano Assante 9f696b7f54 commit comment 2023-02-07 11:42:49 +01:00
Massimiliano Assante 4fb2cebe8d fixed the comment object that was wrong 2023-02-02 20:35:48 +01:00
Massimiliano Assante 60e025cb5a fixed bug 2023-02-02 20:23:51 +01:00
Massimiliano Assante 6066406a08 fixed bug 2023-02-02 20:18:14 +01:00
Massimiliano Assante bffac60eb1 added the comment post method 2023-02-02 20:11:52 +01:00
Massimiliano Assante cdf61e73c4 added get-post by id 2023-02-02 19:17:37 +01:00
Massimiliano Assante db5834fcef testing CD 2022-12-20 10:23:56 +01:00
Massimiliano Assante b28f24e4b4 fixed Support #24314 2022-12-15 18:57:36 +01:00
Massimiliano Assante 2b7eb284c5 ready to release 2022-10-25 18:46:43 +02:00
Massimiliano Assante 7bd02b6b01 added likes interface 2022-10-25 18:38:20 +02:00
Massimiliano Assante b068f92888 added getAllCommentsByPostId
fixed javadoc
2022-10-25 18:12:29 +02:00
Massimiliano Assante e2c4be4633 fixed typo 2022-10-25 17:04:14 +02:00
Massimiliano Assante 61203ff9f7 Feature #24022 Add api the get posts with range filter parameters 2022-10-25 16:50:26 +02:00
Massimiliano Assante f0fa56a7dd added check for TokenUtils 2022-10-24 16:32:41 +02:00
Massimiliano Assante 95edfad9db commented version shub2 for release 2022-10-20 19:23:58 +02:00
Massimiliano Assante 15dcd38edb added support for set Message read / unread 2022-10-20 19:21:42 +02:00
Massimiliano Assante 991ad5ca90 ready to release 2022-10-20 19:18:55 +02:00
Massimiliano Assante dcaaa4836b ready to release 2022-10-20 19:17:13 +02:00
Massimiliano Assante 3b367774cc support attachments for write message 2022-10-20 14:45:17 +02:00
Massimiliano Assante 1455a59ac8 updated changelog 2022-10-20 12:22:50 +02:00
Massimiliano Assante 26b8336f05 fixed token utils to support both IAM and Legacy auth corner cases 2022-10-19 19:59:25 +02:00
Massimiliano Assante c6a625d800 fixed typo 2022-10-19 17:23:40 +02:00
Massimiliano Assante 3f78a78926 allow IAM to send Workspace notifications 2022-10-19 17:20:52 +02:00
Massimiliano Assante ff33c24f7c fixed also for messages 2022-10-19 17:19:20 +02:00
Massimiliano Assante a4b8e945d6 o 2022-10-19 17:12:56 +02:00
Massimiliano Assante 93d7af4473 o 2022-10-19 17:11:15 +02:00
Massimiliano Assante 1003c32ffc added log 2022-10-19 16:28:03 +02:00
Massimiliano Assante 72bb6c65ba added possibility to send notifications from Catalogue 2022-10-19 15:54:45 +02:00
Massimiliano Assante 8a60b754ee updated some deps 2022-09-20 18:26:16 +02:00
Massimiliano Assante f466044eee added maven.compiler.source 1.8 2022-09-20 18:25:15 +02:00
Massimiliano Assante 5f68ed34cc - Feature #23891 Refactored following updates social lib 2022-09-20 18:20:03 +02:00
Massimiliano Assante c726b73f1f fix on method get user post quantity 2022-09-20 18:09:51 +02:00
Massimiliano Assante 8470bb032b fixed pom for source version 2022-09-20 16:57:23 +02:00
Massimiliano Assante c9f542fb8f adapted to be built widh JDK 11 2022-09-20 16:53:48 +02:00
Massimiliano Assante 1ed2f32c49 ready to release 2022-09-16 14:35:51 +02:00
Massimiliano Assante 7879cb795f added logs at INFO advising Notificatiom are disabled for the user 2022-09-16 14:33:54 +02:00
Massimiliano Assante 18b2fd231d aaaa 2022-09-16 12:47:30 +02:00
Massimiliano Assante 4efb919c00 aaaa 2022-09-16 12:41:26 +02:00
Massimiliano Assante 4b80189a6e ssss 2022-09-16 12:39:57 +02:00
Massimiliano Assante 9a4784a250 aaa 2022-09-16 12:34:10 +02:00
Massimiliano Assante 87c06555ca aaaa 2022-09-16 12:33:04 +02:00
Massimiliano Assante 944d14aaa0 aaa 2022-09-16 12:26:26 +02:00
Massimiliano Assante 4b50b72ff5 changed params for set notifications 2022-09-16 12:14:11 +02:00
Massimiliano Assante 195d8f1f65 minor fix 2022-09-16 11:46:41 +02:00
Massimiliano Assante cfcbec3bf8 fixed auth on methods 2022-09-16 10:12:22 +02:00
Massimiliano Assante b7169b101c added query params 2022-09-16 08:56:55 +02:00
Massimiliano Assante 7a6f95d466 mising query param 2022-09-15 14:33:13 +02:00
Massimiliano Assante 3ee604924c implemented set and get 2022-09-15 14:24:04 +02:00
Massimiliano Assante 440dd5236b typo in pom fixed 2022-09-14 16:37:26 +02:00
Massimiliano Assante 2c2a68b580 partial implementation (reads) 2022-09-14 16:26:17 +02:00
44 changed files with 3389 additions and 989 deletions

View File

@ -20,12 +20,12 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>

View File

@ -11,6 +11,6 @@ org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -1 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId"/>
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="social-networking-library-ws-3.0.0-SNAPSHOT">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="social-networking-library-ws"/>
<property name="java-output-path" value="/social-networking-library-ws/target/classes"/>
</wb-module>
</project-modules>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="jst.web" version="3.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="jst.jaxrs" version="1.1"/>
<installed facet="java" version="1.8"/>
<installed facet="jst.web" version="3.0"/>
<installed facet="jst.jaxrs" version="2.1"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>

View File

@ -1,5 +1,34 @@
# Changelog
## [v3.0.1] - 2023-04-22
- Feature 27286: removed noisy logs
- Bug 27218: advance social networking library version
## [v3.0.0-SNAPSHOT] - 2023-12-06
- Feature #26193, new impl for get users by role in a VRE
- Replace Astyanx Java client for Cassandra 2 with Datastax client for Cassandra 4
- Add REST resources for all the functions in social networking library
## [v2.9.1] - 2023-09-28
- Fix for Bug #25760 not closing connection to distributed cached
- Removed memcached dep
## [v2.9.0] - 2023-02-13
- Feature #24456 social-networking rest api endpoints (comments, Likes, GetPost)
## [v2.8.0] - 2022-10-20
- Feature #23891 Refactored following updates social lib
- Feature #23847 Social service: temporarily block of notifications for given username(s)
- Feature #23439 Please allow an IAM client to send notifications OPEN
- Feature #23991 Support attachments through notification / message API
- Feature #23995 added support for set Message read / unread
- Feature #24022 added get posts By PostId with range filter parameters and get Comments By PostId
## [v2.7.0] - 2022-09-12
- Sphinx documentation added

View File

@ -22,10 +22,12 @@ See [Releases](https://code-repo.d4science.org/gCubeSystem/social-networking-lib
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Costantino Perciante**
* **Ahmed Ibrahim** ([ORCID](https://orcid.org/0009-0001-3009-5755)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/en/about/people-detail/976/Ahmed_Salah_Tawfik_Ibrahim)
## Maintainers
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Ahmed Ibrahim** ([ORCID](https://orcid.org/0009-0001-3009-5755)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/en/about/people-detail/976/Ahmed_Salah_Tawfik_Ibrahim)
## License

View File

@ -26,7 +26,7 @@ Base URL
In the production environment, its current value is https://api.d4science.org/rest
Authorization
Authorization (how to contact the service)
==================
D4Science adopts state-of-the-art industry standards for authentication and authorization.

212
pom.xml
View File

@ -6,27 +6,31 @@
<parent>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-parent</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</parent>
<groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library-ws</artifactId>
<packaging>war</packaging>
<version>2.7.0</version>
<version>3.0.1</version>
<name>social-networking-library-ws</name>
<description>Rest interface for the social networking library.</description>
<properties>
<java-version>1.8</java-version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<enunciate.version>2.14.0</enunciate.version>
<jackson.version>2.8.11</jackson.version>
<cassandra.driver.oss.version>4.13.0</cassandra.driver.oss.version>
<jackson.version>2.12.6</jackson.version>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<scm>
<connection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
<developerConnection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
<connection>
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
<developerConnection>
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
</scm>
@ -39,6 +43,11 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -66,13 +75,18 @@
<dependency>
<groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-model</artifactId>
<version>[1.1.7-SNAPSHOT, 2.0.0)</version>
<version>[1.2.0-SNAPSHOT, 2.0.0)</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-control-library</artifactId>
<version>[1.0.1,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.common.portal</groupId>
<artifactId>portal-manager</artifactId>
@ -82,7 +96,7 @@
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-client-library</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
<!-- <version>2.0.0-SNAPSHOT</version> -->
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
@ -113,58 +127,6 @@
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>jersey-client</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-bundle</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-apache-client4</artifactId>
<groupId>com.sun.jersey.contribs</groupId>
</exclusion>
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.mortbay.jetty</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax-thrift</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax-cassandra</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax-core</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.gcube.socialnetworking</groupId>
<artifactId>social-util-library</artifactId>
@ -174,7 +136,7 @@
<dependency>
<groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library</artifactId>
<version>[1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
<version>[2.0.0, 3.0.0)</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -198,7 +160,12 @@
<artifactId>authorization-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@ -211,26 +178,78 @@
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>21.0.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<version>2.8.6</version>
</dependency>
<dependency>
<artifactId>jackson-dataformat-cbor</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<version>2.8.6</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Please note that the elasticsearch client needs a compress-lzf version
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<version>2.8.6</version>
</dependency>
<!-- needed by the search-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>${cassandra.driver.oss.version}</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-mapper-runtime</artifactId>
<version>${cassandra.driver.oss.version}</version>
</dependency>
<dependency>
<groupId>com.google</groupId>
<artifactId>gwt-jsonmaker</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- Please note that the elasticsearch client needs a compress-lzf
version
>= 1.0.2 -->
<dependency>
<groupId>com.ning</groupId>
@ -240,7 +259,8 @@
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
<!-- if your container implements Servlet API older than 3.0, use
"jersey-container-servlet-core" -->
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
@ -293,21 +313,30 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3</version>
<scope>compile</scope>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.22</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- SPHINX PLUGIN triggered at 'compile' -->
<plugin>
<groupId>kr.motd.maven</groupId>
<artifactId>sphinx-maven-plugin</artifactId>
<version>2.10.0</version>
<configuration>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
<outputDirectory>
${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
<builder>html</builder>
<configDirectory>${basedir}/docs</configDirectory>
<sourceDirectory>${basedir}/docs</sourceDirectory>
@ -329,7 +358,8 @@
<configuration>
<sourcepath-includes>
<sourcepath-include>
<!-- Include the "com.external:external" artifact on the sourcepath. -->
<!-- Include the "com.external:external" artifact on
the sourcepath. -->
<groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-model</artifactId>
</sourcepath-include>
@ -348,8 +378,12 @@
</execution>
</executions>
</plugin>
<!-- Copy Enunciate Documentation from your-application/docs to your-application.war -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
<!-- Copy Enunciate Documentation from your-application/docs to
your-application.war -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
@ -365,8 +399,10 @@
<outputDirectory>target</outputDirectory>
<resources>
<resource>
<targetPath>${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
<directory>${project.build.directory}/api-docs</directory>
<targetPath>
${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
<directory>
${project.build.directory}/api-docs</directory>
<filtering>true</filtering>
</resource>
</resources>
@ -374,24 +410,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<additionalJOption>-Xdoclint:none</additionalJOption>
</configuration>
<version>3.1.0</version>
<executions>
<execution>
<id>generate-doc</id>
<phase>install</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -16,7 +16,7 @@ public class GroupsCache {
*/
private GroupsCache(){
logger.info("Building cache");
logger.debug("Building cache");
CachesManager.getCache(CachesManager.GROUPS_CACHE);
}
@ -30,7 +30,7 @@ public class GroupsCache {
/**
* Retrieve an entry
* @param id
* @param groupId
* @return user associated to the user
*/
public GCubeGroup getGroup(long groupId){
@ -44,7 +44,7 @@ public class GroupsCache {
/**
* Save an entry into the cache
* @param id
* @param user
* @param group
*/
public void pushEntry(long id, GCubeGroup group){
Ehcache groupsCache = CachesManager.getCache(CachesManager.GROUPS_CACHE);

View File

@ -55,7 +55,7 @@ public class SocialNetworkingSiteFinder {
// read fallback properties
try{
logger.info("Trying to read config.properties");
logger.debug("Trying to read config.properties");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("config.properties");
Properties properties = new Properties();
@ -90,11 +90,11 @@ public class SocialNetworkingSiteFinder {
if(scope == null || scope.isEmpty())
throw new IllegalArgumentException("Scope cannot be null/empty");
if(socialSitesCache.get(scope) != null)
if(socialSitesCache != null && socialSitesCache.get(scope) != null)
return (SocialNetworkingSite) socialSitesCache.get(scope).getObjectValue();
else{
SocialNetworkingSite site = discoverSite(scope);
if(site != null)
if(socialSitesCache != null && site != null)
socialSitesCache.put(new Element(scope, site));
return site;
}
@ -140,7 +140,7 @@ public class SocialNetworkingSiteFinder {
if(gatewayVirtualGroups != null && !gatewayVirtualGroups.isEmpty()){
for (VirtualGroup gatewayVirtualGroup : gatewayVirtualGroups) {
if(virtualGroupsOfGroup.contains(gatewayVirtualGroup)){
logger.info("Matching gateway for scope " + scope + " is " + gateway);
logger.debug("Matching gateway for scope " + scope + " is " + gateway);
matchingGateway = gateway;
break ext_loop;
}

View File

@ -33,7 +33,7 @@ public class UsersCache{
new Thread(){
public void run() {
try{
logger.info("Fetching users and putting them into cache");
logger.debug("Fetching users and putting them into cache");
Ehcache usersCache = CachesManager.getCache(CachesManager.USERS_CACHE);
GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager();
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
@ -59,7 +59,7 @@ public class UsersCache{
/**
* Retrieve an entry
* @param id
* @param userId
* @return user associated to the user
*/
public GCubeUser getUser(long userId){

View File

@ -17,7 +17,7 @@ public class GroupManagerWSBuilder {
private GroupManagerWSBuilder(){
logger.info("Building GroupManager please wait");
logger.debug("Building GroupManager please wait");
try{
groupManagerWs = new LiferayWSGroupManager(
@ -31,7 +31,7 @@ public class GroupManagerWSBuilder {
return;
}
logger.info("GroupManager instance built");
logger.debug("GroupManager instance built");
}

View File

@ -0,0 +1,143 @@
package org.gcube.portal.social.networking.liferay.ws;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.gcube.common.encryption.encrypter.StringEncrypter;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KeycloakAPICredentials {
private static final Logger logger = LoggerFactory.getLogger(KeycloakAPICredentials.class);
// the singleton obj
private static KeycloakAPICredentials singleton = new KeycloakAPICredentials();
// properties that it contains
private String keycloakURL;
private String realm;
private String clientid;
private String password;
// Service endpoint properties
private final static String RUNTIME_RESOURCE_NAME = "IAM";
private final static String CATEGORY = "Service";
/**
* Private constructor
*/
private KeycloakAPICredentials() {
logger.debug("Building KeycloakAPICredentials object");
lookupPropertiesFromIs();
logger.debug("KeycloakAPICredentials object built");
}
/**
* Read the properties from the infrastructure
*/
private void lookupPropertiesFromIs() {
logger.debug("Starting creating KeycloakAPICredentials");
String oldContext = ScopeProvider.instance.get();
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
ScopeProvider.instance.set("/"+ctx.container().configuration().infrastructure());
logger.debug("Discovering liferay user's credentials in context " + ctx.container().configuration().infrastructure());
try{
List<ServiceEndpoint> resources = getConfigurationFromIS();
if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Category " + CATEGORY + " in this scope.");
throw new Exception("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Category " + CATEGORY + " in this scope.");
}
else {
for (ServiceEndpoint res : resources) {
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
while (accessPointIterator.hasNext()) {
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
.next();
if(accessPoint.name().equals("d4science")){
keycloakURL = accessPoint.address();
realm = accessPoint.name();
clientid = accessPoint.username();
password = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
logger.info("Found accesspoint URL = " + keycloakURL);
}
}
}
}
}catch(Exception e){
logger.error("Unable to retrieve such service endpoint information!", e);
return;
}finally{
if(oldContext != null)
ScopeProvider.instance.set(oldContext);
}
logger.debug("Bean built " + toString());
}
/**
* Retrieve endpoints information from IS for DB
* @return list of endpoints for ckan database
* @throws Exception
*/
private List<ServiceEndpoint> getConfigurationFromIS() throws Exception{
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Category/text() eq '"+ CATEGORY +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
return toReturn;
}
public static KeycloakAPICredentials getSingleton() {
if (singleton == null)
singleton = new KeycloakAPICredentials();
return singleton;
}
public String getServerURL() {
return keycloakURL;
}
public String getClientid() {
return clientid;
}
public String getPassword() {
return password;
}
public String getRealm() {
return realm;
}
@Override
public String toString() {
return "KeycloakAPICredentials [keycloakURL=" + keycloakURL + ", realm=" + realm + ", clientid=" + clientid
+ ", password=**************]";
}
}

View File

@ -7,7 +7,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.gcube.common.encryption.StringEncrypter;
import org.gcube.common.encryption.encrypter.StringEncrypter;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
@ -52,10 +52,10 @@ public class LiferayJSONWsCredentials {
* Private constructor
*/
private LiferayJSONWsCredentials() {
logger.info("Building LiferayJSONWsCredentials object");
logger.debug("Building LiferayJSONWsCredentials object");
loadNotifierToken();
lookupPropertiesFromIs();
logger.info("LiferayJSONWsCredentials object built");
logger.debug("LiferayJSONWsCredentials object built");
}
/**
@ -75,7 +75,7 @@ public class LiferayJSONWsCredentials {
*/
private void lookupPropertiesFromIs() {
logger.info("Starting creating LiferayJSONWsCredentials");
logger.debug("Starting creating LiferayJSONWsCredentials");
String oldContext = ScopeProvider.instance.get();
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
@ -118,7 +118,7 @@ public class LiferayJSONWsCredentials {
ScopeProvider.instance.set(oldContext);
}
logger.info("Bean built " + toString());
logger.debug("Bean built " + toString());
}
/**

View File

@ -17,7 +17,7 @@ public class RoleManagerWSBuilder {
private RoleManagerWSBuilder(){
logger.info("Building UserManager please wait");
logger.debug("Building UserManager please wait");
try{
roleManagerWs = new LiferayWSRoleManager(
@ -31,7 +31,7 @@ public class RoleManagerWSBuilder {
return;
}
logger.info("UserManager instance built");
logger.debug("UserManager instance built");
}

View File

@ -17,7 +17,7 @@ public class UserManagerWSBuilder {
private UserManagerWSBuilder(){
logger.info("Building UserManager please wait");
logger.debug("Building UserManager please wait");
try{
userManagerWs = new LiferayWSUserManager(
@ -31,7 +31,7 @@ public class UserManagerWSBuilder {
return;
}
logger.info("UserManager instance built");
logger.debug("UserManager instance built");
}

View File

@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory;
/**
* Exception thrown when @Valid fail
* Exception gets thrown when @Valid fail
*/
@Provider
public class ApplicationException implements ExceptionMapper<Exception> {

View File

@ -0,0 +1,16 @@
package org.gcube.portal.social.networking.ws.ex;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
public class AuthException extends WebApplicationException {
/**
*
*/
private static final long serialVersionUID = 1L;
public AuthException(Throwable cause) {
super(cause, Status.FORBIDDEN);
}
}

View File

@ -0,0 +1,72 @@
package org.gcube.portal.social.networking.ws.inputs;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.webcohesion.enunciate.metadata.DocumentationExample;
/**
* Generic input bean for methods that allow to comment posts
*/
@JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization
public class CommentInputBean implements Serializable{
private static final long serialVersionUID = 5274608088828232980L;
@JsonProperty("text")
@NotNull(message="text cannot be null")
@Size(min=1, message="text cannot be empty")
@DocumentationExample("I would like to comment that ...")
/**
* text the text of the comment
*/
private String text;
@NotNull(message="postid cannot be null")
@JsonProperty("postid")
/**
* postid the postid of the post where you attach the comment
*/
private String postid;
public CommentInputBean() {
super();
}
/**
* @param text
* @param postid
*/
public CommentInputBean(String text, String postid) {
super();
this.text = text;
this.postid = postid;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getPostid() {
return postid;
}
public void setPostid(String postid) {
this.postid = postid;
}
@Override
public String toString() {
return "CommentInputBean [text=" + text + ", postid=" + postid + "]";
}
}

View File

@ -0,0 +1,60 @@
package org.gcube.portal.social.networking.ws.inputs;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Like Bean object
*/
public class LikeInputBean {
@JsonProperty("likeid")
@NotNull(message="likeid cannot be null")
@Size(message="likeid cannot be empty", min=1)
private String likeid;
@JsonProperty("postid")
@NotNull(message="postid cannot be null")
@Size(message="postid cannot be empty", min=1)
private String postid;
public LikeInputBean() {
super();
}
/**
* @param likeid
* @param postid
*/
public LikeInputBean(String likeid, String postid) {
super();
this.likeid = likeid;
this.postid = postid;
}
public String getLikeid() {
return likeid;
}
public void setLikeid(String likeid) {
this.likeid = likeid;
}
public String getPostid() {
return postid;
}
public void setPostid(String postid) {
this.postid = postid;
}
@Override
public String toString() {
return "LikeInputBean [likeid=" + likeid + ", postid=" + postid + "]";
}
}

View File

@ -1,84 +0,0 @@
package org.gcube.portal.social.networking.ws.inputs;
import java.io.Serializable;
import java.util.ArrayList;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Generic input bean for methods that allow to write messages
*/
@JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization
public class MessageInputBean implements Serializable {
private static final long serialVersionUID = -1317811686036127456L;
@JsonProperty("body")
@NotNull(message="body cannot be missing")
@Size(min=1, message="body cannot be empty")
private String body;
@JsonProperty("subject")
@NotNull(message="subject cannot be missing")
@Size(min=1, message="subject cannot be empty")
/**
* subject
*/
private String subject;
@JsonProperty("recipients")
@NotNull(message="recipients cannot be missing")
@Size(min=1, message="at least a recipient is needed")
@Valid // validate recursively
private ArrayList<Recipient> recipients;
public MessageInputBean() {
super();
}
public MessageInputBean(String sender, String body, String subject,
ArrayList<Recipient> recipients) {
super();
//this.sender = sender;
this.body = body;
this.subject = subject;
this.recipients = recipients;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public ArrayList<Recipient> getRecipients() {
return recipients;
}
public void setRecipients(ArrayList<Recipient> recipients) {
this.recipients = recipients;
}
@Override
public String toString() {
return "MessageInputBean ["
+ (body != null ? "body=" + body + ", " : "")
+ (subject != null ? "subject=" + subject + ", " : "")
+ (recipients != null ? "recipients=" + recipients : "") + "]";
}
}

View File

@ -0,0 +1,43 @@
package org.gcube.portal.social.networking.ws.inputs;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Application id object
*/
public class PostId {
@JsonProperty("postid")
@NotNull(message="postid cannot be null")
@Size(message="postid cannot be empty", min=1)
private String postId;
public PostId() {
super();
}
public PostId(String postId) {
super();
this.postId = postId;
}
public String getPostId() {
return postId;
}
public void setPostId(String postId) {
this.postId = postId;
}
@Override
public String toString() {
return "PostId [postid=" + postId + "]";
}
}

View File

@ -1,49 +0,0 @@
package org.gcube.portal.social.networking.ws.inputs;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.webcohesion.enunciate.metadata.DocumentationExample;
/**
* Recipient message bean
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*
*/
@JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization
public class Recipient implements Serializable{
private static final long serialVersionUID = 1071412144446514138L;
@JsonProperty("id")
@NotNull(message="recipient id must not be null")
@Size(min=1, message="recipient id must not be empty")
/*
* @param "The recipient of the message",
*/
@DocumentationExample("john.smith")
private String id;
public Recipient() {
super();
}
public Recipient(String id) {
super();
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "Recipient [id=" + id + "]";
}
}

View File

@ -0,0 +1,63 @@
package org.gcube.portal.social.networking.ws.inputs;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
*
*/
public class UserSetNotificationBean {
@JsonProperty("username")
@NotNull(message="username cannot be null")
@Size(message="username cannot be empty", min=1)
private String username;
@JsonProperty("disableNotification")
@NotNull(message="disableNotification cannot be null")
private Boolean disableNotification;
public UserSetNotificationBean() {
super();
}
/**
* @param username
* @param disableNotification
*/
public UserSetNotificationBean(String username, boolean disableNotification) {
super();
this.username = username;
this.disableNotification = disableNotification;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean isDisableNotification() {
return disableNotification;
}
public void setDisableNotification(boolean disableNotification) {
this.disableNotification = disableNotification;
}
@Override
public String toString() {
return "UserSetNotificationBean [username=" + username + ", disableNotification=" + disableNotification + "]";
}
}

View File

@ -1,53 +0,0 @@
package org.gcube.portal.social.networking.ws.methods.v1;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.slf4j.LoggerFactory;
/**
* Messages services REST interface
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*/
@Path("/messages")
@Deprecated
public class Messages {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Messages.class);
public Messages() {
}
@POST
@Path("writeMessageToUsers/")
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
/**
* Try to send a message to recipientsIds. The sender is the owner of the gcube-token if not otherwise stated.
* @param body
* @param subject
* @return ok on success, error otherwise
*/
@Deprecated
public Response writeMessageToUsers(
@FormParam("sender") String sender, // the optional sender, if missing the sender will be the token's owner.
@FormParam("body") String body,
@FormParam("subject") String subject,
@FormParam("recipients") String recipientsIds) {
if(body == null || body.isEmpty() || subject == null || subject.isEmpty() || recipientsIds == null || recipientsIds.isEmpty()){
logger.error("Missing/wrong request parameters");
return Response.status(Status.BAD_REQUEST).entity(ErrorMessages.MISSING_PARAMETERS).build();
}
return Response.status(Status.METHOD_NOT_ALLOWED).entity(ErrorMessages.DEPRECATED_METHOD).build();
}
}

View File

@ -1,40 +0,0 @@
package org.gcube.portal.social.networking.ws.methods.v1;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.TokensUtils;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory;
/**
* REST interface for the social networking library (users).
*/
@Path("/users")
@Deprecated
public class Users {
@GET
@Path("getUserFullname")
@Produces(MediaType.TEXT_PLAIN)
@Deprecated
public Response getUserUsername(){
return Response.status(Status.METHOD_NOT_ALLOWED).entity(ErrorMessages.DEPRECATED_METHOD).build();
}
@GET
@Path("getUserEmail")
@Produces(MediaType.TEXT_PLAIN)
@Deprecated
public Response getUserEmail(){
return Response.status(Status.METHOD_NOT_ALLOWED).entity(ErrorMessages.DEPRECATED_METHOD).build();
}
}

View File

@ -1,11 +1,17 @@
package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
@ -17,12 +23,22 @@ import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.inputs.CommentInputBean;
import org.gcube.portal.social.networking.ws.inputs.PostInputBean;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.Filters;
import org.gcube.portal.social.networking.ws.utils.SocialUtils;
import org.gcube.socialnetworking.socialtoken.SocialMessageParser;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory;
import com.liferay.portlet.journal.FeedIdException;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
@ -30,6 +46,7 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (comments).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/comments")
@RequestHeaders ({
@ -41,6 +58,50 @@ public class Comments {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Comments.class);
/*
* Retrieve the list of comments belonging to the post id (key) of the token in the related context
* @param key the key as in the POST JSON representation
* @pathExample /get-comments-by-post-id?key=9ea137e9-6606-45ff-a1a2-94d4e8760583
* @return the list of comments belonging to the post identified by the key in the context identified by the token
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-by-post-id")
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllCommentsByPostId(
@NotNull
@QueryParam("key")
String key) {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
List<Comment> comments = null;
try{
logger.debug("Retrieving comments for user id " + username);
comments = CassandraConnection.getInstance().getDatabookStore().getAllCommentByPost(key);
Filters.filterCommentsPerContext(comments, context);
responseBean.setResult(comments);
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve such comments.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/*
* Retrieve the list of comments belonging to the owner of the token in the related context
* @return the list of comments belonging to the owner of the token in the related context.
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-user")
@ -48,9 +109,6 @@ public class Comments {
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/*
* Retrieve the list of comments belonging to the owner of the token in the related context.
*/
public Response getCommentsUser() {
ResponseBean responseBean = new ResponseBean();
@ -61,7 +119,7 @@ public class Comments {
List<Comment> comments = null;
try{
logger.info("Retrieving comments for user id " + username);
logger.debug("Retrieving comments for user id " + username);
comments = CassandraConnection.getInstance().getDatabookStore().getRecentCommentsByUserAndDate(username, 0);
Filters.filterCommentsPerContext(comments, context);
responseBean.setResult(comments);
@ -76,12 +134,12 @@ public class Comments {
return Response.status(status).entity(responseBean).build();
}
/*
* Retrieve comments of the token owner in the context bound to the token itself and filter them by date
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-user-by-time")
/*
* Retrieve comments of the gcube-token's owner in the context bound to the token itself and filter them by date
*/
public Response getCommentsUserByTime(
@QueryParam("time")
@Min(value = 0, message="time cannot be negative")
@ -96,7 +154,7 @@ public class Comments {
List<Comment> comments = null;
try{
logger.info("Retrieving comments for user id " + username);
logger.debug("Retrieving comments for user id " + username);
comments = CassandraConnection.getInstance().getDatabookStore().getRecentCommentsByUserAndDate(username, timeInMillis);
Filters.filterCommentsPerContext(comments, context);
responseBean.setResult(comments);
@ -111,4 +169,65 @@ public class Comments {
return Response.status(status).entity(responseBean).build();
}
/**
* Create a new comment to a post having as owner the auth token's owner
* @param comment The CommentInputBean object
* @return
* @throws ValidationException
*/
@POST
@Path("comment-post")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Successfull created, the new comment is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response writeComment(
@NotNull(message="Comment to write is missing")
@Valid
CommentInputBean comment) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
logger.debug("Request of writing a comment coming from user " + username);
String context = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try {
String postId = comment.getPostid();
String commentText = comment.getText();
String userid = username;
Date time = new Date();
String postOwnerId = CassandraConnection.getInstance().getDatabookStore().readPost(postId).getEntityId();
Comment theComment = SocialUtils.commentPost(userid, time, postId, commentText, postOwnerId, context);
if (theComment != null)
logger.debug("Added comment " + theComment.toString());
else {
logger.error("Unable to write comment");
responseBean.setMessage("Unable to write comment, something went wrong please see server log");
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
responseBean.setResult(theComment);
responseBean.setSuccess(true);
return Response.status(status).entity(responseBean).build();
} catch(FeedIDNotFoundException ex) {
logger.error("Unable to find a post comment", ex);
responseBean.setMessage("Could not reach the DB to write the comment, something went wrong");
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
catch(Exception e) {
logger.error("Unable to write comment", e);
responseBean.setMessage("Could not reach the DB to write the comment, something went wrong");
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
}

View File

@ -1,10 +1,13 @@
package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.List;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@ -13,6 +16,7 @@ import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.Post;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
@ -26,6 +30,7 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (hash tags).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/hashtags")
@RequestHeaders ({
@ -55,7 +60,7 @@ public class HashTags {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
logger.info("User " + username + " has requested hashtags of context " + context);
logger.debug("User " + username + " has requested hashtags of context " + context);
try{
DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore();
@ -76,5 +81,4 @@ public class HashTags {
return Response.status(status).entity(responseBean).build();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,168 @@
package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.List;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.shared.Like;
import org.gcube.portal.social.networking.ws.inputs.LikeInputBean;
import org.gcube.portal.social.networking.ws.inputs.PostId;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.SocialUtils;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (likes).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/likes")
@RequestHeaders ({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
public class Likes {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Likes.class);
/*
* Retrieve the list of likes belonging to the post id (key) of the token in the related context
* @param key the key as in the POST JSON representation
* @pathExample /get-likes-by-post-id?key=9ea137e9-6606-45ff-a1a2-94d4e8760583
* @return the list of likes belonging to the post identified by the key in the context identified by the token
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("get-likes-by-post-id")
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The list of likes is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllLikesByPostId(
@NotNull
@QueryParam("key")
String key) {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
List<Like> likes = null;
try{
logger.debug("Retrieving likes for user id " + username);
likes = CassandraConnection.getInstance().getDatabookStore().getAllLikesByPost(key);
responseBean.setResult(likes);
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve such likes.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Create a new like to a post in the context of the token
* @param postid The post id to be liked
* @return true if everything is OK
* @throws ValidationException
*/
@POST
@Path("like-post")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Successful created, the like operation result is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response like(
@NotNull(message="Post to like is missing")
@Valid
PostId post) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
logger.debug("Request of like coming from user " + username);
String context = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
boolean likeResultOperation = SocialUtils.like(username, post.getPostId(), context);
if (likeResultOperation)
logger.debug("Added like OK to postId " + post.getPostId());
else {
logger.error("Unable to like this post"+ post.getPostId());
responseBean.setMessage("Unable to like, something went wrong please see server log");
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
responseBean.setResult(true);
responseBean.setSuccess(true);
return Response.status(status).entity(responseBean).build();
}
/**
* Unlike to a post in the context of the token
* @param postid The post id to be liked
* @return true if everything is OK
* @throws ValidationException
*/
@POST
@Path("unlike-post")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "The unlike operation result is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response unlike(
@NotNull(message="Post to unlike is missing")
@Valid
LikeInputBean likeInputBean) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
logger.debug("Request of unlike coming from user " + username);
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
boolean likeResultOperation = SocialUtils.unlike(username, likeInputBean.getLikeid(), likeInputBean.getPostid());
if (likeResultOperation)
logger.debug("Unlike OK to postId " + likeInputBean.getPostid());
else {
logger.error("Unable to unlike this post"+ likeInputBean.getPostid());
responseBean.setMessage("Unable to unlike, something went wrong please see server log");
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
responseBean.setResult(true);
responseBean.setSuccess(true);
return Response.status(status).entity(responseBean).build();
}
}

View File

@ -9,6 +9,7 @@ import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@ -22,6 +23,7 @@ import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
import org.gcube.applicationsupportlayer.social.NotificationsManager;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser;
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.library.utils.Caller;
@ -34,11 +36,14 @@ import org.gcube.portal.notifications.thread.MessageNotificationsThread;
import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder;
import org.gcube.portal.social.networking.liferay.ws.LiferayJSONWsCredentials;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.inputs.MessageInputBean;
import org.gcube.portal.social.networking.ws.inputs.Recipient;
import org.gcube.portal.social.networking.ws.ex.AuthException;
import org.gcube.portal.social.networking.ws.inputs.UserSetNotificationBean;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.TokensUtils;
import org.gcube.social_networking.socialnetworking.model.beans.MessageInputBean;
import org.gcube.social_networking.socialnetworking.model.beans.Recipient;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException;
import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
@ -91,15 +96,25 @@ public class Messages {
logger.debug("Incoming message bean is " + input);
Caller caller = AuthorizationProvider.instance.get();
UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser senderUser = null;
SocialNetworkingUser user = null;
// check if the token belongs to an application token. In this case use J.A.R.V.I.S (the username used to communicate with Liferay)
String senderId = null;
String username = null;
String fullName = "";
logger.debug("Catalogue Notification called by " + caller.getClient().getId() + " isUser?"+TokensUtils.isUserToken(caller));
if(!TokensUtils.isUserToken(caller)){
GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
senderId = jarvis.getUsername();
username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
}else{
senderId = caller.getClient().getId();
username = caller.getClient().getId();
senderUser = um.getUserByUsername(username);
fullName = senderUser.getFullname();
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
}
String scope = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
@ -107,7 +122,7 @@ public class Messages {
String body = input.getBody();
String subject = input.getSubject();
List<Recipient> recipientsIds = input.getRecipients(); // "recipients":[{"recipient":"id recipient"}, ......]
logger.info("Sender is going to be the token's owner [" + senderId + "]");
logger.debug("Sender is going to be [" + fullName + "]");
// get the recipients ids (simple check, trim)
List<String> recipientsListFiltered = new ArrayList<String>();
@ -139,23 +154,16 @@ public class Messages {
try{
logger.debug("Trying to send message with body " + body + " subject " + subject + " to users " + recipientsIds + " from " + senderId);
// sender info
GCubeUser senderUser = UserManagerWSBuilder.getInstance().getUserManager().getUserByUsername(senderId);
MessageManagerClient client = AbstractPlugin.messages().build();
logger.debug("Trying to send message with body " + body + " subject " + subject + " to users " + recipientsIds + " from " + username);
// send message
MessageManagerClient client = AbstractPlugin.messages().build();
logger.debug("Sending message to " + recipientsListFiltered);
String messageId = client.sendMessage(recipientsListFiltered, subject, body, null);
String messageId = client.sendMessage(recipientsListFiltered, subject, body, input.getAttachmentIds());
// send notification
logger.debug("Message sent to " + recipientsIds + ". Sending message notification to: " + recipientsIds);
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(scope);
SocialNetworkingUser user = new SocialNetworkingUser(
senderUser.getUsername(), senderUser.getEmail(),
senderUser.getFullname(), senderUser.getUserAvatarURL());
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, ScopeProvider.instance.get(), user);
new Thread(new MessageNotificationsThread(recipientsBeans, messageId, subject, body, nm)).start();
responseBean.setSuccess(true);
@ -187,7 +195,7 @@ public class Messages {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
logger.info("Request for retrieving sent messages by " + username);
logger.debug("Request for retrieving sent messages by " + username);
try{
MessageManagerClient client = AbstractPlugin.messages().build();
@ -223,7 +231,7 @@ public class Messages {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
logger.info("Request for retrieving received messages by " + username);
logger.debug("Request for retrieving received messages by " + username);
try{
MessageManagerClient client = AbstractPlugin.messages().build();
List<Message> getMessages =client.getReceivedMessages();
@ -237,6 +245,51 @@ public class Messages {
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Set message read or unread
* @param messageId the message identifier
* @param read true to set read, false to set unread
* @return the result of the operation
* @throws ValidationException
*/
@POST
@Path("set-message-read/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Message set Read or Unread is correctly executed"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response setMessageRead(
@NotNull(message="input is missing")
@FormParam("messageId") String messageId,
@FormParam("read") Boolean read) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
String opExecutor = "";
try{
opExecutor = caller.getClient().getId();
MessageManagerClient client = AbstractPlugin.messages().build();
client.setRead(messageId, read);
String toReturn = "set Message id:" + messageId + (read ? " read" : " unread");
logger.debug("set Message id:" + messageId + " read?" + read + " for " + opExecutor);
responseBean.setSuccess(true);
responseBean.setResult(toReturn);
} catch(Exception e){
logger.error("Unable to set message read / unread property for user " + opExecutor, e);
responseBean.setSuccess(false);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
}

View File

@ -1,10 +1,10 @@
package org.gcube.portal.social.networking.ws.methods.v2;
import java.net.URL;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.ValidationException;
@ -23,14 +23,16 @@ import javax.ws.rs.core.Response.Status;
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
import org.gcube.applicationsupportlayer.social.NotificationsManager;
import org.gcube.applicationsupportlayer.social.ScopeBeanExt;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser;
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.portal.databook.shared.Notification;
import org.gcube.portal.databook.shared.NotificationChannelType;
import org.gcube.portal.databook.shared.NotificationType;
import org.gcube.portal.databook.shared.RunningJob;
import org.gcube.portal.notifications.bean.GenericItemBean;
@ -40,16 +42,16 @@ import org.gcube.portal.social.networking.caches.UsersCache;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
import org.gcube.portal.social.networking.liferay.ws.LiferayJSONWsCredentials;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.ex.AuthException;
import org.gcube.portal.social.networking.ws.mappers.CatalogueEventTypeMapper;
import org.gcube.portal.social.networking.ws.mappers.JobMapper;
import org.gcube.portal.social.networking.ws.mappers.WorkspaceItemMapper;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.TokensUtils;
import org.gcube.social_networking.socialnetworking.model.beans.JobNotificationBean;
import org.gcube.social_networking.socialnetworking.model.beans.catalogue.CatalogueEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.WorkspaceEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.AddedItemEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.DeletedItemEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.FolderAddedUserEvent;
@ -60,11 +62,13 @@ import org.gcube.social_networking.socialnetworking.model.beans.workspace.Rename
import org.gcube.social_networking.socialnetworking.model.beans.workspace.SharedFolderEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.UnsharedFolderEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.UpdatedItemEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.WorkspaceEvent;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault;
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException;
import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.mortbay.log.Log;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
@ -74,6 +78,7 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (notifications).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/notifications")
@RequestHeaders ({
@ -84,17 +89,18 @@ public class Notifications {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Notifications.class);
private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager";
@GET
@Path("get-range-notifications/")
@Produces(MediaType.APPLICATION_JSON)
/**
* Retrieve notifications of the gcube-token's owner
* Retrieve notifications of the token's owner
* @param from must be greater or equal to 1, range[0, infinity]
* @param quantity quantity must be greater or equal to 0
* @return notifications up to quantity
* @throws ValidationException
*/
@GET
@Path("get-range-notifications/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Notifications retrieved and reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ -130,6 +136,137 @@ public class Notifications {
return Response.status(status).entity(responseBean).build();
}
/**
* Return whether the notifications for this user are enabled or not
* @pathExample /is-user-disabled?username=john.smith
* @responseExample application/json { "success": true, "message": null "result": true }
* @param username the username you want to check
* @return true if the notification for the user are disabled (Catalogue and Workspace ones)
*
*/
@GET
@Path("is-user-disabled/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "true if the notification for the username given as query param are disabled (Catalogue and Workspace ones), false otherwise"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class)
public Response isUserDisabled(
@QueryParam("username") @NotNull(message="username cannot be null")
String username) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
Boolean userDisabled= !isNotificationEnabled(username);
responseBean.setResult(userDisabled);
responseBean.setSuccess(true);
logger.debug("are User " + username + " Notifications Disabled?"+userDisabled);
}catch(Exception e){
logger.error("Unable to read whether the notifications for this user are enabled or not.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
// /**
// * Set user notification enabled or disabled
// * @param disable true if you want to disable the notifications for this user, false if you want to enable them
// * @return the result of the operation
// * @throws ValidationException
// */
// @POST
// @Path("set-user-notifications/")
// @Consumes(MediaType.APPLICATION_JSON)
// @Produces(MediaType.APPLICATION_JSON)
// @StatusCodes ({
// @ResponseCode ( code = 200, condition = "Notification set Off or On correctly executed"),
// @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
// })
// @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class)
// public Response setUserNotifications(
// @NotNull(message="input is missing")
// @Valid
// UserSetNotificationBean setting) throws ValidationException{
//
// Caller caller = AuthorizationProvider.instance.get();
// String context = ScopeProvider.instance.get();
// ResponseBean responseBean = new ResponseBean();
// Status status = Status.OK;
//
//
// try{
// String opExecutor = caller.getClient().getId();
// Boolean result = setUserNotificationsOnOff(setting.getUsername(), setting.isDisableNotification(), opExecutor);
// String toReturn = "Could not set notifications";
// if (result) {
// toReturn = "Notifications have been set";
// toReturn += setting.isDisableNotification() ? " OFF (for 29 days unless re-enabled manually) ": " ON ";
// toReturn += "for username=" + setting.getUsername();
// }
// responseBean.setSuccess(true);
// responseBean.setResult(toReturn);
//
// } catch(Exception e){
// logger.error("Unable to set user notification", e);
// responseBean.setSuccess(false);
// responseBean.setMessage(e.getMessage());
// status = Status.INTERNAL_SERVER_ERROR;
// }
//
//
// return Response.status(status).entity(responseBean).build();
// }
/**
* @deprecated
* @param usernameToCheck
* @return true if notification are enabled for this user
* @throws IOException
*/
private boolean isNotificationEnabled(String usernameToCheck) throws IOException {
// MemcachedClient entries = new DistributedCacheClient().getMemcachedClient();
// String key = SocialUtils.DISABLED_USERS_NOTIFICATIONS_NAMESPACE+usernameToCheck;
// Boolean userEnabled = false;
// if(entries.get(key) == null)
// userEnabled = true;
// entries.getConnection().shutdown();
// return userEnabled;
return true;
}
// /**
// *
// * @param username the user you want to disable or enable notifications (max 29 days)
// * @param callerId the username or clientid of the operation executor
// * @param disable true if you want to disable the notifications for this user
// * @return true if the operation was performed
// * @throws IOException
// */
// private Boolean setUserNotificationsOnOff(String username, boolean disable, String callerId) throws IOException {
// MemcachedClient entries = new DistributedCacheClient().getMemcachedClient();
// String key = SocialUtils.DISABLED_USERS_NOTIFICATIONS_NAMESPACE+username;
// OperationFuture<Boolean> result = null;
// if (disable) {
// result = entries.set(key, SocialUtils.CACHING_TIME_TO_EXPIRATION, "op.ex:" + callerId); //operator executor is who silenced the user
// } else {
// result = entries.delete(key);
// }
// try {
// boolean res = result.getStatus().isSuccess();
// entries.getConnection().shutdown();
// return res;
// } catch (Exception e) {
// entries.getConnection().shutdown();
// e.printStackTrace();
// }
// return null;
// }
/**
* Send a JOB notification to a given recipient
* @param job The job bean
@ -155,7 +292,7 @@ public class Notifications {
Status status = Status.OK;
String appQualifier = caller.getClient().getId();
logger.info("Received request from app " + appQualifier + " to notify job status described by bean " + job);
logger.debug("Received request from app " + appQualifier + " to notify job status described by bean " + job);
try{
@ -203,28 +340,49 @@ public class Notifications {
public Response catalogue(
@NotNull(message="input is missing")
@Valid
CatalogueEvent event) throws ValidationException{
CatalogueEvent event) throws ValidationException, UserManagementSystemException, UserRetrievalFault{
Caller caller = AuthorizationProvider.instance.get();
UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser senderUser = null;
SocialNetworkingUser user = null;
// check if the token belongs to an application token. In this case use J.A.R.V.I.S (the username used to communicate with Liferay)
String username = null;
String fullName = "";
logger.debug("Catalogue Notification called by " + caller.getClient().getId() + " isUser?"+TokensUtils.isUserToken(caller));
if(!TokensUtils.isUserToken(caller)){
GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
}else{
username = caller.getClient().getId();
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
}
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
logger.debug("catalogue notifications from user = " + username);
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
boolean deliveryResult = false;
try {
logger.debug("catalogue notifications type is " + event.getType());
//logger.debug("catalogue notifications type is " + event.getType());
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser senderUser = um.getUserByUsername(username);
SocialNetworkingUser user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
//logger.debug("social networking site is " + site.getName());
//logger.debug("context is " + context);
//logger.debug("user is " + user.getUsername());
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
String[] idsToNotify = event.getIdsToNotify();
if (! event.idsAsGroup()) {
for (int i = 0; i < idsToNotify.length; i++) {
String userIdToNotify = idsToNotify[i];
if (isNotificationEnabled(userIdToNotify)) {
String username2Notify = null;
try {
username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
@ -236,6 +394,11 @@ public class Notifications {
responseBean.setMessage("Username not found, got: " + userIdToNotify);
return Response.status(status).entity(responseBean).build();
}
//logger.debug("username2notify " + username2Notify);
//logger.debug("type is " + CatalogueEventTypeMapper.getType(event.getType()));
//logger.debug("item id is " + event.getItemId());
//logger.debug("item text is " + event.getNotifyText());
//logger.debug("item url is " + event.getItemURL());
deliveryResult =
nm.notifyCatalogueEvent(
@ -244,6 +407,10 @@ public class Notifications {
event.getItemId(),
event.getNotifyText(),
event.getItemURL());
}
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
}
} else { //the ids are contexts
@ -261,6 +428,7 @@ public class Notifications {
String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); //resolve the members
for (int j = 0; j < userIdsToNotify.length; j++) {
String userIdToNotify = userIdsToNotify[j];
if (isNotificationEnabled(userIdToNotify)) {
deliveryResult =
nm.notifyCatalogueEvent(
CatalogueEventTypeMapper.getType(event.getType()),
@ -268,6 +436,9 @@ public class Notifications {
event.getItemId(),
event.getNotifyText(),
event.getItemURL());
} else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
}
}
}
@ -322,22 +493,37 @@ public class Notifications {
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
logger.debug("workspace notifications from user = " + username);
logger.debug("workspace notifications from = " + username);
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
boolean deliveryResult = false;
try {
GCubeUser senderUser = null;
SocialNetworkingUser user = null;
String fullName = "";
logger.debug("workspace notifications type is " + event.getType());
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser senderUser = um.getUserByUsername(username);
SocialNetworkingUser user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
logger.debug("Workspace Notification called by " + caller.getClient().getId() + " isUser?"+TokensUtils.isUserToken(caller));
if(!TokensUtils.isUserToken(caller)){
GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
}else{
username = caller.getClient().getId();
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
}
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
String[] idsToNotify = event.getIdsToNotify();
if (! event.idsAsGroup()) {
for (int i = 0; i < idsToNotify.length; i++) {
String userIdToNotify = idsToNotify[i];
if (isNotificationEnabled(userIdToNotify)) {
String username2Notify = "";
try {
username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
@ -351,6 +537,10 @@ public class Notifications {
}
deliveryResult = notifyWorkspaceEvent(event, nm, username2Notify);
}
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
}
} else { //the ids are contexts
for (int i = 0; i < idsToNotify.length; i++) {
String contextId = idsToNotify[i];
@ -366,7 +556,11 @@ public class Notifications {
String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); //resolve the members
for (int j = 0; j < userIdsToNotify.length; j++) {
String userIdToNotify = userIdsToNotify[j];
if (isNotificationEnabled(userIdToNotify))
deliveryResult = notifyWorkspaceEvent(event, nm, userIdToNotify);
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
}
}
}
@ -487,5 +681,4 @@ public class Notifications {
}
return usernames;
}
}

View File

@ -46,17 +46,17 @@ public class People {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(People.class);
/**
* @responseExample application/json { "success" : true, "message" : null, "result" : { "roles" : [ ], "context" : "***", "avatar" : "https://*****3D", "fullname" : "John Smith", "username" : "john.smith" } }
* @return the user's profile. The user in this case is the one bound to the token
*/
@Produces(MediaType.APPLICATION_JSON)
@GET
@Path("profile")
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of user's profile, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* @responseExample application/json { "success" : true, "message" : null, "result" : { "roles" : [ ], "context" : "***", "avatar" : "https://*****3D", "fullname" : "John Smith", "username" : "john.smith" } }
* @return the user's profile. The user in this case is the one bound to the token
*/
@Produces(MediaType.APPLICATION_JSON)
public Response getProfile(){
Caller caller = AuthorizationProvider.instance.get();

View File

@ -3,6 +3,7 @@ package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.ValidationException;
@ -18,13 +19,17 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.gcube.portal.databook.shared.PostWithAttachment;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.*;
import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException;
import org.gcube.portal.databook.shared.ex.PrivacyLevelTypeNotFoundException;
import org.gcube.portal.social.networking.ws.inputs.PostInputBean;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
@ -40,6 +45,7 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (posts).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/posts")
@RequestHeaders ({
@ -51,6 +57,12 @@ public class Posts {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Posts.class);
/**
* Retrieve posts of the auth token's owner, and allow to filter them by time"
* @param timeInMillis The reference time since when retrieving posts
* @return the posts
* @throws ValidationException
*/
@GET
@Path("get-posts-user-since/")
@Produces(MediaType.APPLICATION_JSON)
@ -58,12 +70,6 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve posts of the auth token's owner, and allow to filter them by time"
* @param timeInMillis The reference time since when retrieving posts
* @return the posts
* @throws ValidationException
*/
public Response getRecentPostsByUserAndDate(
@QueryParam("time") @Min(value = 0, message="time cannot be negative")
long timeInMillis
@ -74,19 +80,19 @@ public class Posts {
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
List<Feed> feeds = null;
List<Post> posts = null;
try{
logger.info("Retrieving feeds for user id " + username + " and reference time " + timeInMillis);
feeds = CassandraConnection.getInstance().getDatabookStore().getRecentFeedsByUserAndDate(username, timeInMillis);
Filters.filterFeedsPerContext(feeds, context);
Filters.hideSensitiveInformation(feeds, caller.getClient().getId());
responseBean.setResult(feeds);
logger.debug("Retrieving post for user id " + username + " and reference time " + timeInMillis);
posts = CassandraConnection.getInstance().getDatabookStore().getRecentPostsByUserAndDate(username, timeInMillis);
Filters.filterPostsPerContext(posts, context);
Filters.hideSensitiveInformation(posts, caller.getClient().getId());
responseBean.setResult(posts);
responseBean.setMessage("");
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve such feeds.", e);
logger.error("Unable to retrieve such posts.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
@ -95,6 +101,11 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve all user's posts
* @return all posts of the auth token's owner in the context identified by the token
*/
@GET
@Path("get-posts-user/")
@Produces(MediaType.APPLICATION_JSON)
@ -102,10 +113,6 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve all user's posts
* @return all posts of the auth token's owner in the context identified by the token
*/
public Response getAllPostsByUser() {
Caller caller = AuthorizationProvider.instance.get();
@ -113,13 +120,13 @@ public class Posts {
String context = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
List<Feed> feeds = null;
List<Post> posts = null;
try{
logger.debug("Retrieving feeds for user with id " + username);
feeds = CassandraConnection.getInstance().getDatabookStore().getAllFeedsByUser(username);
Filters.filterFeedsPerContext(feeds, context);
Filters.hideSensitiveInformation(feeds, caller.getClient().getId());
responseBean.setResult(feeds);
logger.debug("Retrieving posts for user with id " + username);
posts = CassandraConnection.getInstance().getDatabookStore().getAllPostsByUser(username);
Filters.filterPostsPerContext(posts, context);
Filters.hideSensitiveInformation(posts, caller.getClient().getId());
responseBean.setResult(posts);
responseBean.setMessage("");
responseBean.setSuccess(true);
}catch(Exception e){
@ -132,6 +139,60 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve a post by id
* @return the post if the post id belongs to a post in the context identified by the token
*/
@GET
@Path("get-post/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getPost(@QueryParam("id") String id) {
String context = ScopeProvider.instance.get();
Caller caller = AuthorizationProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
List<Post> posts = new ArrayList<>();
try{
logger.debug("Retrieving post with id " + id);
try {
posts.add(CassandraConnection.getInstance().getDatabookStore().readPost(id));
} catch(FeedIDNotFoundException e){
responseBean.setMessage("The post with id " + id + " does not exist in context " + context);
responseBean.setSuccess(false);
return Response.status(status).entity(responseBean).build();
}
Filters.filterPostsPerContext(posts, context);
Filters.hideSensitiveInformation(posts, caller.getClient().getId());
if (posts.isEmpty()) {
responseBean.setMessage("The post with id " + id + " does not belong to this context " + context);
responseBean.setSuccess(false);
status = Status.FORBIDDEN;
return Response.status(status).entity(responseBean).build();
}
responseBean.setResult(posts.get(0));
responseBean.setMessage("");
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve such post.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve a given quantity of latest user's posts
* @param quantity the number of latest post to get
* @pathExample /get-posts-user-quantity?quantity=10
* @return all posts of the auth token's owner in the context identified by the token, in reverse chronological order up to quantity (at most)
* @throws ValidationException
*/
@GET
@Path("get-posts-user-quantity/")
@Produces(MediaType.APPLICATION_JSON)
@ -139,12 +200,6 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve a given quantity of latest user's posts
* @param quantity the number of latest post to get
* @return all posts of the auth token's owner in the context identified by the token, in reverse chronological order up to quantity (at most)
* @throws ValidationException
*/
public Response getQuantityPostsByUser(
@DefaultValue("10")
@QueryParam("quantity")
@ -157,7 +212,7 @@ public class Posts {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
List<Feed> feeds = new ArrayList<Feed>();
List<Post> posts = new ArrayList<>();
// if quantity is zero, just return an empty list
if(quantity == 0){
@ -165,15 +220,19 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
try{
logger.debug("Retrieving last " + quantity + " feeds made by user " + username);
feeds = CassandraConnection.getInstance().getDatabookStore().getRecentFeedsByUser(username, -1);
Filters.filterFeedsPerContext(feeds, context);
feeds = feeds.subList(0, quantity);
Filters.hideSensitiveInformation(feeds, caller.getClient().getId());
responseBean.setResult(feeds);
logger.debug("getRecentPostsByUser first, posts made by user " + username);
posts = CassandraConnection.getInstance().getDatabookStore().getAllPostsByUser(username);
if (posts != null)
logger.debug("got " + posts.size() + " posts");
logger.debug("Retrieving last " + quantity + " posts made by user " + username + " in context = "+context);
Filters.filterPostsPerContext(posts, context);
quantity = (quantity > posts.size()) ? posts.size() : quantity;
posts = posts.subList(0, quantity);
Filters.hideSensitiveInformation(posts, caller.getClient().getId());
responseBean.setResult(posts);
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve such feeds.", e);
logger.error("Unable to retrieve such posts.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
@ -181,6 +240,12 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Create a new user post having as owner the auth token's owner
* @param post The post to be written
* @return
* @throws ValidationException
*/
@POST
@Path("write-post-user")
@Consumes(MediaType.APPLICATION_JSON)
@ -189,12 +254,6 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Create a new user post having as owner the auth token's owner
* @param post The post to be written
* @return
* @throws ValidationException
*/
public Response writePostUser(
@NotNull(message="Post to write is missing")
@Valid
@ -218,14 +277,14 @@ public class Posts {
// convert enablenotification parameter
if(enableNotification)
logger.info("Enable notification for this user post.");
logger.debug("Enable notification for this user post.");
else
logger.info("Disable notification for this user post.");
logger.debug("Disable notification for this user post.");
// try to share
logger.debug("Trying to share user feed...");
Feed res = SocialUtils.shareUserUpdate(
logger.debug("Trying to share user post...");
Post res = SocialUtils.shareUserUpdate(
username,
postText,
context,
@ -253,6 +312,10 @@ public class Posts {
}
/**
* Retrieve the application's posts
* @return the application (IAM Client) posts belonging to the token's owner (i.e., an application)"
*/
@GET
@Path("get-posts-app/")
@Produces(MediaType.APPLICATION_JSON)
@ -261,10 +324,6 @@ public class Posts {
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve the application's posts
* @return the application's posts belonging to the token's owner (i.e., an application)"
*/
public Response getAllPostsByApp() {
Caller caller = AuthorizationProvider.instance.get();
@ -286,9 +345,9 @@ public class Posts {
}
try{
logger.debug("Retrieving feeds for app with id " + appId);
List<Feed> feeds = CassandraConnection.getInstance().getDatabookStore().getAllFeedsByApp(appId);
Filters.filterFeedsPerContext(feeds, context);
logger.debug("Retrieving posts for app with id " + appId);
List<Post> feeds = CassandraConnection.getInstance().getDatabookStore().getAllPostsByApp(appId);
Filters.filterPostsPerContext(feeds, context);
responseBean.setSuccess(true);
responseBean.setResult(feeds);
@ -304,6 +363,11 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Create a new application post having as owner-application the token's owner (the IAM Client), note that the application must be registered on the Information System
* @param post The post to be written
* @return
*/
@POST
@Path("write-post-app")
@Consumes(MediaType.APPLICATION_JSON)
@ -313,11 +377,6 @@ public class Posts {
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Create a new application post having as owner-application the token's owner (the IAM Client)
* @param post The post to be written
* @return
*/
public Response writePostApp(
@NotNull(message="Post to write is null")
@Valid
@ -343,7 +402,7 @@ public class Posts {
}
// parse
String feedText = post.getText();
String postText = post.getText();
String previewTitle = post.getPreviewtitle();
String previewDescription = post.getPreviewdescription();
String httpImageUrl = post.getHttpimageurl();
@ -356,9 +415,9 @@ public class Posts {
else
logger.debug("Disable notification for this application post.");
// write feed + notification if it is the case
Feed written = SocialUtils.shareApplicationUpdate(
feedText,
// write post + notification if it is the case
Post written = SocialUtils.shareApplicationUpdate(
postText,
params,
previewTitle,
previewDescription,
@ -381,6 +440,10 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
*
* @return all the posts in the context bound to the auth token
*/
@GET
@Path("get-posts-vre/")
@Produces(MediaType.APPLICATION_JSON)
@ -388,24 +451,20 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
*
* @return all the posts in the context bound to the auth token
*/
public Response getAllPostsByVRE() {
String scope = ScopeProvider.instance.get();
String context = ScopeProvider.instance.get();
Caller caller = AuthorizationProvider.instance.get();
logger.debug("Retrieving all posts coming from vre = " + scope);
logger.debug("Retrieving all posts coming from vre = " + context);
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
List<Feed> feeds = CassandraConnection.getInstance().getDatabookStore().getAllFeedsByVRE(scope);
Filters.hideSensitiveInformation(feeds, caller.getClient().getId());
responseBean.setResult(feeds);
List<Post> posts = CassandraConnection.getInstance().getDatabookStore().getAllPostsByVRE(context);
Filters.hideSensitiveInformation(posts, caller.getClient().getId());
responseBean.setResult(posts);
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve feeds for vre = " + scope, e);
logger.error("Unable to retrieve posts for vre = " + context, e);
status = Status.INTERNAL_SERVER_ERROR;
responseBean.setMessage(e.toString());
responseBean.setSuccess(false);
@ -414,6 +473,60 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* return the most recent posts for this vre up to quantity param and the last index of the posts in the timeline
* lastReturnedPostTimelineIndex is useful to know from where to start the range the next time you ask, because there are deletions
*
* @param from the range start (most recent feeds for this vre) has to be greater than 0
* @param quantity the number of most recent feeds for this vre starting from "from" param
* @pathExample /get-recent-posts-vre-by-range?from=1&quantity=10
* @return a <class>RangePosts</class> containing of most recent feeds for this vre
* @throws FeedTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
@GET
@Path("get-recent-posts-vre-by-range/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getRecentPostsByVREAndRange(
@QueryParam("from")
@Min(value=1, message="from cannot be negative")
int from,
@QueryParam("quantity")
@Min(value=1, message="quantity cannot be negative")
int quantity) throws ValidationException {
String context = ScopeProvider.instance.get();
Caller caller = AuthorizationProvider.instance.get();
logger.debug("Retrieving all posts coming from vre = " + context);
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
RangePosts rangePosts = CassandraConnection.getInstance().getDatabookStore().getRecentPostsByVREAndRange(context, from, quantity);
Filters.hideSensitiveInformation(rangePosts.getPosts(), caller.getClient().getId());
responseBean.setResult(rangePosts);
responseBean.setSuccess(true);
}catch(Exception e){
logger.error("Unable to retrieve posts for vre = " + context, e);
status = Status.INTERNAL_SERVER_ERROR;
responseBean.setMessage(e.toString());
responseBean.setSuccess(false);
}
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve posts containing the hashtag in the context bound to the auth token
* @param hashtag he hashtag to be contained within the posts
* @pathExample /get-posts-by-hashtag?hashtag=#thehashtag
* @return the posts in the context bound to the auth token matching the hashtag
* @throws ValidationException
*/
@GET
@Path("get-posts-by-hashtag/")
@Produces({MediaType.APPLICATION_JSON})
@ -421,12 +534,6 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve posts containing the hashtag in the context bound to the auth token
* @param hashtag he hashtag to be contained within the posts
* @return the posts in the context bound to the auth token matching the hashtag
* @throws ValidationException
*/
public Response getPostsByHashTags(
@QueryParam("hashtag")
@NotNull(message="hashtag cannot be missing")
@ -437,12 +544,12 @@ public class Posts {
String context = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
logger.info("User " + username + " has requested posts containing hashtag " + hashtag + " in context " + context);
logger.debug("User " + username + " has requested posts containing hashtag " + hashtag + " in context " + context);
try{
DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore();
List<Feed> feeds = datastore.getVREFeedsByHashtag(context, hashtag);
Filters.hideSensitiveInformation(feeds, caller.getClient().getId());
responseBean.setResult(feeds);
List<Post> posts = datastore.getVREPostsByHashtag(context, hashtag);
Filters.hideSensitiveInformation(posts, caller.getClient().getId());
responseBean.setResult(posts);
responseBean.setSuccess(true);
}catch(Exception e){
@ -452,6 +559,10 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve ids (UUID) of the liked posts by the user
* @return ids (UUID) of the liked posts by the user in the context bound to the auth token
*/
@GET
@Path("get-id-liked-posts/")
@Produces({MediaType.APPLICATION_JSON})
@ -459,30 +570,26 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Sccessfull retrieved ids, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve ids (UUID) of the liked by the user
* @return ids (UUID) of the liked by the user in the context bound to the auth token
*/
public Response getAllLikedPostIdsByUser() {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
String context = ScopeProvider.instance.get();
logger.debug("Retrieving all liked feeds for user with id " + username + " in context " + context);
logger.debug("Retrieving all liked posts for user with id " + username + " in context " + context);
List<String> retrievedLikedFeedsIds = null;
List<String> retrievedLikedPostsIds = null;
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore();
retrievedLikedFeedsIds = datastore.getAllLikedFeedIdsByUser(username);
Filters.filterFeedsPerContextById(retrievedLikedFeedsIds, context);
responseBean.setResult(retrievedLikedFeedsIds);
retrievedLikedPostsIds = datastore.getAllLikedPostIdsByUser(username);
Filters.filterFeedsPerContextById(retrievedLikedPostsIds, context);
responseBean.setResult(retrievedLikedPostsIds);
responseBean.setSuccess(true);
logger.debug("Ids of liked feeds by " + username + " retrieved");
logger.debug("Ids of liked posts by " + username + " retrieved");
}catch(Exception e){
logger.error("Unable to read such ids of liked feeds.", e);
logger.error("Unable to read such ids of liked Posts.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
@ -491,6 +598,12 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve posts liked by the user
* @param limit The maximum number of posts to be retrieved
* @return posts liked by the user (up to a given quantity) in the context bound to the auth token
* @throws ValidationException
*/
@GET
@Path("get-liked-posts/")
@Produces(MediaType.APPLICATION_JSON)
@ -498,12 +611,6 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Retrieve posts liked by the user
* @param limit The maximum number of posts to be retrieved
* @return posts liked by the user (up to a given quantity) in the context bound to the auth token
* @throws ValidationException
*/
public Response getAllLikedPostsByUser(
@DefaultValue("10")
@QueryParam("limit")
@ -513,24 +620,83 @@ public class Posts {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
String context = ScopeProvider.instance.get();
List<Feed> retrievedLikedFeeds = null;
List<Post> retrievedLikedPosts = null;
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
logger.debug("Retrieving " + limit + " liked feeds for user with id " + username + " in context " + context);
retrievedLikedFeeds = CassandraConnection.getInstance().getDatabookStore().getAllLikedFeedsByUser(username, limit);
Filters.filterFeedsPerContext(retrievedLikedFeeds, context);
Filters.hideSensitiveInformation(retrievedLikedFeeds, caller.getClient().getId());
responseBean.setResult(retrievedLikedFeeds);
logger.debug("Retrieving " + limit + " liked posts for user with id " + username + " in context " + context);
retrievedLikedPosts = CassandraConnection.getInstance().getDatabookStore().getAllLikedPostsByUser(username, limit);
Filters.filterPostsPerContext(retrievedLikedPosts, context);
Filters.hideSensitiveInformation(retrievedLikedPosts, caller.getClient().getId());
responseBean.setResult(retrievedLikedPosts);
responseBean.setSuccess(true);
logger.debug("Liked feeds by " + username + " retrieved");
logger.debug("Liked posts by " + username + " retrieved");
}catch(Exception e){
logger.error("Unable to read such liked feeds.", e);
logger.error("Unable to read such liked posts.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
//libapi
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("save-user-post-attachments-lib")
public Response saveUserPostLib(
@NotNull(message="post to add is missing")
@Valid
PostWithAttachment postWithAttachment
) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
Post post = postWithAttachment.getPost();
logger.debug("Post is " + post);
List<Attachment> attachments = postWithAttachment.getAttachments();
logger.debug("Attachments are " + attachments);
boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserPost(post,attachments);
responseBean.setResult(result);
responseBean.setMessage("");
responseBean.setSuccess(result);
}catch(Exception e){
logger.error("Unable to write comment.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("save-app-post-attachments-lib")
public Response saveAppPostLib(
@NotNull(message="post to add is missing")
@Valid
PostWithAttachment postWithAttachment
) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
Post post = postWithAttachment.getPost();
List<Attachment> attachments = postWithAttachment.getAttachments();
boolean result = CassandraConnection.getInstance().getDatabookStore().saveAppPost(post,attachments);
responseBean.setResult(result);
responseBean.setMessage("");
responseBean.setSuccess(result);
}catch(Exception e){
logger.error("Unable to write comment.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
}

View File

@ -70,7 +70,7 @@ public class Tokens {
status = Status.FORBIDDEN;
return Response.status(status).entity(responseBean).build();
}
logger.info("Generating token for the application with id " + appId);
logger.debug("Generating token for the application with id " + appId);
// each token is related to an identifier and the context
String appToken = authorizationService().generateExternalServiceToken(appId);
responseBean.setSuccess(true);

View File

@ -24,6 +24,7 @@ import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.portal.social.networking.caches.UsersCache;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
import org.gcube.portal.social.networking.liferay.ws.KeycloakAPICredentials;
import org.gcube.portal.social.networking.liferay.ws.RoleManagerWSBuilder;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
@ -35,6 +36,11 @@ import org.gcube.vomanagement.usermanagement.RoleManager;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeRole;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
@ -57,6 +63,12 @@ public class Users {
private static final String NOT_USER_TOKEN_CONTEXT_USED = "User's information can only be retrieved through a user token (not qualified)";
private static final List<String> GLOBAL_ROLES_ALLOWED_BY_LOCAL_CALL_METHOD = Arrays.asList("DataMiner-Manager","Quota-Manager");
/**
* Read a user's custom attribute. The user is the one owning the token
* @param attributeKey The key of the attribute to be read
* @return the user's custom attribute
* @throws ValidationException
*/
@GET
@Path("get-custom-attribute/")
@Produces(MediaType.APPLICATION_JSON)
@ -65,12 +77,6 @@ public class Users {
@ResponseCode ( code = 404, condition = "Such an attribute doesn't exist"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Read a user's custom attribute. The user is the one owning the token
* @param attributeKey The key of the attribute to be read
* @return the user's custom attribute
* @throws ValidationException
*/
public Response readCustomAttr(
@QueryParam("attribute")
@NotNull(message="attribute name is missing")
@ -106,7 +112,10 @@ public class Users {
return Response.status(status).entity(responseBean).build();
}
/**
* Read the user's fullname. The user is the one owning the token
* @return the user's fullname
*/
@GET
@Path("get-fullname")
@Produces(MediaType.APPLICATION_JSON)
@ -114,10 +123,6 @@ public class Users {
@ResponseCode ( code = 200, condition = "The user's fullname is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Read the user's fullname. The user is the one owning the token
* @return the user's fullname
*/
public Response getUserFullname(){
Caller caller = AuthorizationProvider.instance.get();
@ -136,7 +141,7 @@ public class Users {
GCubeUser user = userManager.getUserByUsername(username);
fullName = user.getFullname();
logger.info("Found fullname " + fullName + " for user " + username);
logger.debug("Found fullname " + fullName + " for user " + username);
responseBean.setResult(fullName);
responseBean.setSuccess(true);
@ -150,6 +155,10 @@ public class Users {
return Response.status(status).entity(responseBean).build();
}
/**
* Read the user's email address. The user is the one owning the token
* @return rhe user's email address
*/
@GET
@Path("get-email")
@Produces(MediaType.APPLICATION_JSON)
@ -157,10 +166,6 @@ public class Users {
@ResponseCode ( code = 200, condition = "The user's email is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* Read the user's email address. The user is the one owning the token
* @return rhe user's email address
*/
public Response getUserEmail(){
Caller caller = AuthorizationProvider.instance.get();
@ -177,7 +182,7 @@ public class Users {
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser user = userManager.getUserByUsername(username);
email = user.getEmail();
logger.info("Found email " + email + " for user " + username);
logger.debug("Found email " + email + " for user " + username);
responseBean.setResult(email);
responseBean.setSuccess(true);
@ -494,51 +499,61 @@ public class Users {
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
String context = ScopeProvider.instance.get();
KeycloakAPICredentials apiService = KeycloakAPICredentials.getSingleton();
Keycloak keycloak;
keycloak = KeycloakBuilder.builder()
.serverUrl(apiService.getServerURL())
.realm(apiService.getRealm())
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(apiService.getClientid()) //
.clientSecret(apiService.getPassword()).build();
List<String> usernames = new ArrayList<String>();
try {
GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager();
RoleManager roleManager = RoleManagerWSBuilder.getInstance().getRoleManager();
long roleId = roleManager.getRoleIdByName(roleName);
if(roleId > 0){
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
List<GCubeUser> users = null;
long groupId = groupManager.getGroupIdFromInfrastructureScope(context);
// first check if for any reason this is a global role, then (if result is null or exception arises) check for site role
// Global role's users are retrieved much faster
try{
if(GLOBAL_ROLES_ALLOWED_BY_LOCAL_CALL_METHOD.contains(roleName)){
// TODO inconsistent value can be returned
users = userManager.listUsersByGlobalRole(roleId);
}
}catch(Exception globalExp){
logger.warn("Failed while checking for global role... trying with local one", globalExp);
}
if(users == null || users.isEmpty()){
logger.debug("User list is still null/empty, checking for local information");
users = userManager.listUsersByGroupAndRole(groupId, roleId);
}
List<UserRepresentation> users = searchByRole(keycloak, apiService.getRealm(), context, roleName);
if(users != null){
for (GCubeUser gCubeUser : users) {
usernames.add(gCubeUser.getUsername());
for (UserRepresentation user : users) {
usernames.add(user.getUsername());
}
}
responseBean.setResult(usernames);
responseBean.setSuccess(true);
}else{
responseBean.setMessage("No role exists whit such a name");
status = Status.BAD_REQUEST;
}
} catch(Exception e){
logger.error("Unable to retrieve user's usernames", e);
logger.error("Unable to retrieve user with the requested role", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
private static List<UserRepresentation> searchByRole(Keycloak keycloak, String realmName, String context, String roleName) {
logger.debug("Searching by role: {}", roleName);
String clientIdContext = context.replace("/", "%2F") ;
List<ClientRepresentation> clients = keycloak.realm(realmName)
.clients().findByClientId(clientIdContext);
String id = "";
for (ClientRepresentation client : clients) {
logger.debug("found client ="+client.getClientId());
logger.debug("found client id="+client.getId());
id =client.getId();
}
List<UserRepresentation> users = keycloak.realm(realmName)
.clients()
.get(id).roles().get(roleName)
.getUserMembers(0, 100000);
return users;
}
@GET
@Path("user-exists")
@Produces(MediaType.APPLICATION_JSON)

View File

@ -31,7 +31,6 @@ public class ResponseBean implements Serializable {
* @param success
* @param message
* @param result
* @param help
*/
public ResponseBean(boolean success, String message, Object result) {
super();

View File

@ -22,9 +22,9 @@ public class CassandraConnection {
private CassandraConnection(){
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
logger.info("Getting connection to cassandra");
logger.debug("Getting connection to cassandra");
store = new DBCassandraAstyanaxImpl(ctx.container().configuration().infrastructure());
logger.info("Connection to cassandra created");
logger.debug("Connection to cassandra created");
}
/**

View File

@ -24,9 +24,9 @@ public class ElasticSearchConnection {
private ElasticSearchConnection(){
try {
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
logger.info("Creating connection to Elasticsearch");
logger.debug("Creating connection to Elasticsearch");
es = new ElasticSearchClientImpl(ctx.container().configuration().infrastructure());
logger.info("Elasticsearch connection created");
logger.debug("Elasticsearch connection created");
} catch (Exception e) {
logger.error("Failed to connect to elasticsearch", e);
}

View File

@ -8,6 +8,7 @@ import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.EnhancedFeed;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.Post;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault;
@ -88,10 +89,11 @@ public class Filters {
* If the initial context is the root: all feeds are returned;
* If the initial context is a VO: feeds for vres within the vo are returned;
* If the initial context is a vre: feeds of the vre are returned;
* @param retrievedLikedFeeds
* @param feeds
* @param context
* @throws Exception
*/
@Deprecated
public static void filterFeedsPerContext(List<Feed> feeds, String context) throws Exception {
List<String> contexts = getContexts(context);
@ -104,6 +106,27 @@ public class Filters {
iterator.remove();
}
}
/**
* Given a list of not filtered posts, the methods remove posts unaccessible in this scope.
* If the initial context is the root: all posts are returned;
* If the initial context is a VO: posts for vres within the vo are returned;
* If the initial context is a vre: posts of the vre are returned;
* @param context
* @throws Exception
*/
public static void filterPostsPerContext(List<Post> posts, String context) throws Exception {
List<String> contexts = getContexts(context);
// filter
Iterator<Post> iterator = posts.iterator();
while (iterator.hasNext()) {
Post post = (Post) iterator.next();
if(!contexts.contains(post.getVreid()))
iterator.remove();
}
}
/**
@ -137,7 +160,7 @@ public class Filters {
/**
* Depending on the type of object provided (e.g. Feed, Comment etc), some information are removed
* @param comments
* @param toClear
* @throws Exception
*/
public static <T> void hideSensitiveInformation(List<T> toClear, String usernameCaller){

View File

@ -6,8 +6,12 @@ import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
@ -24,11 +28,15 @@ import org.gcube.common.resources.gcore.utils.XPathHelper;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.FeedType;
import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.Like;
import org.gcube.portal.databook.shared.Post;
import org.gcube.portal.databook.shared.PostType;
import org.gcube.portal.databook.shared.PrivacyLevel;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.notifications.bean.GenericItemBean;
import org.gcube.portal.notifications.thread.CommentNotificationsThread;
import org.gcube.portal.notifications.thread.LikeNotificationsThread;
import org.gcube.portal.notifications.thread.MentionNotificationsThread;
import org.gcube.portal.notifications.thread.PostNotificationsThread;
import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder;
@ -42,6 +50,10 @@ import org.gcube.social_networking.socialutillibrary.Utils;
import org.gcube.socialnetworking.socialtoken.SocialMessageParser;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.exception.TeamRetrievalFault;
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException;
import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault;
import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
@ -49,14 +61,16 @@ import org.xml.sax.InputSource;
/**
* Utility class.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
@SuppressWarnings("deprecation")
public class SocialUtils {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SocialUtils.class);
public final static String NO_TEXT_FILE_SHARE = "_N0_73X7_SH4R3_";
public final static int CACHING_TIME_TO_EXPIRATION = 2506000;//29 days 6 minutes 40 seconds
public final static String DISABLED_USERS_NOTIFICATIONS_NAMESPACE = "dun:";
// name of the portlet for vre notification
public static final String NEWS_FEED_PORTLET_CLASSNAME = "org.gcube.portlets.user.newsfeed.server.NewsServiceImpl";
@ -94,14 +108,14 @@ public class SocialUtils {
/**
* Method used when an application needs to publish something.
* @param feedText
* @param postText
* @param uriParams
* @param previewTitle
* @param previewDescription
* @param httpImageUrl
* @return true upon success, false on failure
*/
public static Feed shareApplicationUpdate(
public static Post shareApplicationUpdate(
String postText,
String uriParams,
String previewTitle,
@ -121,12 +135,12 @@ public class SocialUtils {
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
escapedPostText = Utils.convertMentionUsernamesAnchorHTML(escapedPostText, mentionedUsersToConvertInHTML, site.getSiteURL(), site.getSiteLandingPagePath());
logger.info("*** Escaped post text is " + escapedPostText);
logger.debug("*** Escaped post text is " + escapedPostText);
String scope = ScopeProvider.instance.get();
String appId = caller.getClient().getId();
Feed toWrite =
Post toWrite =
buildPost(
escapedPostText,
uriParams == null ? "" : uriParams,
@ -137,10 +151,10 @@ public class SocialUtils {
scope);
// try to save it
boolean res = CassandraConnection.getInstance().getDatabookStore().saveAppFeed(toWrite);
boolean res = CassandraConnection.getInstance().getDatabookStore().saveAppPost(toWrite);
if(res){
logger.info("Feed correctly written by application " + appId);
logger.debug("Feed correctly written by application " + appId);
// wait a bit before saving hashtags
if(hashtags != null && !hashtags.isEmpty())
@ -215,7 +229,7 @@ public class SocialUtils {
* @param previewThumbnailUrl the image url to show in the preview
* @return a feed instance ready to be written
*/
private static Feed buildPost(
private static Post buildPost(
String description,
String uriParams,
String previewTitle,
@ -230,9 +244,9 @@ public class SocialUtils {
if (uriParams != null && uriParams.compareTo("") != 0)
uri += "?"+uriParams;
Feed toReturn = new Feed(
Post toReturn = new Post(
UUID.randomUUID().toString(),
FeedType.PUBLISH,
PostType.PUBLISH,
applicationProfile.getKey(),
new Date(),
scopeApp,
@ -371,7 +385,7 @@ public class SocialUtils {
* @param notifyGroup
* @return The written Feed
*/
public static Feed shareUserUpdate(
public static Post shareUserUpdate(
String userId,
String postText,
String vreId,
@ -422,12 +436,12 @@ public class SocialUtils {
textToPost = escapedPostText;
}
Feed toShare = new Feed(UUID.randomUUID().toString(), FeedType.PUBLISH, userId, new Date(),
Post toShare = new Post(UUID.randomUUID().toString(), PostType.PUBLISH, userId, new Date(),
vreId, url, urlThumbnail, textToPost, PrivacyLevel.SINGLE_VRE, fullName, email, thumbnailURL, linkTitle, linkDesc, host);
logger.info("Attempting to save Post with text: " + textToPost + " Level = " + PrivacyLevel.SINGLE_VRE + " Timeline = " + vreId);
logger.debug("Attempting to save Post with text: " + textToPost + " Level = " + PrivacyLevel.SINGLE_VRE + " Timeline = " + vreId);
boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserFeed(toShare);
boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserPost(toShare);
if(vreId != null && vreId.compareTo("") != 0 && result) {
@ -436,7 +450,7 @@ public class SocialUtils {
try {
try{
logger.info("Sleeping waiting for cassandra's update");
logger.debug("Sleeping waiting for cassandra's update");
Thread.sleep(1000);
}catch(Exception e){
@ -494,4 +508,218 @@ public class SocialUtils {
}
return toShare;
}
/**
* Allows to comment post in a certain vre.
* @param userid the username
* @param time the date and time of the comment
* @param postId the key of the post that was commented
* @param commentText the text as it is, it will be parsed
* @param postOwnerId the username of the user who created the post that was commented
* @param context the VRE context
*
* @return the Comment instance if ok, null if somwthign went KO
* @throws FeedIDNotFoundException
*/
public static Comment commentPost(String userid, Date time, String postId, String commentText, String postOwnerId, String context) throws FeedIDNotFoundException {
SocialMessageParser messageParser = new SocialMessageParser(commentText);
String escapedCommentText = messageParser.getParsedMessage();
//check if any mention exists
ArrayList<GenericItemBean> mentionedUsers = getUsersFromUsernames(Utils.getMentionedUsernames(commentText));
ArrayList<ItemBean> mentionedUsersToConvertInHTML = convertToItemBean(mentionedUsers);
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
escapedCommentText = Utils.convertMentionUsernamesAnchorHTML(escapedCommentText, mentionedUsersToConvertInHTML, site.getSiteURL(), site.getSiteLandingPagePath());
// retrieve user information
GCubeUser user;
UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager();
try {
user = uManager.getUserByUsername(userid);
} catch(Exception e){
logger.error("Unable to get user informations, comment write fails.", e);
return null;
}
String commentKey = UUID.randomUUID().toString(); // a unique id that goes in the DB
String email = user.getEmail();
String fullName = user.getFirstName() + " " + user.getLastName();
String thumbnailURL = user.getUserAvatarURL();
Comment theComment = new Comment(commentKey, userid, time, postId, escapedCommentText, fullName, thumbnailURL);
logger.debug("Attempting to save Comment with text: " + commentText + " postid="+postId);
boolean result = CassandraConnection.getInstance().getDatabookStore().addComment(theComment);
logger.debug("Added comment? " + theComment.toString() + " Result is " +result);
if (!result)
return null;
//if the comment was correctly delivered notify users involved
SocialNetworkingUser socialUser = new SocialNetworkingUser(userid, email, fullName, thumbnailURL);
NotificationsManager nm = new ApplicationNotificationsManager(uManager, site, context, socialUser, NEWS_FEED_PORTLET_CLASSNAME);
//if the user who commented this post is not the user who posted it notify the poster user (Post owner)
logger.debug("The post creator is " + postOwnerId);
if (! user.getUsername().equals(postOwnerId)) {
boolean resultNotifyOwnComment = nm.notifyOwnCommentReply(postOwnerId, postId, escapedCommentText, theComment.getKey());
logger.debug("Comment Notification to post creator added? " + resultNotifyOwnComment);
}
//if there are users who liked this post they get notified, asynchronously with this thread
ArrayList<Like> likes = getAllLikesByPost(postId);
Thread likesThread = new Thread(new LikeNotificationsThread(escapedCommentText, nm, likes, postOwnerId, theComment.getKey()));
likesThread.start();
//notify the other users who commented this post (excluding the ones above)
Thread commentsNotificationthread = new Thread(new CommentNotificationsThread(
CassandraConnection.getInstance().getDatabookStore(),
uManager, user.getUsername(), theComment.getFeedid(), escapedCommentText, nm, postOwnerId, theComment.getKey(), likes));
commentsNotificationthread.start();
//send the notification to the mentioned users, if any
if (mentionedUsers != null && mentionedUsers.size() > 0) {
ArrayList<GenericItemBean> toPass = new ArrayList<GenericItemBean>();
// among the mentionedUsers there could be groups of people
Map<String, ItemBean> uniqueUsersToNotify = new HashMap<>();
UserManager um = new LiferayUserManager();
for (ItemBean bean : mentionedUsersToConvertInHTML) {
if(bean.isItemGroup()){
// retrieve the users of this group
try {
List<GCubeUser> teamUsers = um.listUsersByTeam(Long.parseLong(bean.getId()));
for (GCubeUser userTeam : teamUsers) {
if(!uniqueUsersToNotify.containsKey(userTeam.getUsername()))
uniqueUsersToNotify.put(userTeam.getUsername(), new ItemBean(userTeam.getUserId()+"",
userTeam.getUsername(), userTeam.getFullname(), userTeam.getUserAvatarURL()));
}
} catch (NumberFormatException
| UserManagementSystemException
| TeamRetrievalFault | UserRetrievalFault e) {
logger.error("Unable to retrieve team information", e);
}
}else{
// it is a user, just add to the hashmap
if(!uniqueUsersToNotify.containsKey(bean.getName()))
uniqueUsersToNotify.put(bean.getName(), bean);
}
}
// iterate over the hashmap
Iterator<Entry<String, ItemBean>> userMapIterator = uniqueUsersToNotify.entrySet().iterator();
while (userMapIterator.hasNext()) {
Map.Entry<String, ItemBean> userEntry = (Map.Entry<String, ItemBean>) userMapIterator
.next();
ItemBean userBean = userEntry.getValue();
toPass.add(new GenericItemBean(userBean.getId(), userBean.getName(), userBean.getAlternativeName(), userBean.getThumbnailURL()));
}
Thread thread = new Thread(new MentionNotificationsThread(theComment.getFeedid(), escapedCommentText, nm, null, toPass));
thread.start();
}
return theComment;
}
private static ArrayList<Like> getAllLikesByPost(String postid) {
ArrayList<Like> toReturn = (ArrayList<Like>) CassandraConnection.getInstance().getDatabookStore().getAllLikesByPost(postid);
logger.debug("Asking likes for " + postid);
for (Like like : toReturn) {
// retrieve user information
GCubeUser user;
UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager();
try {
user = uManager.getUserByUsername(like.getUserid());
} catch(Exception e){
logger.error("Unable to get user informations, comment write fails.", e);
return null;
}
String thumbnailURL = user.getUserAvatarURL();
like.setThumbnailURL(thumbnailURL == null ? "" : thumbnailURL);
}
return toReturn;
}
public static boolean like(String username, String postid, String context) {
boolean likeCommitResult = false;
// retrieve user information
GCubeUser user;
UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager();
try {
user = uManager.getUserByUsername(username);
} catch(Exception e){
logger.error("Unable to get user informations, like write fails.", e);
return false;
}
String email = user.getEmail();
String fullName = user.getFirstName() + " " + user.getLastName();
String thumbnailURL = user.getUserAvatarURL();
SocialNetworkingUser socialUser = new SocialNetworkingUser(user.getUsername(), email, fullName, thumbnailURL);
Like toLike = new Like(UUID.randomUUID().toString(), user.getUsername(),
new Date(), postid, user.getFullname(), user.getUserAvatarURL());
Post thePost = null;
try {
logger.debug("Attempting to read post with id: " +postid);
thePost = CassandraConnection.getInstance().getDatabookStore().readPost(postid);
likeCommitResult = CassandraConnection.getInstance().getDatabookStore().like(toLike);
} catch (Exception e) {
logger.error("Post not found for this like ot could not like the post " + e.getMessage());
return false;
}
//if the like was correctly delivered notify the user who made the post
boolean resultNotifyLike =false;
if (likeCommitResult) {
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, socialUser, NEWS_FEED_PORTLET_CLASSNAME);
String postText = thePost.getDescription();
String postOwnerId = thePost.getEntityId();
SocialMessageParser messageParser = new SocialMessageParser(postText);
String escapedPostText = messageParser.getParsedMessage();
//if the user who liked this post is not the user who posted it notify the poster user (Post owner)
logger.debug("The post creator is " + postOwnerId);
if (! user.getUsername().equals(postOwnerId)) {
resultNotifyLike = nm.notifyLikedPost(postOwnerId, postid, escapedPostText);
logger.debug("Like Notification to post creator added? " + resultNotifyLike);
}
}
return likeCommitResult && resultNotifyLike;
}
public static boolean unlike(String username, String likeid, String postid) {
boolean unlikeCommitResult = false;
// retrieve user information
GCubeUser user;
UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager();
try {
user = uManager.getUserByUsername(username);
} catch(Exception e){
logger.error("Unable to get user informations, unlike write fails.", e);
return false;
}
String fullName = user.getFirstName() + " " + user.getLastName();
String thumbnailURL = user.getUserAvatarURL();
try {
unlikeCommitResult = CassandraConnection.getInstance().getDatabookStore().unlike(username, likeid, postid);
} catch (Exception e) {
logger.error("Post not Found for this like ot could not unlike the post " + e.getMessage());
return false;
}
return unlikeCommitResult;
}
}

View File

@ -2,17 +2,18 @@ package org.gcube.portal.social.networking.ws.utils;
import org.gcube.common.authorization.library.ClientType;
import org.gcube.common.authorization.library.utils.Caller;
import org.slf4j.LoggerFactory;
/**
* Tokens utils methods
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class TokensUtils {
// a user context token (not qualified) has as qualifier the word "TOKEN"
private static final String DEFAULT_QUALIFIER_USER_TOKEN = "TOKEN";
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(TokensUtils.class);
/**
* Check if it is a service token
* @return a boolean value
@ -28,7 +29,10 @@ public class TokensUtils {
* @return a boolean value
*/
public static boolean isApplicationToken(Caller caller){
String username = caller.getClient().getId();
if (username.startsWith("service-account-")) {
return true;
}
return caller.getClient().getType().equals(ClientType.EXTERNALSERVICE);
}
@ -48,7 +52,11 @@ public class TokensUtils {
* @return a boolean value
*/
public static boolean isUserToken(Caller caller) {
logger.debug("\n ****** \n isUserToken: caller.getClient().getType().equals(ClientType.USER) => " + caller.getClient().getType().equals(ClientType.USER));
String username = caller.getClient().getId();
if (username.startsWith("service-account-")) {
return false;
}
return caller.getClient().getType().equals(ClientType.USER);
}
@ -58,9 +66,7 @@ public class TokensUtils {
* @return a boolean value
*/
public static boolean isUserTokenDefault(Caller caller){
return caller.getClient().getType().equals(ClientType.USER);
return isUserToken(caller);
}
/**

View File

@ -6,6 +6,7 @@
padding: 10px;
background: white;
width: 100%;
height: 100px;
}
.navbar-fixed-top {

View File

@ -1,201 +0,0 @@
package org.gcube.portal.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.social.networking.liferay.ws.LiferayJSONWsCredentials;
import org.gcube.portal.social.networking.ws.inputs.MessageInputBean;
import org.gcube.portal.social.networking.ws.inputs.Recipient;
import org.json.simple.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JTests {
private static final String YOUR_TOKEN_HERE = "";
private static final String METHOD = "messages/writeMessageToUsers";
private static final String SCOPE = "/gcube";
//@Test
public void readSocialServiceEndPoint() throws Exception {
String findInContext = SCOPE;
ScopeProvider.instance.set(findInContext);
ServiceEndPointReaderSocial readerSE = new ServiceEndPointReaderSocial(findInContext);
System.out.println("Found base path " + readerSE.getBasePath());
}
//@Test
public void testWithApacheClient() throws Exception {
ServiceEndPointReaderSocial reader = new ServiceEndPointReaderSocial(SCOPE);
String requestForMessage = reader.getBasePath() + METHOD + "?gcube-token=" + YOUR_TOKEN_HERE;
requestForMessage = requestForMessage.replace("http", "https"); // remove the port (or set it to 443) otherwise you get an SSL error
System.out.println("Request url is going to be " + requestForMessage);
try(CloseableHttpClient client = HttpClientBuilder.create().build();){
HttpPost postRequest = new HttpPost(requestForMessage);
// put the sender, the recipients, subject and body of the mail here
StringEntity input = new StringEntity("sender=andrea.rossi&recipients=gianpaolo.coro&subject=Sample mail&body=Sample mail object");
input.setContentType("application/x-www-form-urlencoded");
postRequest.setEntity(input);
HttpResponse response = client.execute(postRequest);
System.out.println("Error is " + response.getStatusLine().getReasonPhrase());
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
System.out.println(response.toString());
}catch(Exception e){
System.err.println("error while performing post method " + e.toString());
}
}
//@Test
public void parserJSON() throws IOException{
MessageInputBean message = new MessageInputBean();
message.setBody("a caso");
message.setSubject("subject");
ArrayList<Recipient> recipients = new ArrayList<Recipient>();
Recipient recipient = new Recipient("recipient1");
recipients.add(recipient);
message.setRecipients(recipients);
//Object mapper instance
ObjectMapper mapper = new ObjectMapper();
//Convert POJO to JSON
String json = mapper.writeValueAsString(message);
MessageInputBean obje = mapper.readValue(json, MessageInputBean.class);
System.out.println(json);
System.out.println(obje);
}
//@Test
public void callLiferayWS() throws Exception{
HttpHost target = new HttpHost("localhost", 8080, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials("test@liferay.com", "random321"));
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider).build();
try {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local
// auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(target, basicAuth);
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
HttpGet httpget = new HttpGet("/api/jsonws" + "/user/get-user-by-screen-name/company-id/20155/screen-name/costantino.perciante");
System.out.println("Executing request " + httpget.getRequestLine() + " to target " + target);
CloseableHttpResponse response = httpclient.execute(target, httpget, localContext);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity()));
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
//@Test
public void retrieveCredentials(){
ScopeProvider.instance.set("/gcube");
LiferayJSONWsCredentials cred = LiferayJSONWsCredentials.getSingleton();
System.out.println("Password is " + cred.getPassword());
System.out.println("Host is " + cred.getHost());
}
//@Test
public void readGcoreEndPoint() throws Exception{
GcoreEndpointReader reader = new GcoreEndpointReader("/gcube");
reader.getResourceEntyName();
}
//@Test
public void sendNotification() throws ClientProtocolException, IOException{
String url ="https://socialnetworking-d-d4s.d4science.org/social-networking-library-ws/rest//2/notifications/notify-job-status?gcube-token=07f5f961-d0e0-4bc4-af90-a305e8b63ac7-98187548";
CloseableHttpClient client = HttpClientBuilder.create().build();
JSONObject obj = new JSONObject();
obj.put("job_id", "bbbbb");
obj.put("recipient", "costantino.perciante");
obj.put("job_name", "aaaaaa");
obj.put("service_name", "Test");
obj.put("status", "SUCCEEDED");
HttpPost request = new HttpPost(url);
request.addHeader("Content-type", ContentType.APPLICATION_JSON.toString());
StringEntity paramsEntity = new StringEntity(obj.toJSONString(), ContentType.APPLICATION_JSON);
request.setEntity(paramsEntity);
client.execute(request);
}
}