Compare commits

..

No commits in common. "master" and "Feature/23439" have entirely different histories.

73 changed files with 2117 additions and 4132 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

34
.classpath Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<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">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

174
.gitignore vendored
View File

@ -1,174 +1,2 @@
# /target/
ignore_me
tomcat
target
.classpath
.visual
.project
.settings
/**/.DS_Store
# Created by https://www.toptal.com/developers/gitignore/api/java,macos,linux,visualstudiocode,eclipse
# Edit at https://www.toptal.com/developers/gitignore?templates=java,macos,linux,visualstudiocode,eclipse
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project
### Eclipse Patch ###
# Spring Boot Tooling
.sts4-cache/
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# End of https://www.toptal.com/developers/gitignore/api/java,macos,linux,visualstudiocode,eclipse

42
.project Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>social-networking-library-ws</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

13
.settings/.jsdtscope Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@ -0,0 +1,16 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
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=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId"/>

View File

@ -0,0 +1,7 @@
<root>
<facet id="jst.jaxrs">
<node name="libprov">
<attribute name="provider-id" value="jaxrs-no-op-library-provider"/>
</node>
</facet>
</root>

View File

@ -0,0 +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"/>
</faceted-project>

View File

@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

View File

@ -0,0 +1 @@
Window

View File

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

View File

@ -1,37 +1,9 @@
# Changelog # Changelog
## [v3.1.0-SNAPSHOT] ## [v2.7.1-SNAPSHOT] - 2022-09-14
- gcube-smartgears-bom to 2.5.1-SNAPSHOT
## [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 #23891 Refactored following updates social lib
- Feature #23847 Social service: temporarily block of notifications for given username(s) - 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 ## [v2.7.0] - 2022-09-12

View File

@ -22,12 +22,10 @@ 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) * **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Costantino Perciante** * **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 ## Maintainers
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante) * **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 ## License

View File

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

223
pom.xml
View File

@ -6,31 +6,28 @@
<parent> <parent>
<groupId>org.gcube.tools</groupId> <groupId>org.gcube.tools</groupId>
<artifactId>maven-parent</artifactId> <artifactId>maven-parent</artifactId>
<version>1.2.0</version> <version>1.1.0</version>
</parent> </parent>
<groupId>org.gcube.portal</groupId> <groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library-ws</artifactId> <artifactId>social-networking-library-ws</artifactId>
<packaging>war</packaging> <packaging>war</packaging>
<version>3.1.0-SNAPSHOT</version> <version>2.7.1-SNAPSHOT</version>
<name>social-networking-library-ws</name> <name>social-networking-library-ws</name>
<description>Rest interface for the social networking library.</description> <description>Rest interface for the social networking library.</description>
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<enunciate.version>2.14.0</enunciate.version> <enunciate.version>2.14.0</enunciate.version>
<cassandra.driver.oss.version>4.13.0</cassandra.driver.oss.version> <jackson.version>2.8.11</jackson.version>
<jackson.version>2.12.6</jackson.version>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory> <webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties> </properties>
<scm> <scm>
<connection> <connection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</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>
<developerConnection>
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url> <url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
</scm> </scm>
@ -39,7 +36,7 @@
<dependency> <dependency>
<groupId>org.gcube.distribution</groupId> <groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId> <artifactId>gcube-smartgears-bom</artifactId>
<version>2.5.1-SNAPSHOT</version> <version>2.1.1</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
@ -75,13 +72,18 @@
<dependency> <dependency>
<groupId>org.gcube.social-networking</groupId> <groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-model</artifactId> <artifactId>social-service-model</artifactId>
<version>[1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version> <version>[1.1.7-SNAPSHOT, 2.0.0)</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.sf.ehcache</groupId> <groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId> <artifactId>ehcache</artifactId>
<version>2.10.0</version> <version>2.10.0</version>
</dependency> </dependency>
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.3</version>
</dependency>
<dependency> <dependency>
<groupId>org.gcube.common</groupId> <groupId>org.gcube.common</groupId>
<artifactId>authorization-control-library</artifactId> <artifactId>authorization-control-library</artifactId>
@ -96,7 +98,6 @@
<dependency> <dependency>
<groupId>org.gcube.common</groupId> <groupId>org.gcube.common</groupId>
<artifactId>storagehub-client-library</artifactId> <artifactId>storagehub-client-library</artifactId>
<!-- <version>2.0.0-SNAPSHOT</version> -->
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sun.mail</groupId> <groupId>com.sun.mail</groupId>
@ -127,6 +128,58 @@
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </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> <dependency>
<groupId>org.gcube.socialnetworking</groupId> <groupId>org.gcube.socialnetworking</groupId>
<artifactId>social-util-library</artifactId> <artifactId>social-util-library</artifactId>
@ -136,7 +189,7 @@
<dependency> <dependency>
<groupId>org.gcube.portal</groupId> <groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library</artifactId> <artifactId>social-networking-library</artifactId>
<version>[2.0.0, 3.0.0)</version> <version>[1.18.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -178,78 +231,26 @@
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version> <version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<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> <artifactId>jackson-dataformat-yaml</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<version>2.8.6</version> <version>2.8.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId> <artifactId>jackson-dataformat-smile</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<version>2.8.6</version> <version>2.8.6</version>
</dependency> </dependency>
<!-- needed by the search-->
<dependency> <dependency>
<groupId>org.codehaus.jackson</groupId> <artifactId>jackson-dataformat-cbor</artifactId>
<artifactId>jackson-mapper-asl</artifactId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<version>1.9.2</version> <version>2.8.6</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> </dependency>
<!-- Please note that the elasticsearch client needs a compress-lzf <!-- Please note that the elasticsearch client needs a compress-lzf version
version
>= 1.0.2 --> >= 1.0.2 -->
<dependency> <dependency>
<groupId>com.ning</groupId> <groupId>com.ning</groupId>
@ -259,8 +260,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.glassfish.jersey.containers</groupId> <groupId>org.glassfish.jersey.containers</groupId>
<!-- if your container implements Servlet API older than 3.0, use <!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
"jersey-container-servlet-core" -->
<artifactId>jersey-container-servlet-core</artifactId> <artifactId>jersey-container-servlet-core</artifactId>
</dependency> </dependency>
<dependency> <dependency>
@ -313,30 +313,47 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.5.3</version> <version>4.3</version>
</dependency> <scope>compile</scope>
<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> </dependency>
</dependencies> </dependencies>
<build> <build>
<pluginManagement>
<plugins> <plugins>
<!-- <plugin> <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<aspectLibraries>
<aspectLibrary>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-control-library</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>kr.motd.maven</groupId> <groupId>kr.motd.maven</groupId>
<artifactId>sphinx-maven-plugin</artifactId> <artifactId>sphinx-maven-plugin</artifactId>
<version>2.10.0</version> <version>2.10.0</version>
<configuration> <configuration>
<outputDirectory> <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
<builder>html</builder> <builder>html</builder>
<configDirectory>${basedir}/docs</configDirectory> <configDirectory>${basedir}/docs</configDirectory>
<sourceDirectory>${basedir}/docs</sourceDirectory> <sourceDirectory>${basedir}/docs</sourceDirectory>
@ -349,7 +366,7 @@
</goals> </goals>
</execution> </execution>
</executions> </executions>
</plugin> --> </plugin>
<!-- Enunciate Maven plugin --> <!-- Enunciate Maven plugin -->
<plugin> <plugin>
<groupId>com.webcohesion.enunciate</groupId> <groupId>com.webcohesion.enunciate</groupId>
@ -358,8 +375,7 @@
<configuration> <configuration>
<sourcepath-includes> <sourcepath-includes>
<sourcepath-include> <sourcepath-include>
<!-- Include the "com.external:external" artifact on <!-- Include the "com.external:external" artifact on the sourcepath. -->
the sourcepath. -->
<groupId>org.gcube.social-networking</groupId> <groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-model</artifactId> <artifactId>social-service-model</artifactId>
</sourcepath-include> </sourcepath-include>
@ -382,8 +398,7 @@
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId> <artifactId>aspectj-maven-plugin</artifactId>
</plugin> </plugin>
<!-- Copy Enunciate Documentation from your-application/docs to <!-- Copy Enunciate Documentation from your-application/docs to your-application.war -->
your-application.war -->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>
@ -399,10 +414,8 @@
<outputDirectory>target</outputDirectory> <outputDirectory>target</outputDirectory>
<resources> <resources>
<resource> <resource>
<targetPath> <targetPath>${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath> <directory>${project.build.directory}/api-docs</directory>
<directory>
${project.build.directory}/api-docs</directory>
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
</resources> </resources>
@ -410,6 +423,24 @@
</execution> </execution>
</executions> </executions>
</plugin> </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> </plugins>
</build> </build>
</project> </project>

View File

@ -5,7 +5,6 @@ import net.sf.ehcache.Ehcache;
/** /**
* Handle caches via Ehcache * Handle caches via Ehcache
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class CachesManager { public class CachesManager {
@ -13,8 +12,7 @@ public class CachesManager {
private static CacheManager cacheManager; private static CacheManager cacheManager;
public static final CachesManager singleton = new CachesManager(); public static final CachesManager singleton = new CachesManager();
// the following caches are declared within the ehcache.xml (no default is // the following caches are declared within the ehcache.xml (no default is available)
// available)
public static final String SOCIAL_NETWORKING_SITES_CACHE = "social_networking_site_cache"; public static final String SOCIAL_NETWORKING_SITES_CACHE = "social_networking_site_cache";
public static final String USERS_CACHE = "users_cache"; public static final String USERS_CACHE = "users_cache";
public static final String GROUPS_CACHE = "groups_cache"; public static final String GROUPS_CACHE = "groups_cache";

View File

@ -12,12 +12,11 @@ public class GroupsCache {
/** /**
* Private constructor: build the cache * Private constructor: build the cache
*
* @return * @return
*/ */
private GroupsCache(){ private GroupsCache(){
logger.debug("Building cache"); logger.info("Building cache");
CachesManager.getCache(CachesManager.GROUPS_CACHE); CachesManager.getCache(CachesManager.GROUPS_CACHE);
} }
@ -31,8 +30,7 @@ public class GroupsCache {
/** /**
* Retrieve an entry * Retrieve an entry
* * @param id
* @param groupId
* @return user associated to the user * @return user associated to the user
*/ */
public GCubeGroup getGroup(long groupId){ public GCubeGroup getGroup(long groupId){
@ -45,9 +43,8 @@ public class GroupsCache {
/** /**
* Save an entry into the cache * Save an entry into the cache
*
* @param id * @param id
* @param group * @param user
*/ */
public void pushEntry(long id, GCubeGroup group){ public void pushEntry(long id, GCubeGroup group){
Ehcache groupsCache = CachesManager.getCache(CachesManager.GROUPS_CACHE); Ehcache groupsCache = CachesManager.getCache(CachesManager.GROUPS_CACHE);

View File

@ -25,12 +25,9 @@ import org.gcube.vomanagement.usermanagement.model.VirtualGroup;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* When a notification needs to be sent, this class offers utility to discover * When a notification needs to be sent, this class offers utility to discover (starting from the scope)
* (starting from the scope) * the site information needed to build up the SocialNetworkingSite object (which, for instance, contains the
* the site information needed to build up the SocialNetworkingSite object
* (which, for instance, contains the
* portal email). * portal email).
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class SocialNetworkingSiteFinder { public class SocialNetworkingSiteFinder {
@ -58,7 +55,7 @@ public class SocialNetworkingSiteFinder {
// read fallback properties // read fallback properties
try{ try{
logger.debug("Trying to read config.properties"); logger.info("Trying to read config.properties");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("config.properties"); InputStream input = classLoader.getResourceAsStream("config.properties");
Properties properties = new Properties(); Properties properties = new Properties();
@ -83,7 +80,6 @@ public class SocialNetworkingSiteFinder {
/** /**
* Retrieve the SocialNetworkingSite given the scope * Retrieve the SocialNetworkingSite given the scope
*
* @param scope * @param scope
* @return * @return
*/ */
@ -94,11 +90,11 @@ public class SocialNetworkingSiteFinder {
if(scope == null || scope.isEmpty()) if(scope == null || scope.isEmpty())
throw new IllegalArgumentException("Scope cannot be null/empty"); throw new IllegalArgumentException("Scope cannot be null/empty");
if (socialSitesCache != null && socialSitesCache.get(scope) != null) if(socialSitesCache.get(scope) != null)
return (SocialNetworkingSite) socialSitesCache.get(scope).getObjectValue(); return (SocialNetworkingSite) socialSitesCache.get(scope).getObjectValue();
else{ else{
SocialNetworkingSite site = discoverSite(scope); SocialNetworkingSite site = discoverSite(scope);
if (socialSitesCache != null && site != null) if(site != null)
socialSitesCache.put(new Element(scope, site)); socialSitesCache.put(new Element(scope, site));
return site; return site;
} }
@ -107,7 +103,6 @@ public class SocialNetworkingSiteFinder {
/** /**
* Discover the site for this scope * Discover the site for this scope
*
* @param scope * @param scope
* @return * @return
*/ */
@ -138,15 +133,14 @@ public class SocialNetworkingSiteFinder {
logger.info("Retrieved Gateways are " + gateways); logger.info("Retrieved Gateways are " + gateways);
// now, retrieve the virtual groups for each gateway and stop when a VG matches // now, retrieve the virtual groups for each gateway and stop when a VG matches with one of the group
// with one of the group
// then, it is the gateway of interest // then, it is the gateway of interest
ext_loop: for (GCubeGroup gateway : gateways) { ext_loop: for (GCubeGroup gateway : gateways) {
List<VirtualGroup> gatewayVirtualGroups = groupManager.getVirtualGroups(gateway.getGroupId()); List<VirtualGroup> gatewayVirtualGroups = groupManager.getVirtualGroups(gateway.getGroupId());
if(gatewayVirtualGroups != null && !gatewayVirtualGroups.isEmpty()){ if(gatewayVirtualGroups != null && !gatewayVirtualGroups.isEmpty()){
for (VirtualGroup gatewayVirtualGroup : gatewayVirtualGroups) { for (VirtualGroup gatewayVirtualGroup : gatewayVirtualGroups) {
if(virtualGroupsOfGroup.contains(gatewayVirtualGroup)){ if(virtualGroupsOfGroup.contains(gatewayVirtualGroup)){
logger.debug("Matching gateway for scope " + scope + " is " + gateway); logger.info("Matching gateway for scope " + scope + " is " + gateway);
matchingGateway = gateway; matchingGateway = gateway;
break ext_loop; break ext_loop;
} }
@ -158,8 +152,7 @@ public class SocialNetworkingSiteFinder {
List<GCubeGroup> gateways = groupManager.getGateways(); List<GCubeGroup> gateways = groupManager.getGateways();
// vo and root vo cases are treated separately: in production environment // vo and root vo cases are treated separately: in production environment services.d4science.org is used, instead
// services.d4science.org is used, instead
// in dev next.d4science.org is used TODO better way... // in dev next.d4science.org is used TODO better way...
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
String rootContext = "/"+ctx.container().configuration().infrastructure(); String rootContext = "/"+ctx.container().configuration().infrastructure();
@ -199,16 +192,11 @@ public class SocialNetworkingSiteFinder {
return null; return null;
}else{ }else{
String siteName = matchingGateway.getGroupName(); String siteName = matchingGateway.getGroupName();
String emailSender = (String) groupManager.readCustomAttr(matchingGateway.getGroupId(), String emailSender = (String)groupManager.readCustomAttr(matchingGateway.getGroupId(), EMAIL_SENDER_SITE_CUSTOM_FIELD);
EMAIL_SENDER_SITE_CUSTOM_FIELD); emailSender = emailSender.replace("\"", ""); //this is because otherwise it would contains double quotes and postfix would use it as first part before @ e.g. senderEmail="aginfra@d4science.org"@d4science.org
emailSender = emailSender.replace("\"", ""); // this is because otherwise it would contains double
// quotes and postfix would use it as first part before
// @ e.g.
// senderEmail="aginfra@d4science.org"@d4science.org
String siteLandingPagePath = GCubePortalConstants.PREFIX_GROUP_URL + matchingGateway.getFriendlyURL(); String siteLandingPagePath = GCubePortalConstants.PREFIX_GROUP_URL + matchingGateway.getFriendlyURL();
String siteUrl = discoverHostOfServiceEndpoint(siteName); String siteUrl = discoverHostOfServiceEndpoint(siteName);
SocialNetworkingSite site = new SocialNetworkingSite(siteName, emailSender, siteUrl, SocialNetworkingSite site = new SocialNetworkingSite(siteName, emailSender, siteUrl, siteLandingPagePath);
siteLandingPagePath);
logger.info("Site is " + site); logger.info("Site is " + site);
return site; return site;
} }
@ -226,7 +214,6 @@ public class SocialNetworkingSiteFinder {
/** /**
* Retrieve endpoint host from IS for this gateway * Retrieve endpoint host from IS for this gateway
*
* @return the host for the gateway * @return the host for the gateway
* @throws Exception * @throws Exception
*/ */

View File

@ -2,6 +2,9 @@ package org.gcube.portal.social.networking.caches;
import java.util.List; import java.util.List;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.smartgears.ContextProvider; import org.gcube.smartgears.ContextProvider;
@ -11,13 +14,8 @@ import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
/** /**
* This cache will store GCubeUser of the users of the infrastructure as couples * This cache will store GCubeUser of the users of the infrastructure as couples {user-id, user screename}
* {user-id, user screename}
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class UsersCache{ public class UsersCache{
@ -27,7 +25,6 @@ public class UsersCache {
/** /**
* Private constructor: build the cache * Private constructor: build the cache
*
* @return * @return
*/ */
private UsersCache(){ private UsersCache(){
@ -36,13 +33,12 @@ public class UsersCache {
new Thread(){ new Thread(){
public void run() { public void run() {
try{ try{
logger.debug("Fetching users and putting them into cache"); logger.info("Fetching users and putting them into cache");
Ehcache usersCache = CachesManager.getCache(CachesManager.USERS_CACHE); Ehcache usersCache = CachesManager.getCache(CachesManager.USERS_CACHE);
GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager(); GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager();
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager(); UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
List<GCubeUser> users = userManager.listUsersByGroup(groupManager List<GCubeUser> users = userManager.listUsersByGroup(groupManager.getGroupIdFromInfrastructureScope("/"+ctx.container().configuration().infrastructure()));
.getGroupIdFromInfrastructureScope("/" + ctx.container().configuration().infrastructure()));
for (GCubeUser gCubeUser : users) { for (GCubeUser gCubeUser : users) {
usersCache.put(new Element(gCubeUser.getUserId(), gCubeUser)); usersCache.put(new Element(gCubeUser.getUserId(), gCubeUser));
} }
@ -63,8 +59,7 @@ public class UsersCache {
/** /**
* Retrieve an entry * Retrieve an entry
* * @param id
* @param userId
* @return user associated to the user * @return user associated to the user
*/ */
public GCubeUser getUser(long userId){ public GCubeUser getUser(long userId){
@ -77,7 +72,6 @@ public class UsersCache {
/** /**
* Save an entry into the cache * Save an entry into the cache
*
* @param id * @param id
* @param user * @param user
*/ */

View File

@ -7,7 +7,6 @@ import org.slf4j.LoggerFactory;
/** /**
* Class that builds a (singleton) GroupManagerWS object. * Class that builds a (singleton) GroupManagerWS object.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class GroupManagerWSBuilder { public class GroupManagerWSBuilder {
@ -18,7 +17,7 @@ public class GroupManagerWSBuilder {
private GroupManagerWSBuilder(){ private GroupManagerWSBuilder(){
logger.debug("Building GroupManager please wait"); logger.info("Building GroupManager please wait");
try{ try{
groupManagerWs = new LiferayWSGroupManager( groupManagerWs = new LiferayWSGroupManager(
@ -32,13 +31,12 @@ public class GroupManagerWSBuilder {
return; return;
} }
logger.debug("GroupManager instance built"); logger.info("GroupManager instance built");
} }
/** /**
* Get the user manager instance * Get the user manager instance
*
* @return * @return
*/ */
public GroupManager getGroupManager(){ public GroupManager getGroupManager(){

View File

@ -1,140 +0,0 @@
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 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.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.List;
import java.util.Map; import java.util.Map;
import org.gcube.common.encryption.encrypter.StringEncrypter; import org.gcube.common.encryption.StringEncrypter;
import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.Property; import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
@ -19,11 +19,12 @@ import org.gcube.smartgears.context.application.ApplicationContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* This is a singleton bean instantiated at service start up. It contains * This is a singleton bean instantiated at service start up. It contains
* the credentials of the user who is allowed to perform calls to Liferay. * the credentials of the user who is allowed to perform calls to Liferay.
* Its credentials are looked up from the infrastructure. * Its credentials are looked up from the infrastructure.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class LiferayJSONWsCredentials { public class LiferayJSONWsCredentials {
@ -40,8 +41,7 @@ public class LiferayJSONWsCredentials {
private String password; private String password;
private int port; private int port;
// The token of the user used to send notifications/messages when an application // The token of the user used to send notifications/messages when an application token is provided. (will be read from web.xml)
// token is provided. (will be read from web.xml)
private String notifierUserToken; private String notifierUserToken;
// Service endpoint properties // Service endpoint properties
@ -52,10 +52,10 @@ public class LiferayJSONWsCredentials {
* Private constructor * Private constructor
*/ */
private LiferayJSONWsCredentials() { private LiferayJSONWsCredentials() {
logger.debug("Building LiferayJSONWsCredentials object"); logger.info("Building LiferayJSONWsCredentials object");
loadNotifierToken(); loadNotifierToken();
lookupPropertiesFromIs(); lookupPropertiesFromIs();
logger.debug("LiferayJSONWsCredentials object built"); logger.info("LiferayJSONWsCredentials object built");
} }
/** /**
@ -75,22 +75,20 @@ public class LiferayJSONWsCredentials {
*/ */
private void lookupPropertiesFromIs() { private void lookupPropertiesFromIs() {
logger.debug("Starting creating LiferayJSONWsCredentials"); logger.info("Starting creating LiferayJSONWsCredentials");
String oldContext = ScopeProvider.instance.get(); String oldContext = ScopeProvider.instance.get();
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
ScopeProvider.instance.set("/"+ctx.container().configuration().infrastructure()); ScopeProvider.instance.set("/"+ctx.container().configuration().infrastructure());
logger.info("Discovering liferay user's credentials in context " logger.info("Discovering liferay user's credentials in context " + ctx.container().configuration().infrastructure());
+ ctx.container().configuration().infrastructure());
try{ try{
List<ServiceEndpoint> resources = getConfigurationFromIS(); List<ServiceEndpoint> resources = getConfigurationFromIS();
if (resources.size() == 0){ if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME + " and Category " logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Category " + CATEGORY + " in this scope.");
+ CATEGORY + " in this scope."); throw new Exception("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 {
} else {
for (ServiceEndpoint res : resources) { for (ServiceEndpoint res : resources) {
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator(); Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
while (accessPointIterator.hasNext()) { while (accessPointIterator.hasNext()) {
@ -103,8 +101,7 @@ public class LiferayJSONWsCredentials {
host = accessPoint.address(); host = accessPoint.address();
schema = (String)properties.get("schema").value(); schema = (String)properties.get("schema").value();
user = StringEncrypter.getEncrypter().decrypt((String)properties.get("username").value()); user = StringEncrypter.getEncrypter().decrypt((String)properties.get("username").value());
password = StringEncrypter.getEncrypter() password = StringEncrypter.getEncrypter().decrypt((String)properties.get("password").value());
.decrypt((String) properties.get("password").value());
port = Integer.valueOf(properties.get("port").value()); port = Integer.valueOf(properties.get("port").value());
// break // break
@ -121,12 +118,11 @@ public class LiferayJSONWsCredentials {
ScopeProvider.instance.set(oldContext); ScopeProvider.instance.set(oldContext);
} }
logger.debug("Bean built " + toString()); logger.info("Bean built " + toString());
} }
/** /**
* Retrieve endpoints information from IS for DB * Retrieve endpoints information from IS for DB
*
* @return list of endpoints for ckan database * @return list of endpoints for ckan database
* @throws Exception * @throws Exception
*/ */

View File

@ -7,7 +7,6 @@ import org.slf4j.LoggerFactory;
/** /**
* Class that builds a (singleton) UserManagerWS object. * Class that builds a (singleton) UserManagerWS object.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class RoleManagerWSBuilder { public class RoleManagerWSBuilder {
@ -18,7 +17,7 @@ public class RoleManagerWSBuilder {
private RoleManagerWSBuilder(){ private RoleManagerWSBuilder(){
logger.debug("Building UserManager please wait"); logger.info("Building UserManager please wait");
try{ try{
roleManagerWs = new LiferayWSRoleManager( roleManagerWs = new LiferayWSRoleManager(
@ -32,13 +31,12 @@ public class RoleManagerWSBuilder {
return; return;
} }
logger.debug("UserManager instance built"); logger.info("UserManager instance built");
} }
/** /**
* Get the role manager instance * Get the role manager instance
*
* @return * @return
*/ */
public RoleManager getRoleManager(){ public RoleManager getRoleManager(){

View File

@ -3,13 +3,14 @@ package org.gcube.portal.social.networking.liferay.ws;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
import org.gcube.portal.social.networking.caches.UsersCache;
/** /**
* Loaded at start up. This class performs some init - to be done once - * Loaded at start up. This class performs some init - to be done once - operations.
* operations.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class ServletContextClass implements ServletContextListener { public class ServletContextClass implements ServletContextListener
{
private static String notifierToken; private static String notifierToken;
@ -18,8 +19,7 @@ public class ServletContextClass implements ServletContextListener {
// get the token and save it // get the token and save it
notifierToken = arg0.getServletContext().getInitParameter("NOTIFIER_TOKEN"); notifierToken = arg0.getServletContext().getInitParameter("NOTIFIER_TOKEN");
// start the thread to retrieve infrastructure users (which is, build up the // start the thread to retrieve infrastructure users (which is, build up the singleton)
// singleton)
//UsersCache.getSingleton(); //UsersCache.getSingleton();
} }
@ -31,7 +31,6 @@ public class ServletContextClass implements ServletContextListener {
/** /**
* Returns the token of the Liferay's User. * Returns the token of the Liferay's User.
*
* @return * @return
*/ */
public static String getNotifierToken() { public static String getNotifierToken() {

View File

@ -7,7 +7,6 @@ import org.slf4j.LoggerFactory;
/** /**
* Class that builds a (singleton) UserManagerWS object. * Class that builds a (singleton) UserManagerWS object.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class UserManagerWSBuilder { public class UserManagerWSBuilder {
@ -18,7 +17,7 @@ public class UserManagerWSBuilder {
private UserManagerWSBuilder(){ private UserManagerWSBuilder(){
logger.debug("Building UserManager please wait"); logger.info("Building UserManager please wait");
try{ try{
userManagerWs = new LiferayWSUserManager( userManagerWs = new LiferayWSUserManager(
@ -32,13 +31,12 @@ public class UserManagerWSBuilder {
return; return;
} }
logger.debug("UserManager instance built"); logger.info("UserManager instance built");
} }
/** /**
* Get the user manager instance * Get the user manager instance
*
* @return * @return
*/ */
public UserManager getUserManager(){ public UserManager getUserManager(){

View File

@ -14,7 +14,6 @@ public class WelcomeService {
@GET @GET
@Produces(MediaType.TEXT_HTML) @Produces(MediaType.TEXT_HTML)
public Response sayHtmlHello() { public Response sayHtmlHello() {
return Response.ok("<html><body><h2>The social networking web service is up and running!</h2></body></html>") return Response.ok("<html><body><h2>The social networking web service is up and running!</h2></body></html>").build();
.build();
} }
} }

View File

@ -35,6 +35,7 @@ public class DocsGenerator {
pathInfo += "index.html"; pathInfo += "index.html";
} }
logger.info("going to {}", pathInfo); logger.info("going to {}", pathInfo);
String realPath = req.getServletContext().getRealPath(pathInfo); String realPath = req.getServletContext().getRealPath(pathInfo);

View File

@ -8,8 +8,9 @@ import javax.ws.rs.ext.Provider;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* Exception gets thrown when @Valid fail * Exception thrown when @Valid fail
*/ */
@Provider @Provider
public class ApplicationException implements ExceptionMapper<Exception> { public class ApplicationException implements ExceptionMapper<Exception> {

View File

@ -12,14 +12,12 @@ import org.slf4j.LoggerFactory;
/** /**
* Exception thrown on fail * Exception thrown on fail
*
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
*/ */
@Provider @Provider
public class ValidationException implements ExceptionMapper<javax.validation.ValidationException> { public class ValidationException implements ExceptionMapper<javax.validation.ValidationException> {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ValidationException.class); private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ValidationException.class);
@Override @Override
public Response toResponse(javax.validation.ValidationException e) { public Response toResponse(javax.validation.ValidationException e) {
final StringBuilder strBuilder = new StringBuilder(); final StringBuilder strBuilder = new StringBuilder();

View File

@ -5,13 +5,12 @@ import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
/** /**
* Application id object * Application id object
*
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
*/ */
// @ApiModel(description="An object containing the app_id field", //@ApiModel(description="An object containing the app_id field", value="Application")
// value="Application")
public class ApplicationId { public class ApplicationId {
@JsonProperty("app_id") @JsonProperty("app_id")

View File

@ -1,71 +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;
/**
* 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

@ -1,58 +0,0 @@
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

@ -0,0 +1,84 @@
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

@ -1,41 +0,0 @@
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

@ -8,10 +8,8 @@ import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.webcohesion.enunciate.metadata.DocumentationExample; import com.webcohesion.enunciate.metadata.DocumentationExample;
/** /**
* Generic input bean for methods that allow to write posts * Generic input bean for methods that allow to write posts
*
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization @JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization
@ -46,8 +44,7 @@ public class PostInputBean implements Serializable {
private String httpimageurl; private String httpimageurl;
/** /**
* enablenotification If true send a notification to the other vre members about * enablenotification If true send a notification to the other vre members about this post
* this post
*/ */
@JsonProperty("enable_notification") @JsonProperty("enable_notification")
private boolean enablenotification; private boolean enablenotification;

View File

@ -0,0 +1,49 @@
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

@ -5,6 +5,7 @@ import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
/** /**
* *
* *
@ -24,6 +25,7 @@ public class UserSetNotificationBean {
super(); super();
} }
/** /**
* @param username * @param username
* @param disableNotification * @param disableNotification
@ -34,6 +36,7 @@ public class UserSetNotificationBean {
this.disableNotification = disableNotification; this.disableNotification = disableNotification;
} }
public String getUsername() { public String getUsername() {
return username; return username;
} }
@ -50,9 +53,11 @@ public class UserSetNotificationBean {
this.disableNotification = disableNotification; this.disableNotification = disableNotification;
} }
@Override @Override
public String toString() { public String toString() {
return "UserSetNotificationBean [username=" + username + ", disableNotification=" + disableNotification + "]"; return "UserSetNotificationBean [username=" + username + ", disableNotification=" + disableNotification + "]";
} }
} }

View File

@ -60,4 +60,5 @@ public class JobMapper {
return toReturn; return toReturn;
} }
} }

View File

@ -0,0 +1,53 @@
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

@ -0,0 +1,40 @@
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,15 +1,11 @@
package org.gcube.portal.social.networking.ws.methods.v2; package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.Date;
import java.util.List; import java.util.List;
import javax.validation.Valid;
import javax.validation.ValidationException; import javax.validation.ValidationException;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
@ -21,13 +17,10 @@ import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.social.networking.ws.inputs.CommentInputBean;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean; 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.CassandraConnection;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages; 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.Filters;
import org.gcube.portal.social.networking.ws.utils.SocialUtils;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader; import com.webcohesion.enunciate.metadata.rs.RequestHeader;
@ -37,8 +30,6 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/** /**
* REST interface for the social networking library (comments). * REST interface for the social networking library (comments).
*
* @author Ahmed Ibrahim ISTI-CNR
*/ */
@Path("2/comments") @Path("2/comments")
@RequestHeaders ({ @RequestHeaders ({
@ -50,58 +41,6 @@ public class Comments {
// Logger // Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Comments.class); 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 @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-user") @Path("get-comments-user")
@ -109,6 +48,9 @@ public class Comments {
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"), @ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @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() { public Response getCommentsUser() {
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
@ -119,7 +61,7 @@ public class Comments {
List<Comment> comments = null; List<Comment> comments = null;
try{ try{
logger.debug("Retrieving comments for user id " + username); logger.info("Retrieving comments for user id " + username);
comments = CassandraConnection.getInstance().getDatabookStore().getRecentCommentsByUserAndDate(username, 0); comments = CassandraConnection.getInstance().getDatabookStore().getRecentCommentsByUserAndDate(username, 0);
Filters.filterCommentsPerContext(comments, context); Filters.filterCommentsPerContext(comments, context);
responseBean.setResult(comments); responseBean.setResult(comments);
@ -134,16 +76,17 @@ public class Comments {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-user-by-time") @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( public Response getCommentsUserByTime(
@QueryParam("time") @Min(value = 0, message = "time cannot be negative") long timeInMillis) @QueryParam("time")
throws ValidationException { @Min(value = 0, message="time cannot be negative")
long timeInMillis
) throws ValidationException{
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
@ -153,9 +96,8 @@ public class Comments {
List<Comment> comments = null; List<Comment> comments = null;
try{ try{
logger.debug("Retrieving comments for user id " + username); logger.info("Retrieving comments for user id " + username);
comments = CassandraConnection.getInstance().getDatabookStore().getRecentCommentsByUserAndDate(username, comments = CassandraConnection.getInstance().getDatabookStore().getRecentCommentsByUserAndDate(username, timeInMillis);
timeInMillis);
Filters.filterCommentsPerContext(comments, context); Filters.filterCommentsPerContext(comments, context);
responseBean.setResult(comments); responseBean.setResult(comments);
responseBean.setMessage(""); responseBean.setMessage("");
@ -169,65 +111,4 @@ public class Comments {
return Response.status(status).entity(responseBean).build(); 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

@ -60,15 +60,11 @@ public class FullTextSearch {
/** /**
* Retrieve posts/comments that match the given query * Retrieve posts/comments that match the given query
*
* @param httpServletRequest * @param httpServletRequest
* @param query A string to search for * @param query A string to search for
* @param from the index of the base result to be returned, * @param from the index of the base result to be returned, range[0, infinity], defaults from = 0
* range[0, infinity], defaults from = 0 * @param quantity defines how many results are most are to be returned, range[1, infinity], defaults from = 0,
* @param quantity defines how many results are most are to be * @return The posts/comments returned belong to the context bound to the AUTH Token
* returned, range[1, infinity], defaults from = 0,
* @return The posts/comments returned belong to the context bound to the AUTH
* Token
* @throws ValidationException * @throws ValidationException
*/ */
@GET @GET
@ -80,10 +76,13 @@ public class FullTextSearch {
}) })
public Response searchByQuery( public Response searchByQuery(
@Context HttpServletRequest httpServletRequest, @Context HttpServletRequest httpServletRequest,
@QueryParam("query") @NotNull(message = "query cannot be null") @Size(min = 1, message = "query cannot be empty") String query, @QueryParam("query") @NotNull(message="query cannot be null") @Size(min=1, message="query cannot be empty")
@DefaultValue("0") @QueryParam("from") @Min(value = 0, message = "from cannot be negative") int from, String query,
@DefaultValue("10") @QueryParam("quantity") @Min(value = 0, message = "quantity cannot be negative") int quantity) @DefaultValue("0") @QueryParam("from") @Min(value=0, message="from cannot be negative")
throws ValidationException { int from,
@DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity cannot be negative")
int quantity
) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();
@ -116,20 +115,20 @@ public class FullTextSearch {
vres.add(groupManager.getInfrastructureScope(group.getGroupId())); vres.add(groupManager.getInfrastructureScope(group.getGroupId()));
} }
} }
} else if (groupManager.isVO(currentGroupId)) { }
else if(groupManager.isVO(currentGroupId)){
for (GCubeGroup group : groupManager.listGroupsByUser(currUser.getUserId())) { for (GCubeGroup group : groupManager.listGroupsByUser(currUser.getUserId())) {
if (groupManager.isVRE(group.getGroupId()) && group.getParentGroupId() == currentGroupId if (groupManager.isVRE(group.getGroupId()) && group.getParentGroupId() == currentGroupId && userContexts.contains(group)) {
&& userContexts.contains(group)) {
vres.add(groupManager.getInfrastructureScope(group.getGroupId())); vres.add(groupManager.getInfrastructureScope(group.getGroupId()));
} }
} }
} else { }
else {
vres.add(context); vres.add(context);
} }
// query elastic search // query elastic search
List<EnhancedFeed> enhancedFeeds = ElasticSearchConnection.getSingleton().getElasticSearchClient() List<EnhancedFeed> enhancedFeeds = ElasticSearchConnection.getSingleton().getElasticSearchClient().search(query, vres, from, quantity);
.search(query, vres, from, quantity);
Filters.hideSensitiveInformation(enhancedFeeds, caller.getClient().getId()); Filters.hideSensitiveInformation(enhancedFeeds, caller.getClient().getId());
DatabookStore store = CassandraConnection.getInstance().getDatabookStore(); DatabookStore store = CassandraConnection.getInstance().getDatabookStore();
@ -157,7 +156,6 @@ public class FullTextSearch {
/** /**
* tell if a feed belongs to the current user or not * tell if a feed belongs to the current user or not
*
* @param tocheck * @param tocheck
* @param username * @param username
* @return true if this feed is of the current user * @return true if this feed is of the current user

View File

@ -26,8 +26,6 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/** /**
* REST interface for the social networking library (hash tags). * REST interface for the social networking library (hash tags).
*
* @author Ahmed Ibrahim ISTI-CNR
*/ */
@Path("2/hashtags") @Path("2/hashtags")
@RequestHeaders ({ @RequestHeaders ({
@ -57,13 +55,12 @@ public class HashTags {
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
logger.debug("User " + username + " has requested hashtags of context " + context); logger.info("User " + username + " has requested hashtags of context " + context);
try{ try{
DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore(); DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore();
// TODO handle the case of VO and ROOT // TODO handle the case of VO and ROOT
boolean isVRE = GroupManagerWSBuilder.getInstance().getGroupManager().isVRE( boolean isVRE = GroupManagerWSBuilder.getInstance().getGroupManager().isVRE(GroupManagerWSBuilder.getInstance().getGroupManager().getGroupIdFromInfrastructureScope(context));
GroupManagerWSBuilder.getInstance().getGroupManager().getGroupIdFromInfrastructureScope(context));
if(isVRE){ if(isVRE){
Map<String, Integer> map = datastore.getVREHashtagsWithOccurrence(context); Map<String, Integer> map = datastore.getVREHashtagsWithOccurrence(context);
responseBean.setResult(map); responseBean.setResult(map);
@ -79,4 +76,5 @@ public class HashTags {
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
} }

View File

@ -1,171 +0,0 @@
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,7 +9,6 @@ import javax.validation.Valid;
import javax.validation.ValidationException; import javax.validation.ValidationException;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
@ -35,11 +34,11 @@ import org.gcube.portal.notifications.thread.MessageNotificationsThread;
import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder; 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.LiferayJSONWsCredentials;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; 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.outputs.ResponseBean; 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.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.TokensUtils; 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.UserManager;
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException;
import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault;
@ -53,7 +52,6 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/** /**
* Messages services REST interface * Messages services REST interface
*
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it) * (costantino.perciante@isti.cnr.it)
*/ */
@ -69,9 +67,7 @@ public class Messages {
/** /**
* Write a message to another user. The sender is the token's owner by default * Write a message to another user. The sender is the token's owner by default
* * @responseExample application/json {"success": true, "message": null, "result": "556142e3-d6f5-4550-b2fa-abe5626625d3"}
* @responseExample application/json {"success": true, "message": null,
* "result": "556142e3-d6f5-4550-b2fa-abe5626625d3"}
* @param input The message to write" * @param input The message to write"
* @param httpServletRequest * @param httpServletRequest
* @return see response example * @return see response example
@ -88,9 +84,10 @@ public class Messages {
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
}) })
public Response writeMessage( public Response writeMessage(
@NotNull(message = "Message to send is missing") @Valid MessageInputBean input, @NotNull(message="Message to send is missing")
@Context HttpServletRequest httpServletRequest) @Valid
throws ValidationException, UserManagementSystemException, UserRetrievalFault { MessageInputBean input,
@Context HttpServletRequest httpServletRequest) throws ValidationException, UserManagementSystemException, UserRetrievalFault{
logger.debug("Incoming message bean is " + input); logger.debug("Incoming message bean is " + input);
@ -98,27 +95,22 @@ public class Messages {
UserManager um = UserManagerWSBuilder.getInstance().getUserManager(); UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser senderUser = null; GCubeUser senderUser = null;
SocialNetworkingUser user = null; SocialNetworkingUser user = null;
// check if the token belongs to an application token. In this case use // 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)
// J.A.R.V.I.S (the username used to communicate with Liferay)
String username = null; String username = null;
String fullName = ""; String fullName = "";
logger.debug("Catalogue Notification called by " + caller.getClient().getId() + " isUser?" logger.debug("Catalogue Notification called by " + caller.getClient().getId() + " isUser?"+TokensUtils.isUserToken(caller));
+ TokensUtils.isUserToken(caller));
if(!TokensUtils.isUserToken(caller)){ if(!TokensUtils.isUserToken(caller)){
GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager() GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
.getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken()); SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername(); username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username); senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
senderUser.getUserAvatarURL());
}else{ }else{
username = caller.getClient().getId(); username = caller.getClient().getId();
senderUser = um.getUserByUsername(username); senderUser = um.getUserByUsername(username);
fullName = senderUser.getFullname(); fullName = senderUser.getFullname();
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
senderUser.getUserAvatarURL());
} }
String scope = ScopeProvider.instance.get(); String scope = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
@ -126,7 +118,7 @@ public class Messages {
String body = input.getBody(); String body = input.getBody();
String subject = input.getSubject(); String subject = input.getSubject();
List<Recipient> recipientsIds = input.getRecipients(); // "recipients":[{"recipient":"id recipient"}, ......] List<Recipient> recipientsIds = input.getRecipients(); // "recipients":[{"recipient":"id recipient"}, ......]
logger.debug("Sender is going to be [" + fullName + "]"); logger.info("Sender is going to be [" + fullName + "]");
// get the recipients ids (simple check, trim) // get the recipients ids (simple check, trim)
List<String> recipientsListFiltered = new ArrayList<String>(); List<String> recipientsListFiltered = new ArrayList<String>();
@ -140,8 +132,7 @@ public class Messages {
if(userRecipient == null) if(userRecipient == null)
userRecipient = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(tempId); userRecipient = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(tempId);
if(userRecipient != null){ if(userRecipient != null){
GenericItemBean beanUser = new GenericItemBean(userRecipient.getUsername(), GenericItemBean beanUser = new GenericItemBean(userRecipient.getUsername(), userRecipient.getUsername(), userRecipient.getFullname(), userRecipient.getUserAvatarURL());
userRecipient.getUsername(), userRecipient.getFullname(), userRecipient.getUserAvatarURL());
recipientsBeans.add(beanUser); recipientsBeans.add(beanUser);
recipientsListFiltered.add(userRecipient.getUsername()); recipientsListFiltered.add(userRecipient.getUsername());
} }
@ -159,19 +150,17 @@ public class Messages {
try{ try{
logger.debug("Trying to send message with body " + body + " subject " + subject + " to users " logger.debug("Trying to send message with body " + body + " subject " + subject + " to users " + recipientsIds + " from " + username);
+ recipientsIds + " from " + username);
// send message // send message
MessageManagerClient client = AbstractPlugin.messages().build(); MessageManagerClient client = AbstractPlugin.messages().build();
logger.debug("Sending message to " + recipientsListFiltered); logger.debug("Sending message to " + recipientsListFiltered);
String messageId = client.sendMessage(recipientsListFiltered, subject, body, input.getAttachmentIds()); String messageId = client.sendMessage(recipientsListFiltered, subject, body, null);
// send notification // send notification
logger.debug("Message sent to " + recipientsIds + ". Sending message notification to: " + recipientsIds); logger.debug("Message sent to " + recipientsIds + ". Sending message notification to: " + recipientsIds);
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(scope); SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(scope);
NotificationsManager nm = new ApplicationNotificationsManager( NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, ScopeProvider.instance.get(), user);
UserManagerWSBuilder.getInstance().getUserManager(), site, ScopeProvider.instance.get(), user);
new Thread(new MessageNotificationsThread(recipientsBeans, messageId, subject, body, nm)).start(); new Thread(new MessageNotificationsThread(recipientsBeans, messageId, subject, body, nm)).start();
responseBean.setSuccess(true); responseBean.setSuccess(true);
responseBean.setResult(messageId); responseBean.setResult(messageId);
@ -202,7 +191,7 @@ public class Messages {
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
logger.debug("Request for retrieving sent messages by " + username); logger.info("Request for retrieving sent messages by " + username);
try{ try{
MessageManagerClient client = AbstractPlugin.messages().build(); MessageManagerClient client = AbstractPlugin.messages().build();
@ -238,7 +227,7 @@ public class Messages {
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
logger.debug("Request for retrieving received messages by " + username); logger.info("Request for retrieving received messages by " + username);
try{ try{
MessageManagerClient client = AbstractPlugin.messages().build(); MessageManagerClient client = AbstractPlugin.messages().build();
List<Message> getMessages =client.getReceivedMessages(); List<Message> getMessages =client.getReceivedMessages();
@ -254,48 +243,4 @@ public class Messages {
return Response.status(status).entity(responseBean).build(); 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,14 +1,20 @@
package org.gcube.portal.social.networking.ws.methods.v2; package org.gcube.portal.social.networking.ws.methods.v2;
import java.io.IOException; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.ValidationException; import javax.validation.ValidationException;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue; import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
@ -22,6 +28,7 @@ import javax.ws.rs.core.Response.Status;
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
import org.gcube.applicationsupportlayer.social.NotificationsManager; 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.SocialNetworkingSite;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser;
import org.gcube.common.authorization.control.annotations.AuthorizationControl; import org.gcube.common.authorization.control.annotations.AuthorizationControl;
@ -31,6 +38,7 @@ import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.portal.databook.shared.Notification; import org.gcube.portal.databook.shared.Notification;
import org.gcube.portal.databook.shared.NotificationType;
import org.gcube.portal.databook.shared.RunningJob; import org.gcube.portal.databook.shared.RunningJob;
import org.gcube.portal.notifications.bean.GenericItemBean; import org.gcube.portal.notifications.bean.GenericItemBean;
import org.gcube.portal.notifications.thread.JobStatusNotificationThread; import org.gcube.portal.notifications.thread.JobStatusNotificationThread;
@ -40,15 +48,20 @@ 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.LiferayJSONWsCredentials;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; 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.ex.AuthException;
import org.gcube.portal.social.networking.ws.inputs.UserSetNotificationBean;
import org.gcube.portal.social.networking.ws.mappers.CatalogueEventTypeMapper; 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.JobMapper;
import org.gcube.portal.social.networking.ws.mappers.WorkspaceItemMapper; 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.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection; import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
import org.gcube.portal.social.networking.ws.utils.DistributedCacheClient;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.portal.social.networking.ws.utils.SocialUtils;
import org.gcube.portal.social.networking.ws.utils.TokensUtils; 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.JobNotificationBean;
import org.gcube.social_networking.socialnetworking.model.beans.catalogue.CatalogueEvent; 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.AddedItemEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.DeletedItemEvent; import org.gcube.social_networking.socialnetworking.model.beans.workspace.DeletedItemEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.FolderAddedUserEvent; import org.gcube.social_networking.socialnetworking.model.beans.workspace.FolderAddedUserEvent;
@ -59,24 +72,26 @@ 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.SharedFolderEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.UnsharedFolderEvent; 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.UpdatedItemEvent;
import org.gcube.social_networking.socialnetworking.model.beans.workspace.WorkspaceEvent;
import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.UserManager; 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.UserManagementSystemException;
import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault;
import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.mortbay.log.Log; import org.mortbay.log.Log;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.webcohesion.enunciate.metadata.rs.RequestHeader; import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders; import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.internal.OperationFuture;
/** /**
* REST interface for the social networking library (notifications). * REST interface for the social networking library (notifications).
*
* @author Ahmed Ibrahim ISTI-CNR
*/ */
@Path("2/notifications") @Path("2/notifications")
@RequestHeaders ({ @RequestHeaders ({
@ -89,25 +104,27 @@ public class Notifications {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Notifications.class); private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Notifications.class);
private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager"; private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager";
@GET
@Path("get-range-notifications/")
@Produces(MediaType.APPLICATION_JSON)
/** /**
* Retrieve notifications of the token's owner * Retrieve notifications of the gcube-token's owner
*
* @param from must be greater or equal to 1, range[0, infinity] * @param from must be greater or equal to 1, range[0, infinity]
* @param quantity quantity must be greater or equal to 0 * @param quantity quantity must be greater or equal to 0
* @return notifications up to quantity * @return notifications up to quantity
* @throws ValidationException * @throws ValidationException
*/ */
@GET
@Path("get-range-notifications/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({ @StatusCodes ({
@ResponseCode ( code = 200, condition = "Notifications retrieved and reported in the 'result' field of the returned object"), @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) @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
}) })
public Response getRangeNotifications( public Response getRangeNotifications(
@DefaultValue("1") @QueryParam("from") @Min(value = 1, message = "from must be greater or equal to 1") int from, @DefaultValue("1") @QueryParam("from") @Min(value=1, message="from must be greater or equal to 1")
@DefaultValue("10") @QueryParam("quantity") @Min(value = 0, message = "quantity must be greater or equal to 0") int quantity) int from,
throws ValidationException { @DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity must be greater or equal to 0")
int quantity
) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();
@ -119,8 +136,7 @@ public class Notifications {
List<Notification> notifications = null; List<Notification> notifications = null;
try{ try{
notifications = CassandraConnection.getInstance().getDatabookStore().getRangeNotificationsByUser(username, notifications = CassandraConnection.getInstance().getDatabookStore().getRangeNotificationsByUser(username, from, quantity);
from, quantity);
responseBean.setResult(notifications); responseBean.setResult(notifications);
responseBean.setSuccess(true); responseBean.setSuccess(true);
logger.debug("List of notifications retrieved"); logger.debug("List of notifications retrieved");
@ -134,20 +150,19 @@ public class Notifications {
return Response.status(status).entity(responseBean).build(); 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 * @pathExample /is-user-disabled?username=john.smith
* @responseExample application/json { "success": true, "message": null * @responseExample application/json { "success": true, "message": null "result": true }
* "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 @GET
@Path("is-user-disabled/") @Path("is-user-disabled/")
/**
* Return whether the notifications for this user are enabled or not
* @param username the username you want to check
* @return true if the notification for the user are disabled (Catalogue and Workspace ones)
*
*/
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({ @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 = 200, condition = "true if the notification for the username given as query param are disabled (Catalogue and Workspace ones), false otherwise"),
@ -155,8 +170,8 @@ public class Notifications {
}) })
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class) @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class)
public Response isUserDisabled( public Response isUserDisabled(
@QueryParam("username") @NotNull(message = "username cannot be null") String username) @QueryParam("username") @NotNull(message="username cannot be null")
throws ValidationException { String username) throws ValidationException{
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
try{ try{
@ -174,111 +189,94 @@ public class Notifications {
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
// /** /**
// * Set user notification enabled or disabled * Set user notification enabled or disabled
// * @param disable true if you want to disable the notifications for this user, * @param disable true if you want to disable the notifications for this user, false if you want to enable them
// false if you want to enable them * @return the result of the operation
// * @return the result of the operation * @throws ValidationException
// * @throws ValidationException */
// */ @POST
// @POST @Path("set-user-notifications/")
// @Path("set-user-notifications/") @Consumes(MediaType.APPLICATION_JSON)
// @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
// @Produces(MediaType.APPLICATION_JSON) @StatusCodes ({
// @StatusCodes ({ @ResponseCode ( code = 200, condition = "Notification set Off or On correctly executed"),
// @ResponseCode ( code = 200, condition = "Notification set Off or On correctly @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
// executed"), })
// @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class)
// }) public Response setUserNotifications(
// @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, @NotNull(message="input is missing")
// exception=AuthException.class) @Valid
// public Response setUserNotifications( UserSetNotificationBean setting) throws ValidationException{
// @NotNull(message="input is missing")
// @Valid Caller caller = AuthorizationProvider.instance.get();
// UserSetNotificationBean setting) throws ValidationException{ String context = ScopeProvider.instance.get();
// ResponseBean responseBean = new ResponseBean();
// Caller caller = AuthorizationProvider.instance.get(); Status status = Status.OK;
// 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);
// try{ String toReturn = "Could not set notifications";
// String opExecutor = caller.getClient().getId(); if (result) {
// Boolean result = setUserNotificationsOnOff(setting.getUsername(), toReturn = "Notifications have been set";
// setting.isDisableNotification(), opExecutor); toReturn += setting.isDisableNotification() ? " OFF (for 29 days unless re-enabled manually) ": " ON ";
// String toReturn = "Could not set notifications"; toReturn += "for username=" + setting.getUsername();
// if (result) { }
// toReturn = "Notifications have been set"; responseBean.setSuccess(true);
// toReturn += setting.isDisableNotification() ? " OFF (for 29 days unless responseBean.setResult(toReturn);
// re-enabled manually) ": " ON ";
// toReturn += "for username=" + setting.getUsername(); } catch(Exception e){
// } logger.error("Unable to set user notification", e);
// responseBean.setSuccess(true); responseBean.setSuccess(false);
// responseBean.setResult(toReturn); responseBean.setMessage(e.getMessage());
// status = Status.INTERNAL_SERVER_ERROR;
// } catch(Exception e){ }
// logger.error("Unable to set user notification", e);
// responseBean.setSuccess(false);
// responseBean.setMessage(e.getMessage()); return Response.status(status).entity(responseBean).build();
// status = Status.INTERNAL_SERVER_ERROR; }
// }
//
//
// return Response.status(status).entity(responseBean).build();
// }
/** /**
* @deprecated *
* @param usernameToCheck * @param usernameToCheck
* @return true if notification are enabled for this user * @return true if notification are enabled for this user
* @throws IOException
*/ */
private boolean isNotificationEnabled(String usernameToCheck) throws IOException { private boolean isNotificationEnabled(String usernameToCheck) {
// MemcachedClient entries = new DistributedCacheClient().getMemcachedClient(); MemcachedClient entries = new DistributedCacheClient().getMemcachedClient();
// String key = String key = SocialUtils.DISABLED_USERS_NOTIFICATIONS_NAMESPACE+usernameToCheck;
// SocialUtils.DISABLED_USERS_NOTIFICATIONS_NAMESPACE+usernameToCheck; Boolean userEnabled = false;
// Boolean userEnabled = false; if(entries.get(key) == null)
// if(entries.get(key) == null) userEnabled = true;
// userEnabled = true; return userEnabled;
// 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
*/
private Boolean setUserNotificationsOnOff(String username, boolean disable, String callerId) {
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 {
return result.getStatus().isSuccess();
} catch (Exception e) {
e.printStackTrace();
}
return null;
} }
// /**
// *
// * @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 * Send a JOB notification to a given recipient
*
* @param job The job bean * @param job The job bean
* @return * @return
* @throws ValidationException * @throws ValidationException
@ -292,7 +290,9 @@ public class Notifications {
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
}) })
public Response notifyJobStatus( public Response notifyJobStatus(
@NotNull(message = "input is missing") @Valid JobNotificationBean job) throws ValidationException { @NotNull(message="input is missing")
@Valid
JobNotificationBean job) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get(); String context = ScopeProvider.instance.get();
@ -300,23 +300,19 @@ public class Notifications {
Status status = Status.OK; Status status = Status.OK;
String appQualifier = caller.getClient().getId(); String appQualifier = caller.getClient().getId();
logger.debug("Received request from app " + appQualifier + " to notify job status described by bean " + job); logger.info("Received request from app " + appQualifier + " to notify job status described by bean " + job);
try{ try{
String recipient = job.getRecipient(); String recipient = job.getRecipient();
GCubeUser userRecipient = UserManagerWSBuilder.getInstance().getUserManager().getUserByUsername(recipient); GCubeUser userRecipient = UserManagerWSBuilder.getInstance().getUserManager().getUserByUsername(recipient);
GenericItemBean recipientBean = new GenericItemBean(userRecipient.getUsername(), GenericItemBean recipientBean = new GenericItemBean(userRecipient.getUsername(), userRecipient.getUsername(), userRecipient.getFullname(), userRecipient.getUserAvatarURL());
userRecipient.getUsername(), userRecipient.getFullname(), userRecipient.getUserAvatarURL());
// notifications are sent by using the user allowed to use liferay's json apis // notifications are sent by using the user allowed to use liferay's json apis
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context); SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
GCubeUser senderUser = UserManagerWSBuilder.getInstance().getUserManager() GCubeUser senderUser = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
.getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser()); SocialNetworkingUser user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
SocialNetworkingUser user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
senderUser.getFullname(), senderUser.getUserAvatarURL());
NotificationsManager nm = new ApplicationNotificationsManager(
UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
RunningJob theJob = JobMapper.getJob(job); RunningJob theJob = JobMapper.getJob(job);
@ -331,12 +327,12 @@ public class Notifications {
status = Status.INTERNAL_SERVER_ERROR; status = Status.INTERNAL_SERVER_ERROR;
} }
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
/** /**
* Send a Catalogue notification to a given user * Send a Catalogue notification to a given user
*
* @param event * @param event
* @return * @return
* @throws ValidationException * @throws ValidationException
@ -350,33 +346,29 @@ public class Notifications {
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
}) })
public Response catalogue( public Response catalogue(
@NotNull(message = "input is missing") @Valid CatalogueEvent event) @NotNull(message="input is missing")
throws ValidationException, UserManagementSystemException, UserRetrievalFault { @Valid
CatalogueEvent event) throws ValidationException, UserManagementSystemException, UserRetrievalFault{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
UserManager um = UserManagerWSBuilder.getInstance().getUserManager(); UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser senderUser = null; GCubeUser senderUser = null;
SocialNetworkingUser user = null; SocialNetworkingUser user = null;
// check if the token belongs to an application token. In this case use // 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)
// J.A.R.V.I.S (the username used to communicate with Liferay)
String username = null; String username = null;
String fullName = ""; String fullName = "";
logger.debug("Catalogue Notification called by " + caller.getClient().getId() + " isUser?" logger.debug("Catalogue Notification called by " + caller.getClient().getId() + " isUser?"+TokensUtils.isUserToken(caller));
+ TokensUtils.isUserToken(caller));
if(!TokensUtils.isUserToken(caller)){ if(!TokensUtils.isUserToken(caller)){
GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager() GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
.getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken()); SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername(); username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username); senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
senderUser.getUserAvatarURL());
}else{ }else{
username = caller.getClient().getId(); username = caller.getClient().getId();
senderUser = um.getUserByUsername(username); senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
senderUser.getUserAvatarURL());
} }
String context = ScopeProvider.instance.get(); String context = ScopeProvider.instance.get();
@ -386,14 +378,11 @@ public class Notifications {
Status status = Status.OK; Status status = Status.OK;
boolean deliveryResult = false; boolean deliveryResult = false;
try { try {
// logger.debug("catalogue notifications type is " + event.getType()); logger.debug("catalogue notifications type is " + event.getType());
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context); SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
// 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); NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
String[] idsToNotify = event.getIdsToNotify(); String[] idsToNotify = event.getIdsToNotify();
if (! event.idsAsGroup()) { if (! event.idsAsGroup()) {
@ -403,26 +392,24 @@ public class Notifications {
String username2Notify = null; String username2Notify = null;
try { try {
username2Notify = um.getUserByUsername(userIdToNotify).getUsername(); username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
} catch (Exception e) { }
catch (Exception e) {
status = Status.BAD_REQUEST; status = Status.BAD_REQUEST;
logger.error("Username not found", e); logger.error("Username not found", e);
responseBean.setSuccess(false); responseBean.setSuccess(false);
responseBean.setMessage("Username not found, got: " + userIdToNotify); responseBean.setMessage("Username not found, got: " + userIdToNotify);
return Response.status(status).entity(responseBean).build(); 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( deliveryResult =
nm.notifyCatalogueEvent(
CatalogueEventTypeMapper.getType(event.getType()), CatalogueEventTypeMapper.getType(event.getType()),
username2Notify, username2Notify,
event.getItemId(), event.getItemId(),
event.getNotifyText(), event.getNotifyText(),
event.getItemURL()); event.getItemURL());
} else { }
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify"); Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
} }
@ -439,25 +426,24 @@ public class Notifications {
responseBean.setMessage("Not a VRE Context, only VREs are supported"); responseBean.setMessage("Not a VRE Context, only VREs are supported");
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} else { // it is a context and it is a valid VRE } else { // it is a context and it is a valid VRE
String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); // resolve String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); //resolve the members
// the
// members
for (int j = 0; j < userIdsToNotify.length; j++) { for (int j = 0; j < userIdsToNotify.length; j++) {
String userIdToNotify = userIdsToNotify[j]; String userIdToNotify = userIdsToNotify[j];
if (isNotificationEnabled(userIdToNotify)) { if (isNotificationEnabled(userIdToNotify)) {
deliveryResult = nm.notifyCatalogueEvent( deliveryResult =
nm.notifyCatalogueEvent(
CatalogueEventTypeMapper.getType(event.getType()), CatalogueEventTypeMapper.getType(event.getType()),
userIdToNotify, userIdToNotify,
event.getItemId(), event.getItemId(),
event.getNotifyText(), event.getNotifyText(),
event.getItemURL()); event.getItemURL());
} else { } else {
Log.info("Notification disabled (admin) for user " + userIdToNotify Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
+ " will not notify");
} }
} }
} }
} catch (IllegalArgumentException e) { }
catch(IllegalArgumentException e) {
status = Status.BAD_REQUEST; status = Status.BAD_REQUEST;
logger.error("Context not valid", e); logger.error("Context not valid", e);
responseBean.setSuccess(false); responseBean.setSuccess(false);
@ -479,8 +465,7 @@ public class Notifications {
responseBean.setResult(new Boolean(true)); responseBean.setResult(new Boolean(true));
} else { } else {
responseBean.setSuccess(false); responseBean.setSuccess(false);
responseBean.setMessage( responseBean.setMessage("An error occurred between this service and Cassandra DB, notification not delivered correctly");
"An error occurred between this service and Cassandra DB, notification not delivered correctly");
responseBean.setResult(new Boolean(false)); responseBean.setResult(new Boolean(false));
} }
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
@ -488,7 +473,6 @@ public class Notifications {
/** /**
* Send a Workspace notification to a given user * Send a Workspace notification to a given user
*
* @param event * @param event
* @return * @return
* @throws ValidationException * @throws ValidationException
@ -502,7 +486,9 @@ public class Notifications {
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
}) })
public Response workspace( public Response workspace(
@NotNull(message = "input is missing") @Valid WorkspaceEvent event) throws ValidationException { @NotNull(message="input is missing")
@Valid
WorkspaceEvent event) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get(); String context = ScopeProvider.instance.get();
@ -519,26 +505,20 @@ public class Notifications {
logger.debug("workspace notifications type is " + event.getType()); logger.debug("workspace notifications type is " + event.getType());
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context); SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
UserManager um = UserManagerWSBuilder.getInstance().getUserManager(); UserManager um = UserManagerWSBuilder.getInstance().getUserManager();
logger.debug("Workspace Notification called by " + caller.getClient().getId() + " isUser?" logger.debug("Workspace Notification called by " + caller.getClient().getId() + " isUser?"+TokensUtils.isUserToken(caller));
+ TokensUtils.isUserToken(caller));
if(!TokensUtils.isUserToken(caller)){ if(!TokensUtils.isUserToken(caller)){
GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager() GCubeUser jarvis = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
.getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken()); SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername(); username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
// Client
senderUser = um.getUserByUsername(username); senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
senderUser.getUserAvatarURL());
}else{ }else{
username = caller.getClient().getId(); username = caller.getClient().getId();
senderUser = um.getUserByUsername(username); senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
senderUser.getFullname(), senderUser.getUserAvatarURL());
} }
NotificationsManager nm = new ApplicationNotificationsManager( NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
String[] idsToNotify = event.getIdsToNotify(); String[] idsToNotify = event.getIdsToNotify();
if (! event.idsAsGroup()) { if (! event.idsAsGroup()) {
@ -548,7 +528,8 @@ public class Notifications {
String username2Notify = ""; String username2Notify = "";
try { try {
username2Notify = um.getUserByUsername(userIdToNotify).getUsername(); username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
} catch (Exception e) { }
catch (Exception e) {
status = Status.NOT_ACCEPTABLE; status = Status.NOT_ACCEPTABLE;
logger.error("Username not found", e); logger.error("Username not found", e);
responseBean.setSuccess(false); responseBean.setSuccess(false);
@ -556,7 +537,8 @@ public class Notifications {
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
deliveryResult = notifyWorkspaceEvent(event, nm, username2Notify); deliveryResult = notifyWorkspaceEvent(event, nm, username2Notify);
} else { }
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify"); Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
} }
} }
@ -572,20 +554,18 @@ public class Notifications {
responseBean.setMessage("Not a VRE Context, only VREs are supported"); responseBean.setMessage("Not a VRE Context, only VREs are supported");
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} else { // it is a context and it is a valid VRE } else { // it is a context and it is a valid VRE
String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); // resolve String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); //resolve the members
// the
// members
for (int j = 0; j < userIdsToNotify.length; j++) { for (int j = 0; j < userIdsToNotify.length; j++) {
String userIdToNotify = userIdsToNotify[j]; String userIdToNotify = userIdsToNotify[j];
if (isNotificationEnabled(userIdToNotify)) if (isNotificationEnabled(userIdToNotify))
deliveryResult = notifyWorkspaceEvent(event, nm, userIdToNotify); deliveryResult = notifyWorkspaceEvent(event, nm, userIdToNotify);
else { else {
Log.info("Notification disabled (admin) for user " + userIdToNotify Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
+ " will not notify");
} }
} }
} }
} catch (IllegalArgumentException e) { }
catch(IllegalArgumentException e) {
status = Status.BAD_REQUEST; status = Status.BAD_REQUEST;
logger.error("Context not valid", e); logger.error("Context not valid", e);
responseBean.setSuccess(false); responseBean.setSuccess(false);
@ -607,13 +587,11 @@ public class Notifications {
responseBean.setResult(new Boolean(true)); responseBean.setResult(new Boolean(true));
} else { } else {
responseBean.setSuccess(false); responseBean.setSuccess(false);
responseBean.setMessage( responseBean.setMessage("An error occurred between this service and Cassandra DB, notification not delivered correctly");
"An error occurred between this service and Cassandra DB, notification not delivered correctly");
responseBean.setResult(new Boolean(false)); responseBean.setResult(new Boolean(false));
} }
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
/** /**
* *
* @param event * @param event
@ -626,55 +604,44 @@ public class Notifications {
switch (event.getType()) { switch (event.getType()) {
case ITEM_NEW: { case ITEM_NEW: {
AddedItemEvent itemBean = (AddedItemEvent) event; AddedItemEvent itemBean = (AddedItemEvent) event;
return nm.notifyAddedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), return nm.notifyAddedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
} }
case ITEM_UPDATE: { case ITEM_UPDATE: {
UpdatedItemEvent itemBean = (UpdatedItemEvent) event; UpdatedItemEvent itemBean = (UpdatedItemEvent) event;
return nm.notifyUpdatedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), return nm.notifyUpdatedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
} }
case ITEM_DELETE: { case ITEM_DELETE: {
DeletedItemEvent itemBean = (DeletedItemEvent) event; DeletedItemEvent itemBean = (DeletedItemEvent) event;
return nm.notifyRemovedItem(idToNotify, itemBean.getItemName(), return nm.notifyRemovedItem(idToNotify, itemBean.getItemName(), WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
} }
case FOLDER_SHARE: { case FOLDER_SHARE: {
SharedFolderEvent itemBean = (SharedFolderEvent) event; SharedFolderEvent itemBean = (SharedFolderEvent) event;
return nm.notifyFolderSharing(idToNotify, return nm.notifyFolderSharing(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
} }
case FOLDER_UNSHARE: { case FOLDER_UNSHARE: {
UnsharedFolderEvent itemBean = (UnsharedFolderEvent) event; UnsharedFolderEvent itemBean = (UnsharedFolderEvent) event;
return nm.notifyFolderUnsharing(idToNotify, itemBean.getUnsharedFolderId(), return nm.notifyFolderUnsharing(idToNotify, itemBean.getUnsharedFolderId(), itemBean.getUnsharedFolderName());
itemBean.getUnsharedFolderName());
} }
case FOLDER_RENAME: { case FOLDER_RENAME: {
RenamedFolderEvent itemBean = (RenamedFolderEvent) event; RenamedFolderEvent itemBean = (RenamedFolderEvent) event;
return nm.notifyFolderRenaming(idToNotify, itemBean.getPreviousName(), itemBean.getNewName(), return nm.notifyFolderRenaming(idToNotify, itemBean.getPreviousName(), itemBean.getNewName(), itemBean.getRenamedFolderId());
itemBean.getRenamedFolderId());
} }
case FOLDER_ADMIN_UPGRADE: { case FOLDER_ADMIN_UPGRADE: {
FolderAdminUpgradeEvent itemBean = (FolderAdminUpgradeEvent) event; FolderAdminUpgradeEvent itemBean = (FolderAdminUpgradeEvent) event;
return nm.notifyAdministratorUpgrade(idToNotify, return nm.notifyAdministratorUpgrade(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
} }
case FOLDER_ADMIN_DOWNGRADE: { case FOLDER_ADMIN_DOWNGRADE: {
FolderAdminDowngradeEvent itemBean = (FolderAdminDowngradeEvent) event; FolderAdminDowngradeEvent itemBean = (FolderAdminDowngradeEvent) event;
return nm.notifyAdministratorDowngrade(idToNotify, return nm.notifyAdministratorDowngrade(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
} }
case FOLDER_ADDEDUSER: { case FOLDER_ADDEDUSER: {
FolderAddedUserEvent itemBean = (FolderAddedUserEvent) event; FolderAddedUserEvent itemBean = (FolderAddedUserEvent) event;
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager(); UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
return nm.notifyFolderAddedUsers(idToNotify, return nm.notifyFolderAddedUsers(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()), itemBean.getNewAddedUserIds(), userManager);
WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()), itemBean.getNewAddedUserIds(),
userManager);
} }
case FOLDER_REMOVEDUSER: { case FOLDER_REMOVEDUSER: {
FolderRemovedUserEvent itemBean = (FolderRemovedUserEvent) event; FolderRemovedUserEvent itemBean = (FolderRemovedUserEvent) event;
return nm.notifyFolderRemovedUser(idToNotify, return nm.notifyFolderRemovedUser(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
} }
default: default:
break; break;
@ -685,7 +652,6 @@ public class Notifications {
} }
return false; return false;
} }
/** /**
* *
* @param context * @param context
@ -716,4 +682,5 @@ public class Notifications {
} }
return usernames; return usernames;
} }
} }

View File

@ -33,6 +33,7 @@ import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/** /**
* REST interface for the social service (people). Used by OAUTH 2.0 apps/users. * REST interface for the social service (people). Used by OAUTH 2.0 apps/users.
*/ */
@ -45,21 +46,17 @@ public class People {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(People.class); 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 @GET
@Path("profile") @Path("profile")
@StatusCodes ({ @StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of user's profile, reported in the 'result' field of the returned object"), @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) @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(){ public Response getProfile(){
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -86,8 +83,7 @@ public class People {
toReturn.put("avatar", user.getUserAvatarURL()); toReturn.put("avatar", user.getUserAvatarURL());
toReturn.put("fullname", user.getFullname()); toReturn.put("fullname", user.getFullname());
toReturn.put("context", scope); toReturn.put("context", scope);
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(user.getUserId(), List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(user.getUserId(), groupManager.getGroupIdFromInfrastructureScope(scope));
groupManager.getGroupIdFromInfrastructureScope(scope));
List<String> rolesNames = new ArrayList<String>(); List<String> rolesNames = new ArrayList<String>();
for (GCubeRole gCubeRole : roles) { for (GCubeRole gCubeRole : roles) {
rolesNames.add(gCubeRole.getRoleName()); rolesNames.add(gCubeRole.getRoleName());

View File

@ -1,5 +1,6 @@
package org.gcube.portal.social.networking.ws.methods.v2; package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -23,14 +24,8 @@ import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.server.DatabookStore; import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.ApplicationProfile; import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Attachment; import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.Post; import org.gcube.portal.databook.shared.Post;
import org.gcube.portal.databook.shared.PostWithAttachment;
import org.gcube.portal.databook.shared.RangePosts;
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.inputs.PostInputBean;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean; 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.CassandraConnection;
@ -46,8 +41,6 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/** /**
* REST interface for the social networking library (posts). * REST interface for the social networking library (posts).
*
* @author Ahmed Ibrahim ISTI-CNR
*/ */
@Path("2/posts") @Path("2/posts")
@RequestHeaders ({ @RequestHeaders ({
@ -59,13 +52,6 @@ public class Posts {
// Logger // Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Posts.class); 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 @GET
@Path("get-posts-user-since/") @Path("get-posts-user-since/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -73,9 +59,16 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"), @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) @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( public Response getRecentPostsByUserAndDate(
@QueryParam("time") @Min(value = 0, message = "time cannot be negative") long timeInMillis) @QueryParam("time") @Min(value = 0, message="time cannot be negative")
throws ValidationException { long timeInMillis
) throws ValidationException{
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
@ -85,9 +78,8 @@ public class Posts {
List<Post> posts = null; List<Post> posts = null;
try{ try{
logger.debug("Retrieving post for user id " + username + " and reference time " + timeInMillis); logger.info("Retrieving post for user id " + username + " and reference time " + timeInMillis);
posts = CassandraConnection.getInstance().getDatabookStore().getRecentPostsByUserAndDate(username, posts = CassandraConnection.getInstance().getDatabookStore().getRecentPostsByUserAndDate(username, timeInMillis);
timeInMillis);
Filters.filterPostsPerContext(posts, context); Filters.filterPostsPerContext(posts, context);
Filters.hideSensitiveInformation(posts, caller.getClient().getId()); Filters.hideSensitiveInformation(posts, caller.getClient().getId());
responseBean.setResult(posts); responseBean.setResult(posts);
@ -104,12 +96,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-posts-user/") @Path("get-posts-user/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -117,6 +103,10 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"), @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) @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() { public Response getAllPostsByUser() {
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -143,64 +133,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-posts-user-quantity/") @Path("get-posts-user-quantity/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -208,9 +140,17 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"), @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) @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( public Response getQuantityPostsByUser(
@DefaultValue("10") @QueryParam("quantity") @Min(value = 0, message = "quantity cannot be negative") int quantity) @DefaultValue("10")
throws ValidationException { @QueryParam("quantity")
@Min(value=0, message="quantity cannot be negative")
int quantity) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();
@ -230,8 +170,7 @@ public class Posts {
posts = CassandraConnection.getInstance().getDatabookStore().getAllPostsByUser(username); posts = CassandraConnection.getInstance().getDatabookStore().getAllPostsByUser(username);
if (posts != null) if (posts != null)
logger.debug("got " + posts.size() + " posts"); logger.debug("got " + posts.size() + " posts");
logger.debug( logger.debug("Retrieving last " + quantity + " posts made by user " + username + " in context = "+context);
"Retrieving last " + quantity + " posts made by user " + username + " in context = " + context);
Filters.filterPostsPerContext(posts, context); Filters.filterPostsPerContext(posts, context);
quantity = (quantity > posts.size()) ? posts.size() : quantity; quantity = (quantity > posts.size()) ? posts.size() : quantity;
posts = posts.subList(0, quantity); posts = posts.subList(0, quantity);
@ -247,13 +186,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @POST
@Path("write-post-user") @Path("write-post-user")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -262,8 +194,16 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"), @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) @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( public Response writePostUser(
@NotNull(message = "Post to write is missing") @Valid PostInputBean post) throws ValidationException { @NotNull(message="Post to write is missing")
@Valid
PostInputBean post) throws ValidationException{
logger.debug("Request of writing a feed coming from user " + post); logger.debug("Request of writing a feed coming from user " + post);
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -283,13 +223,14 @@ public class Posts {
// convert enablenotification parameter // convert enablenotification parameter
if(enableNotification) if(enableNotification)
logger.debug("Enable notification for this user post."); logger.info("Enable notification for this user post.");
else else
logger.debug("Disable notification for this user post."); logger.info("Disable notification for this user post.");
// try to share // try to share
logger.debug("Trying to share user post..."); logger.debug("Trying to share user post...");
Post res = SocialUtils.shareUserUpdate( Feed res = SocialUtils.shareUserUpdate(
username, username,
postText, postText,
context, context,
@ -298,7 +239,8 @@ public class Posts {
previewHost, previewHost,
previewUrl, previewUrl,
httpImageUrl, httpImageUrl,
enableNotification); enableNotification
);
if(res != null){ if(res != null){
logger.debug("Post correctly written by user " + username); logger.debug("Post correctly written by user " + username);
@ -316,12 +258,6 @@ 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 @GET
@Path("get-posts-app/") @Path("get-posts-app/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -330,6 +266,10 @@ public class Posts {
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"), @ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @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() { public Response getAllPostsByApp() {
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -369,14 +309,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @POST
@Path("write-post-app") @Path("write-post-app")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -386,8 +318,15 @@ public class Posts {
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"), @ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @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( public Response writePostApp(
@NotNull(message = "Post to write is null") @Valid PostInputBean post) { @NotNull(message="Post to write is null")
@Valid
PostInputBean post){
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String appId = caller.getClient().getId(); String appId = caller.getClient().getId();
@ -422,8 +361,8 @@ public class Posts {
else else
logger.debug("Disable notification for this application post."); logger.debug("Disable notification for this application post.");
// write post + notification if it is the case // write feed + notification if it is the case
Post written = SocialUtils.shareApplicationUpdate( Feed written = SocialUtils.shareApplicationUpdate(
postText, postText,
params, params,
previewTitle, previewTitle,
@ -431,7 +370,8 @@ public class Posts {
httpImageUrl, httpImageUrl,
appProfile, appProfile,
caller, caller,
enableNotification); enableNotification
);
if(written != null){ if(written != null){
responseBean.setResult(written); responseBean.setResult(written);
@ -446,10 +386,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
/**
*
* @return all the posts in the context bound to the auth token
*/
@GET @GET
@Path("get-posts-vre/") @Path("get-posts-vre/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -457,6 +393,10 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"), @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) @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
}) })
/**
*
* @return all the posts in the context bound to the auth token
*/
public Response getAllPostsByVRE() { public Response getAllPostsByVRE() {
String context = ScopeProvider.instance.get(); String context = ScopeProvider.instance.get();
@ -479,64 +419,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-posts-by-hashtag/") @Path("get-posts-by-hashtag/")
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
@ -544,17 +426,23 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"), @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) @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( public Response getPostsByHashTags(
@QueryParam("hashtag") @NotNull(message = "hashtag cannot be missing") String hashtag) @QueryParam("hashtag")
throws ValidationException { @NotNull(message="hashtag cannot be missing")
String hashtag) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();
String context = ScopeProvider.instance.get(); String context = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
logger.debug( logger.info("User " + username + " has requested posts containing hashtag " + hashtag + " in context " + context);
"User " + username + " has requested posts containing hashtag " + hashtag + " in context " + context);
try{ try{
DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore(); DatabookStore datastore = CassandraConnection.getInstance().getDatabookStore();
List<Post> posts = datastore.getVREPostsByHashtag(context, hashtag); List<Post> posts = datastore.getVREPostsByHashtag(context, hashtag);
@ -569,12 +457,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-id-liked-posts/") @Path("get-id-liked-posts/")
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
@ -582,6 +464,10 @@ public class Posts {
@ResponseCode ( code = 201, condition = "Sccessfull retrieved ids, they are reported in the 'result' field of the returned object"), @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) @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() { public Response getAllLikedPostIdsByUser() {
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -610,14 +496,6 @@ public class Posts {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-liked-posts/") @Path("get-liked-posts/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -625,9 +503,17 @@ public class Posts {
@ResponseCode ( code = 200, condition = "Successfull retrieved posts, they are reported in the 'result' field of the returned object"), @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) @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( public Response getAllLikedPostsByUser(
@DefaultValue("10") @QueryParam("limit") @Min(message = "limit cannot be negative", value = 0) int limit) @DefaultValue("10")
throws ValidationException { @QueryParam("limit")
@Min(message="limit cannot be negative", value = 0)
int limit) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();
@ -637,10 +523,8 @@ public class Posts {
Status status = Status.OK; Status status = Status.OK;
try{ try{
logger.debug( logger.debug("Retrieving " + limit + " liked posts for user with id " + username + " in context " + context);
"Retrieving " + limit + " liked posts for user with id " + username + " in context " + context); retrievedLikedPosts = CassandraConnection.getInstance().getDatabookStore().getAllLikedPostsByUser(username, limit);
retrievedLikedPosts = CassandraConnection.getInstance().getDatabookStore().getAllLikedPostsByUser(username,
limit);
Filters.filterPostsPerContext(retrievedLikedPosts, context); Filters.filterPostsPerContext(retrievedLikedPosts, context);
Filters.hideSensitiveInformation(retrievedLikedPosts, caller.getClient().getId()); Filters.hideSensitiveInformation(retrievedLikedPosts, caller.getClient().getId());
responseBean.setResult(retrievedLikedPosts); responseBean.setResult(retrievedLikedPosts);
@ -654,59 +538,4 @@ public class Posts {
} }
return Response.status(status).entity(responseBean).build(); 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

@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/** /**
* REST interface for the social networking library (tokens). * REST interface for the social networking library (tokens).
*/ */
@ -45,13 +46,14 @@ public class Tokens {
}) })
/** /**
* Generate a legacy application auth token for the application with id app_id * Generate a legacy application auth token for the application with id app_id
*
* @param input The bean containing the app_id field * @param input The bean containing the app_id field
* @return the legacy application token * @return the legacy application token
* @throws ValidationException * @throws ValidationException
*/ */
public Response generateApplicationToken( public Response generateApplicationToken(
@NotNull(message = "Missing input parameter") @Valid ApplicationId input) throws ValidationException { @NotNull(message="Missing input parameter")
@Valid
ApplicationId input) throws ValidationException{
logger.debug("Incoming request for app token generation."); logger.debug("Incoming request for app token generation.");
String context = ScopeProvider.instance.get(); String context = ScopeProvider.instance.get();
@ -68,7 +70,7 @@ public class Tokens {
status = Status.FORBIDDEN; status = Status.FORBIDDEN;
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
logger.debug("Generating token for the application with id " + appId); logger.info("Generating token for the application with id " + appId);
// each token is related to an identifier and the context // each token is related to an identifier and the context
String appToken = authorizationService().generateExternalServiceToken(appId); String appToken = authorizationService().generateExternalServiceToken(appId);
responseBean.setSuccess(true); responseBean.setSuccess(true);

View File

@ -24,7 +24,6 @@ import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.portal.social.networking.caches.UsersCache; 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.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.RoleManagerWSBuilder;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
@ -36,11 +35,6 @@ import org.gcube.vomanagement.usermanagement.RoleManager;
import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeRole; import org.gcube.vomanagement.usermanagement.model.GCubeRole;
import org.gcube.vomanagement.usermanagement.model.GCubeUser; 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 org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader; import com.webcohesion.enunciate.metadata.rs.RequestHeader;
@ -61,16 +55,8 @@ public class Users {
// Logger // Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Users.class); private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Users.class);
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 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", private static final List<String> GLOBAL_ROLES_ALLOWED_BY_LOCAL_CALL_METHOD = Arrays.asList("DataMiner-Manager","Quota-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 @GET
@Path("get-custom-attribute/") @Path("get-custom-attribute/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -79,9 +65,17 @@ public class Users {
@ResponseCode ( code = 404, condition = "Such an attribute doesn't exist"), @ResponseCode ( code = 404, condition = "Such an attribute doesn't exist"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) @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( public Response readCustomAttr(
@QueryParam("attribute") @NotNull(message = "attribute name is missing") String attributeKey) @QueryParam("attribute")
throws ValidationException { @NotNull(message="attribute name is missing")
String attributeKey
) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();
@ -112,11 +106,7 @@ public class Users {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-fullname") @Path("get-fullname")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -124,6 +114,10 @@ public class Users {
@ResponseCode ( code = 200, condition = "The user's fullname is reported in the 'result' field of the returned object"), @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) @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(){ public Response getUserFullname(){
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -142,7 +136,7 @@ public class Users {
GCubeUser user = userManager.getUserByUsername(username); GCubeUser user = userManager.getUserByUsername(username);
fullName = user.getFullname(); fullName = user.getFullname();
logger.debug("Found fullname " + fullName + " for user " + username); logger.info("Found fullname " + fullName + " for user " + username);
responseBean.setResult(fullName); responseBean.setResult(fullName);
responseBean.setSuccess(true); responseBean.setSuccess(true);
@ -156,11 +150,6 @@ public class Users {
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("get-email") @Path("get-email")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -168,6 +157,10 @@ public class Users {
@ResponseCode ( code = 200, condition = "The user's email is reported in the 'result' field of the returned object"), @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) @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(){ public Response getUserEmail(){
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
@ -184,7 +177,7 @@ public class Users {
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager(); UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
GCubeUser user = userManager.getUserByUsername(username); GCubeUser user = userManager.getUserByUsername(username);
email = user.getEmail(); email = user.getEmail();
logger.debug("Found email " + email + " for user " + username); logger.info("Found email " + email + " for user " + username);
responseBean.setResult(email); responseBean.setResult(email);
responseBean.setSuccess(true); responseBean.setSuccess(true);
@ -200,17 +193,7 @@ public class Users {
/** /**
* Get the profile associated to the token * Get the profile associated to the token
* * @responseExample application/json { "success" : true, "message" : null, "result" : { "user_id" : 23769487, "username" : "john.smith", "email" : "********", "first_name" : "John", "middle_name" : "", "last_name" : "Smith", "fullname" : "John Smith", "registration_date" : 1475151491415, "user_avatar_url" : "https://******D", "male" : true, "job_title" : "", "location_industry" : "no", "custom_attrs_map" : null, "email_addresses" : [ ], "screen_name" : "john.smith", "user_avatar_id" : "https://****sY%3D" } }
* @responseExample application/json { "success" : true, "message" : null,
* "result" : { "user_id" : 23769487, "username" :
* "john.smith", "email" : "********", "first_name" : "John",
* "middle_name" : "", "last_name" : "Smith", "fullname" :
* "John Smith", "registration_date" : 1475151491415,
* "user_avatar_url" : "https://******D", "male" : true,
* "job_title" : "", "location_industry" : "no",
* "custom_attrs_map" : null, "email_addresses" : [ ],
* "screen_name" : "john.smith", "user_avatar_id" :
* "https://****sY%3D" } }
* @return the user's profile. The user is the one owning the token * @return the user's profile. The user is the one owning the token
*/ */
@GET @GET
@ -247,7 +230,8 @@ public class Users {
return Response.status(status).entity(responseBean).build(); return Response.status(status).entity(responseBean).build();
} }
private static final Function<GCubeUser, UserProfileExtendedWithVerifiedEmail> GCUBE_TO_EXTENDED_PROFILE_MAP_WITH_VERIFIED_EMAIL = new Function<GCubeUser, UserProfileExtendedWithVerifiedEmail>() { private static final Function<GCubeUser, UserProfileExtendedWithVerifiedEmail> GCUBE_TO_EXTENDED_PROFILE_MAP_WITH_VERIFIED_EMAIL
= new Function<GCubeUser, UserProfileExtendedWithVerifiedEmail>() {
@Override @Override
public UserProfileExtendedWithVerifiedEmail apply(GCubeUser t) { public UserProfileExtendedWithVerifiedEmail apply(GCubeUser t) {
@ -255,8 +239,7 @@ public class Users {
if(t == null) if(t == null)
return null; return null;
UserProfileExtendedWithVerifiedEmail profile = new UserProfileExtendedWithVerifiedEmail(t.getUsername(), UserProfileExtendedWithVerifiedEmail profile = new UserProfileExtendedWithVerifiedEmail(t.getUsername(), null, t.getUserAvatarURL(), t.getFullname());
null, t.getUserAvatarURL(), t.getFullname());
profile.setEmail(t.getEmail()); profile.setEmail(t.getEmail());
profile.setFirstName(t.getFirstName()); profile.setFirstName(t.getFirstName());
profile.setJobTitle(t.getJobTitle()); profile.setJobTitle(t.getJobTitle());
@ -271,19 +254,19 @@ public class Users {
/** /**
* @responseExample application/json { * @responseExample application/json {
* "id": "john.smith", "id": "john.smith",
* "roles": [], "roles": [],
* "picture": "https://***gAJ4uVWTA74xwQ6%2FCA72RRinysY%3D", "picture": "https://***gAJ4uVWTA74xwQ6%2FCA72RRinysY%3D",
* "name": "John Smith", "name": "John Smith",
* "middle_name": "", "middle_name": "",
* "male": true, "male": true,
* "location_industry": "no", "location_industry": "no",
* "given_name": "John", "given_name": "John",
* "email": "******", "email": "******",
* "job_title": "", "job_title": "",
* "family_name": "Smith", "family_name": "Smith",
* "verified_email": true "verified_email": true
* } }
* @return the user's profile compliant with oauth * @return the user's profile compliant with oauth
*/ */
@GET @GET
@ -308,8 +291,7 @@ public class Users {
GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager(); GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager();
user = userManager.getUserByUsername(username); user = userManager.getUserByUsername(username);
userWithEmailVerified = GCUBE_TO_EXTENDED_PROFILE_MAP_WITH_VERIFIED_EMAIL.apply(user); userWithEmailVerified = GCUBE_TO_EXTENDED_PROFILE_MAP_WITH_VERIFIED_EMAIL.apply(user);
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(user.getUserId(), List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(user.getUserId(), groupManager.getGroupIdFromInfrastructureScope(scope));
groupManager.getGroupIdFromInfrastructureScope(scope));
List<String> rolesNames = new ArrayList<String>(); List<String> rolesNames = new ArrayList<String>();
for (GCubeRole gCubeRole : roles) { for (GCubeRole gCubeRole : roles) {
rolesNames.add(gCubeRole.getRoleName()); rolesNames.add(gCubeRole.getRoleName());
@ -330,16 +312,15 @@ public class Users {
/** /**
* @responseExample application/json { * @responseExample application/json {
* "success": true, "success": true,
* "message": null, "message": null,
* "result": [ "result": [
* "john.smith", "john.smith",
* "marco.polo" "marco.polo"
* ] ]
* } }
* Get the list of usernames belonging to a given context * Get the list of usernames belonging to a given context
* @return the list of usernames for the user belonging to the context linked to * @return the list of usernames for the user belonging to the context linked to the provided auth token
* the provided auth token
*/ */
@GET @GET
@Path("get-all-usernames") @Path("get-all-usernames")
@ -389,11 +370,8 @@ public class Users {
} }
/** /**
* Get the map of couples username/fullname of the users belonging to a given * Get the map of couples username/fullname of the users belonging to a given context
* context * @return the map of couples username/fullname of the users belonging to the context linked to the provided token.
*
* @return the map of couples username/fullname of the users belonging to the
* context linked to the provided token.
*/ */
@GET @GET
@Path("get-all-fullnames-and-usernames") @Path("get-all-fullnames-and-usernames")
@ -443,9 +421,7 @@ public class Users {
} }
/** /**
* Get the list of users having a given global-role, e.g. 'Administrator'. * Get the list of users having a given global-role, e.g. 'Administrator'. (Legacy)
* (Legacy)
*
* @param roleName the name of the role to be checked (e.g. Administrator) * @param roleName the name of the role to be checked (e.g. Administrator)
* @return the list of users having a given global-role * @return the list of users having a given global-role
*/ */
@ -462,8 +438,7 @@ public class Users {
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
// this method can only be called from IS scope (except for roles in // this method can only be called from IS scope (except for roles in GLOBAL_ROLES_ALLOWED_BY_LOCAL)
// GLOBAL_ROLES_ALLOWED_BY_LOCAL)
ScopeBean scopeInfo = new ScopeBean(ScopeProvider.instance.get()); ScopeBean scopeInfo = new ScopeBean(ScopeProvider.instance.get());
if(!scopeInfo.is(Type.INFRASTRUCTURE)){ if(!scopeInfo.is(Type.INFRASTRUCTURE)){
@ -503,13 +478,13 @@ public class Users {
* @param roleName the role name * @param roleName the role name
* @return the usernames having the role in the VRE * @return the usernames having the role in the VRE
* @responseExample application/json { * @responseExample application/json {
* "success": true, "success": true,
* "message": null, "message": null,
* "result": [ "result": [
* "john.smith", "john.smith",
* "marco.polo" "marco.polo"
* ] ]
* } }
*/ */
@GET @GET
@Path("get-usernames-by-role") @Path("get-usernames-by-role")
@ -519,59 +494,51 @@ public class Users {
ResponseBean responseBean = new ResponseBean(); ResponseBean responseBean = new ResponseBean();
Status status = Status.OK; Status status = Status.OK;
String context = ScopeProvider.instance.get(); 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>(); List<String> usernames = new ArrayList<String>();
try{ try{
List<UserRepresentation> users = searchByRole(keycloak, apiService.getRealm(), context, roleName); 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);
}
if(users != null){ if(users != null){
for (UserRepresentation user : users) { for (GCubeUser gCubeUser : users) {
usernames.add(user.getUsername()); usernames.add(gCubeUser.getUsername());
} }
} }
responseBean.setResult(usernames); responseBean.setResult(usernames);
responseBean.setSuccess(true); responseBean.setSuccess(true);
}else{
responseBean.setMessage("No role exists whit such a name");
status = Status.BAD_REQUEST;
}
}catch(Exception e){ }catch(Exception e){
logger.error("Unable to retrieve user with the requested role", e); logger.error("Unable to retrieve user's usernames", e);
responseBean.setMessage(e.getMessage()); responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR; status = Status.INTERNAL_SERVER_ERROR;
} }
return Response.status(status).entity(responseBean).build(); 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 @GET
@Path("user-exists") @Path("user-exists")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)

View File

@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader; import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders; import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
/** /**
* REST interface for the social networking library (vres). * REST interface for the social networking library (vres).
*/ */
@ -47,18 +48,18 @@ public class VREs {
/** /**
* @responseExample application/json { * @responseExample application/json {
* "success" : true, "success" : true,
* "message" : null, "message" : null,
* "result" : [ { "result" : [ {
* "name" : "NextNext", "name" : "NextNext",
* "context" : "/gcube/devNext/NextNext", "context" : "/gcube/devNext/NextNext",
* "description" : "NextNext description AAA" "description" : "NextNext description AAA"
* }, { }, {
* "name" : "devVRE", "name" : "devVRE",
* "context" : "/gcube/devsec/devVRE", "context" : "/gcube/devsec/devVRE",
* "description" : "devVRE description BBB" "description" : "devVRE description BBB"
* } ] } ]
* } }
* @pathExample /get-my-vres?getManagers=false * @pathExample /get-my-vres?getManagers=false
* @param getManagers set true if you also want to know the VRE-Managers * @param getManagers set true if you also want to know the VRE-Managers
* @return the list of vres along with some metadata * @return the list of vres along with some metadata
@ -69,7 +70,8 @@ public class VREs {
@Path("get-my-vres/") @Path("get-my-vres/")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response getMyVres( public Response getMyVres(
@DefaultValue("false") @QueryParam("getManagers") boolean getManagers) throws ValidationException { @DefaultValue("false") @QueryParam("getManagers") boolean getManagers
) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get(); Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId(); String username = caller.getClient().getId();

View File

@ -31,6 +31,7 @@ public class ResponseBean implements Serializable {
* @param success * @param success
* @param message * @param message
* @param result * @param result
* @param help
*/ */
public ResponseBean(boolean success, String message, Object result) { public ResponseBean(boolean success, String message, Object result) {
super(); super();
@ -39,26 +40,32 @@ public class ResponseBean implements Serializable {
this.result = result; this.result = result;
} }
public boolean isSuccess() { public boolean isSuccess() {
return success; return success;
} }
public void setSuccess(boolean success) { public void setSuccess(boolean success) {
this.success = success; this.success = success;
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
public void setMessage(String message) { public void setMessage(String message) {
this.message = message; this.message = message;
} }
public Object getResult() { public Object getResult() {
return result; return result;
} }
public void setResult(Object result) { public void setResult(Object result) {
this.result = result; this.result = result;
} }

View File

@ -11,14 +11,10 @@ import com.fasterxml.jackson.databind.SerializationFeature;
@Provider @Provider
/** /**
* Custom mapper with property CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES to * Custom mapper with property CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES to perform serialization/deserialization
* perform serialization/deserialization
* with snake case over camel case for json beans. * with snake case over camel case for json beans.
* TODO check * TODO check https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations for applying such transformation
* https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations for
* applying such transformation
* only to some classes. * only to some classes.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class CustomObjectMapper implements ContextResolver<ObjectMapper> { public class CustomObjectMapper implements ContextResolver<ObjectMapper> {

View File

@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory;
/** /**
* Cassandra connection class. * Cassandra connection class.
*
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
*/ */
public class CassandraConnection { public class CassandraConnection {
@ -23,14 +22,13 @@ public class CassandraConnection {
private CassandraConnection(){ private CassandraConnection(){
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
logger.debug("Getting connection to cassandra"); logger.info("Getting connection to cassandra");
store = new DBCassandraAstyanaxImpl(ctx.container().configuration().infrastructure()); store = new DBCassandraAstyanaxImpl(ctx.container().configuration().infrastructure());
logger.debug("Connection to cassandra created"); logger.info("Connection to cassandra created");
} }
/** /**
* Returns the object to query the cassandra cluster. * Returns the object to query the cassandra cluster.
*
* @return connection pool to cassandra cluster * @return connection pool to cassandra cluster
*/ */
public DatabookStore getDatabookStore(){ public DatabookStore getDatabookStore(){
@ -41,7 +39,6 @@ public class CassandraConnection {
/** /**
* Get the instance * Get the instance
*
* @return * @return
*/ */
public static CassandraConnection getInstance(){ public static CassandraConnection getInstance(){

View File

@ -0,0 +1,95 @@
package org.gcube.portal.social.networking.ws.utils;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.resources.gcore.utils.Group;
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.LoggerFactory;
import net.spy.memcached.KetamaConnectionFactory;
import net.spy.memcached.MemcachedClient;
/**
* @author Massimiliano Assante at ISTI-CNR
*/
public class DistributedCacheClient {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DistributedCacheClient.class);
private static final String MEMCACHED_RESOURCE_NAME = "Memcached";
private static final String CATEGORY = "Database";
private MemcachedClient mClient;
/**
* Build the singleton instance
*/
public DistributedCacheClient(){
List<InetSocketAddress> addrs = discoverHostOfServiceEndpoint();
try {
mClient = new MemcachedClient(new KetamaConnectionFactory(), addrs);
} catch (IOException e) {
e.printStackTrace();
}
}
public MemcachedClient getMemcachedClient() {
return mClient;
}
/**
* Retrieve endpoint resoruce from IS
* @return List of InetSocketAddresses
* @throws Exception
*/
private static List<InetSocketAddress> discoverHostOfServiceEndpoint(){
String currentScope = ScopeProvider.instance.get();
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
String infrastructure = "/"+ctx.container().configuration().infrastructure();
ScopeProvider.instance.set(infrastructure);
List<InetSocketAddress> toReturn = new ArrayList<InetSocketAddress>();
try{
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ MEMCACHED_RESOURCE_NAME +"'");
query.addCondition("$resource/Profile/Category/text() eq '"+ CATEGORY +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> ses = client.submit(query);
if (ses.isEmpty()) {
logger.error("There is no Memcached cluster having name: " + MEMCACHED_RESOURCE_NAME + " and Category " + CATEGORY + " on root context in this infrastructure: ");
return null;
}
for (ServiceEndpoint se : ses) {
Group<AccessPoint> aps = se.profile().accessPoints();
for (AccessPoint ap : aps.asCollection()) {
String address = ap.address(); //e.g. socialnetworking-d-d4s.d4science.org:11211
String[] splits = address.split(":");
String hostname = splits[0];
int port = Integer.parseInt(splits[1]);
toReturn.add(new InetSocketAddress(hostname, port));
}
break;
}
} catch(Exception e){
logger.error("Error while retrieving hosts for the Memcached cluster having name: " + MEMCACHED_RESOURCE_NAME + " and Category " + CATEGORY + " on root context");
}finally{
ScopeProvider.instance.set(currentScope);
}
ScopeProvider.instance.set(currentScope);
return toReturn;
}
}

View File

@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory;
/** /**
* The class discovers and offer connections to the elastic search cluster. * The class discovers and offer connections to the elastic search cluster.
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class ElasticSearchConnection { public class ElasticSearchConnection {
@ -25,9 +24,9 @@ public class ElasticSearchConnection {
private ElasticSearchConnection(){ private ElasticSearchConnection(){
try { try {
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
logger.debug("Creating connection to Elasticsearch"); logger.info("Creating connection to Elasticsearch");
es = new ElasticSearchClientImpl(ctx.container().configuration().infrastructure()); es = new ElasticSearchClientImpl(ctx.container().configuration().infrastructure());
logger.debug("Elasticsearch connection created"); logger.info("Elasticsearch connection created");
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed to connect to elasticsearch", e); logger.error("Failed to connect to elasticsearch", e);
} }
@ -41,7 +40,6 @@ public class ElasticSearchConnection {
/** /**
* Returns the object to connect to cassandra cluster. * Returns the object to connect to cassandra cluster.
*
* @return connection pool to cassandra cluster * @return connection pool to cassandra cluster
* @throws Exception * @throws Exception
*/ */

View File

@ -1,8 +1,8 @@
package org.gcube.portal.social.networking.ws.utils; package org.gcube.portal.social.networking.ws.utils;
/** /**
* Class that contains error messages to be returned in the HTTP responses. * Class that contains error messages to be returned in the HTTP responses.
*
* @author Costantino Perciante at ISTI-CNR * @author Costantino Perciante at ISTI-CNR
*/ */
public class ErrorMessages { public class ErrorMessages {

View File

@ -18,7 +18,6 @@ import org.slf4j.LoggerFactory;
/** /**
* Filters to apply to feeds/comments etc * Filters to apply to feeds/comments etc
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class Filters { public class Filters {
@ -26,8 +25,7 @@ public class Filters {
// Logger // Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Filters.class); private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Filters.class);
private static List<String> getContexts(String context) private static List<String> getContexts(String context) throws IllegalArgumentException, UserManagementSystemException, GroupRetrievalFault{
throws IllegalArgumentException, UserManagementSystemException, GroupRetrievalFault {
// retrieve group information // retrieve group information
GroupManager gm = GroupManagerWSBuilder.getInstance().getGroupManager(); GroupManager gm = GroupManagerWSBuilder.getInstance().getGroupManager();
@ -37,7 +35,8 @@ public class Filters {
if(gm.isRootVO(group.getGroupId())){ if(gm.isRootVO(group.getGroupId())){
} else if (gm.isVO(group.getGroupId())) { }
else if(gm.isVO(group.getGroupId())){
List<GCubeGroup> vres = group.getChildren(); List<GCubeGroup> vres = group.getChildren();
for (GCubeGroup gCubeGroup : vres) { for (GCubeGroup gCubeGroup : vres) {
@ -52,12 +51,10 @@ public class Filters {
} }
/** /**
* Given a list of not filtered feeds, the methods remove feeds unaccessible in * Given a list of not filtered feeds, the methods remove feeds unaccessible in this scope.
* this scope.
* If the initial context is the root: all feeds are returned; * 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 VO: feeds for vres within the vo are returned;
* If the initial context is a vre: feeds of the vre are returned; * If the initial context is a vre: feeds of the vre are returned;
*
* @param feedsIds * @param feedsIds
* @param context * @param context
* @throws Exception * @throws Exception
@ -88,13 +85,11 @@ public class Filters {
} }
/** /**
* Given a list of not filtered feeds, the methods remove feeds unaccessible in * Given a list of not filtered feeds, the methods remove feeds unaccessible in this scope.
* this scope.
* If the initial context is the root: all feeds are returned; * 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 VO: feeds for vres within the vo are returned;
* If the initial context is a vre: feeds of the vre are returned; * If the initial context is a vre: feeds of the vre are returned;
* * @param retrievedLikedFeeds
* @param feeds
* @param context * @param context
* @throws Exception * @throws Exception
*/ */
@ -112,14 +107,11 @@ public class Filters {
} }
} }
/** /**
* Given a list of not filtered posts, the methods remove posts unaccessible in * Given a list of not filtered posts, the methods remove posts unaccessible in this scope.
* this scope.
* If the initial context is the root: all posts are returned; * 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 VO: posts for vres within the vo are returned;
* If the initial context is a vre: posts of the vre are returned; * If the initial context is a vre: posts of the vre are returned;
*
* @param context * @param context
* @throws Exception * @throws Exception
*/ */
@ -139,7 +131,6 @@ public class Filters {
/** /**
* Filter comments per context * Filter comments per context
*
* @param comments * @param comments
* @param context * @param context
* @throws Exception * @throws Exception
@ -168,10 +159,8 @@ public class Filters {
} }
/** /**
* Depending on the type of object provided (e.g. Feed, Comment etc), some * Depending on the type of object provided (e.g. Feed, Comment etc), some information are removed
* information are removed * @param comments
*
* @param toClear
* @throws Exception * @throws Exception
*/ */
public static <T> void hideSensitiveInformation(List<T> toClear, String usernameCaller){ public static <T> void hideSensitiveInformation(List<T> toClear, String usernameCaller){

View File

@ -6,12 +6,8 @@ import java.io.StringReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -28,15 +24,11 @@ import org.gcube.common.resources.gcore.utils.XPathHelper;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.portal.databook.shared.ApplicationProfile; import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.Like; import org.gcube.portal.databook.shared.FeedType;
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.PrivacyLevel;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.notifications.bean.GenericItemBean; 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.MentionNotificationsThread;
import org.gcube.portal.notifications.thread.PostNotificationsThread; import org.gcube.portal.notifications.thread.PostNotificationsThread;
import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder; import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder;
@ -50,10 +42,6 @@ import org.gcube.social_networking.socialutillibrary.Utils;
import org.gcube.socialnetworking.socialtoken.SocialMessageParser; import org.gcube.socialnetworking.socialtoken.SocialMessageParser;
import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.UserManager; 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.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.w3c.dom.Node; import org.w3c.dom.Node;
@ -62,7 +50,6 @@ import org.xml.sax.InputSource;
/** /**
* Utility class. * Utility class.
*/ */
@SuppressWarnings("deprecation")
public class SocialUtils { public class SocialUtils {
// Logger // Logger
@ -108,15 +95,14 @@ public class SocialUtils {
/** /**
* Method used when an application needs to publish something. * Method used when an application needs to publish something.
* * @param feedText
* @param postText
* @param uriParams * @param uriParams
* @param previewTitle * @param previewTitle
* @param previewDescription * @param previewDescription
* @param httpImageUrl * @param httpImageUrl
* @return true upon success, false on failure * @return true upon success, false on failure
*/ */
public static Post shareApplicationUpdate( public static Feed shareApplicationUpdate(
String postText, String postText,
String uriParams, String uriParams,
String previewTitle, String previewTitle,
@ -124,7 +110,8 @@ public class SocialUtils {
String httpImageUrl, String httpImageUrl,
ApplicationProfile applicationProfile, ApplicationProfile applicationProfile,
Caller caller, Caller caller,
boolean notifyGroup) { boolean notifyGroup
){
SocialMessageParser messageParser = new SocialMessageParser(postText); SocialMessageParser messageParser = new SocialMessageParser(postText);
String escapedPostText = messageParser.getParsedMessage(); String escapedPostText = messageParser.getParsedMessage();
@ -132,17 +119,16 @@ public class SocialUtils {
ArrayList<GenericItemBean> mentionedUsers = getUsersFromUsernames(Utils.getMentionedUsernames(postText)); ArrayList<GenericItemBean> mentionedUsers = getUsersFromUsernames(Utils.getMentionedUsernames(postText));
ArrayList<ItemBean> mentionedUsersToConvertInHTML = convertToItemBean(mentionedUsers); ArrayList<ItemBean> mentionedUsersToConvertInHTML = convertToItemBean(mentionedUsers);
SocialNetworkingSite site = SocialNetworkingSiteFinder SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
escapedPostText = Utils.convertMentionUsernamesAnchorHTML(escapedPostText, mentionedUsersToConvertInHTML, escapedPostText = Utils.convertMentionUsernamesAnchorHTML(escapedPostText, mentionedUsersToConvertInHTML, site.getSiteURL(), site.getSiteLandingPagePath());
site.getSiteURL(), site.getSiteLandingPagePath()); logger.info("*** Escaped post text is " + escapedPostText);
logger.debug("*** Escaped post text is " + escapedPostText);
String scope = ScopeProvider.instance.get(); String scope = ScopeProvider.instance.get();
String appId = caller.getClient().getId(); String appId = caller.getClient().getId();
Post toWrite = buildPost( Feed toWrite =
buildPost(
escapedPostText, escapedPostText,
uriParams == null ? "" : uriParams, uriParams == null ? "" : uriParams,
previewTitle == null ? "" : previewTitle, previewTitle == null ? "" : previewTitle,
@ -152,27 +138,26 @@ public class SocialUtils {
scope); scope);
// try to save it // try to save it
boolean res = CassandraConnection.getInstance().getDatabookStore().saveAppPost(toWrite); boolean res = CassandraConnection.getInstance().getDatabookStore().saveAppFeed(toWrite);
if(res){ if(res){
logger.debug("Feed correctly written by application " + appId); logger.info("Feed correctly written by application " + appId);
// wait a bit before saving hashtags // wait a bit before saving hashtags
if(hashtags != null && !hashtags.isEmpty()) if(hashtags != null && !hashtags.isEmpty())
new Thread(()->{ new Thread(()->{
try { try {
Thread.sleep(1000); Thread.sleep(1000);
CassandraConnection.getInstance().getDatabookStore().saveHashTags(toWrite.getKey(), scope, CassandraConnection.getInstance().getDatabookStore().saveHashTags(toWrite.getKey(), scope, hashtags);
hashtags);
} catch (Exception e1) { } catch (Exception e1) {
logger.error("Failed to save hashtags in Cassandra", e1); logger.error("Failed to save hashtags in Cassandra", e1);
} }
}).start(); }).start();
// build the notification manager // build the notification manager
SocialNetworkingUser user = new SocialNetworkingUser(appId, "", applicationProfile.getName(), SocialNetworkingUser user = new SocialNetworkingUser(appId, "", applicationProfile.getName(), applicationProfile.getImageUrl());
applicationProfile.getImageUrl());
NotificationsManager nm = new ApplicationNotificationsManager( NotificationsManager nm = new ApplicationNotificationsManager(
UserManagerWSBuilder.getInstance().getUserManager(), UserManagerWSBuilder.getInstance().getUserManager(),
site, site,
@ -181,8 +166,7 @@ public class SocialUtils {
NEWS_FEED_PORTLET_CLASSNAME); NEWS_FEED_PORTLET_CLASSNAME);
if (!mentionedUsers.isEmpty()) if (!mentionedUsers.isEmpty())
new Thread(new MentionNotificationsThread(toWrite.getKey(), toWrite.getDescription(), nm, null, new Thread(new MentionNotificationsThread(toWrite.getKey(), toWrite.getDescription(), nm, null, mentionedUsers)).start();
mentionedUsers)).start();
if(notifyGroup){ if(notifyGroup){
@ -208,14 +192,16 @@ public class SocialUtils {
""+groupId, ""+groupId,
nm, nm,
new HashSet<String>(hashtags), new HashSet<String>(hashtags),
new HashSet<String>())).start(); new HashSet<String>())
).start();
}catch (Exception e) { }catch (Exception e) {
logger.debug("Feed succesfully created but unable to send notifications."); logger.debug("Feed succesfully created but unable to send notifications.");
} }
} }
return toWrite; return toWrite;
} else }
else
return null; return null;
} }
@ -224,15 +210,13 @@ public class SocialUtils {
* Build an ApplicationProfile Feed. * Build an ApplicationProfile Feed.
* *
* @param description add a description for the update you are sharing * @param description add a description for the update you are sharing
* @param uriParams the additional parameters your applicationProfile * @param uriParams the additional parameters your applicationProfile needs to open the subject of this update e.g. id=12345&type=foo
* needs to open the subject of this update e.g.
* id=12345&type=foo
* @param previewTitle the title to show in the preview * @param previewTitle the title to show in the preview
* @param previewDescription the description to show in the preview * @param previewDescription the description to show in the preview
* @param previewThumbnailUrl the image url to show in the preview * @param previewThumbnailUrl the image url to show in the preview
* @return a feed instance ready to be written * @return a feed instance ready to be written
*/ */
private static Post buildPost( private static Feed buildPost(
String description, String description,
String uriParams, String uriParams,
String previewTitle, String previewTitle,
@ -247,9 +231,9 @@ public class SocialUtils {
if (uriParams != null && uriParams.compareTo("") != 0) if (uriParams != null && uriParams.compareTo("") != 0)
uri += "?"+uriParams; uri += "?"+uriParams;
Post toReturn = new Post( Feed toReturn = new Feed(
UUID.randomUUID().toString(), UUID.randomUUID().toString(),
PostType.PUBLISH, FeedType.PUBLISH,
applicationProfile.getKey(), applicationProfile.getKey(),
new Date(), new Date(),
scopeApp, scopeApp,
@ -269,18 +253,14 @@ public class SocialUtils {
} }
/** /**
* This method looks up the applicationProfile profile among the ones available * This method looks up the applicationProfile profile among the ones available in the infrastructure
* in the infrastructure * @param idApp as identifier of your application (as reported in the ApplicationProfile)
*
* @param idApp as identifier of your application (as reported in the
* ApplicationProfile)
* @param scopeApp the scope of the application * @param scopeApp the scope of the application
*/ */
public static ApplicationProfile getProfileFromInfrastrucure(String idApp, String scopeApp) { public static ApplicationProfile getProfileFromInfrastrucure(String idApp, String scopeApp) {
ScopeBean scope = new ScopeBean(scopeApp); ScopeBean scope = new ScopeBean(scopeApp);
logger.debug( logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " + idApp + " scope: " + scope);
"Trying to fetch applicationProfile profile from the infrastructure for " + idApp + " scope: " + scope);
// set the scope of the root infrastructure // set the scope of the root infrastructure
String rootInfrastructure = scopeApp.split("/")[1]; String rootInfrastructure = scopeApp.split("/")[1];
@ -290,11 +270,11 @@ public class SocialUtils {
ApplicationProfile toReturn = new ApplicationProfile(); ApplicationProfile toReturn = new ApplicationProfile();
Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " + Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " +
"where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Body/AppId/string() " "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Body/AppId/string() " +
+
" eq '" + idApp + "'" + " eq '" + idApp + "'" +
"return $profile"); "return $profile");
DiscoveryClient<String> client = client(); DiscoveryClient<String> client = client();
List<String> appProfile = client.submit(q); List<String> appProfile = client.submit(q);
@ -314,17 +294,16 @@ public class SocialUtils {
toReturn.setName(currValue.get(0)); toReturn.setName(currValue.get(0));
} else }
throw new ApplicationProfileNotFoundException( else throw new ApplicationProfileNotFoundException("Your applicationProfile NAME was not found in the profile");
"Your applicationProfile NAME was not found in the profile");
currValue = helper.evaluate("/Resource/Profile/Description/text()"); currValue = helper.evaluate("/Resource/Profile/Description/text()");
if (currValue != null && currValue.size() > 0) { if (currValue != null && currValue.size() > 0) {
toReturn.setDescription(currValue.get(0)); toReturn.setDescription(currValue.get(0));
} else }
logger.warn("No Description exists for " + toReturn.getName()); else logger.warn("No Description exists for " + toReturn.getName());
currValue = helper.evaluate("/Resource/Profile/Body/AppId/text()"); currValue = helper.evaluate("/Resource/Profile/Body/AppId/text()");
@ -332,18 +311,16 @@ public class SocialUtils {
toReturn.setKey(currValue.get(0)); toReturn.setKey(currValue.get(0));
} else }
throw new ApplicationProfileNotFoundException( else throw new ApplicationProfileNotFoundException("Your applicationProfile ID n was not found in the profile, consider adding <AppId> element in <Body>");
"Your applicationProfile ID n was not found in the profile, consider adding <AppId> element in <Body>");
currValue = helper.evaluate("/Resource/Profile/Body/ThumbnailURL/text()"); currValue = helper.evaluate("/Resource/Profile/Body/ThumbnailURL/text()");
if (currValue != null && currValue.size() > 0) { if (currValue != null && currValue.size() > 0) {
toReturn.setImageUrl(currValue.get(0)); toReturn.setImageUrl(currValue.get(0));
} else }
throw new Exception( else throw new Exception("Your applicationProfile Image Url was not found in the profile, consider adding <ThumbnailURL> element in <Body>");
"Your applicationProfile Image Url was not found in the profile, consider adding <ThumbnailURL> element in <Body>");
currValue = helper.evaluate("/Resource/Profile/Body/EndPoint/Scope/text()"); currValue = helper.evaluate("/Resource/Profile/Body/EndPoint/Scope/text()");
if (currValue != null && currValue.size() > 0) { if (currValue != null && currValue.size() > 0) {
@ -359,14 +336,10 @@ public class SocialUtils {
} }
if (! foundUrl) if (! foundUrl)
throw new ApplicationProfileNotFoundException( throw new ApplicationProfileNotFoundException("Your applicationProfile URL was not found in the profile for Scope: " + scope.toString());
"Your applicationProfile URL was not found in the profile for Scope: "
+ scope.toString());
} }
else else throw new ApplicationProfileNotFoundException("Your applicationProfile EndPoint was not found in the profile, consider adding <EndPoint><Scope> element in <Body>");
throw new ApplicationProfileNotFoundException(
"Your applicationProfile EndPoint was not found in the profile, consider adding <EndPoint><Scope> element in <Body>");
logger.debug("Returning " + toReturn); logger.debug("Returning " + toReturn);
return toReturn; return toReturn;
} }
@ -388,7 +361,6 @@ public class SocialUtils {
/** /**
* Allows user to post a feed in a certain vre. * Allows user to post a feed in a certain vre.
*
* @param userId * @param userId
* @param postText * @param postText
* @param vreId * @param vreId
@ -400,7 +372,7 @@ public class SocialUtils {
* @param notifyGroup * @param notifyGroup
* @return The written Feed * @return The written Feed
*/ */
public static Post shareUserUpdate( public static Feed shareUserUpdate(
String userId, String userId,
String postText, String postText,
String vreId, String vreId,
@ -418,11 +390,9 @@ public class SocialUtils {
ArrayList<GenericItemBean> mentionedUsers = getUsersFromUsernames(Utils.getMentionedUsernames(postText)); ArrayList<GenericItemBean> mentionedUsers = getUsersFromUsernames(Utils.getMentionedUsernames(postText));
ArrayList<ItemBean> mentionedUsersToConvertInHTML = convertToItemBean(mentionedUsers); ArrayList<ItemBean> mentionedUsersToConvertInHTML = convertToItemBean(mentionedUsers);
SocialNetworkingSite site = SocialNetworkingSiteFinder SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get());
escapedPostText = Utils.convertMentionUsernamesAnchorHTML(escapedPostText, mentionedUsersToConvertInHTML, escapedPostText = Utils.convertMentionUsernamesAnchorHTML(escapedPostText, mentionedUsersToConvertInHTML, site.getSiteURL(), site.getSiteLandingPagePath());
site.getSiteURL(), site.getSiteLandingPagePath());
GCubeUser user; GCubeUser user;
@ -453,14 +423,12 @@ public class SocialUtils {
textToPost = escapedPostText; textToPost = escapedPostText;
} }
Post toShare = new Post(UUID.randomUUID().toString(), PostType.PUBLISH, userId, new Date(), Feed toShare = new Feed(UUID.randomUUID().toString(), FeedType.PUBLISH, userId, new Date(),
vreId, url, urlThumbnail, textToPost, PrivacyLevel.SINGLE_VRE, fullName, email, thumbnailURL, linkTitle, vreId, url, urlThumbnail, textToPost, PrivacyLevel.SINGLE_VRE, fullName, email, thumbnailURL, linkTitle, linkDesc, host);
linkDesc, host);
logger.debug("Attempting to save Post with text: " + textToPost + " Level = " + PrivacyLevel.SINGLE_VRE logger.info("Attempting to save Post with text: " + textToPost + " Level = " + PrivacyLevel.SINGLE_VRE + " Timeline = " + vreId);
+ " Timeline = " + vreId);
boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserPost(toShare); boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserFeed(toShare);
if(vreId != null && vreId.compareTo("") != 0 && result) { if(vreId != null && vreId.compareTo("") != 0 && result) {
@ -469,7 +437,7 @@ public class SocialUtils {
try { try {
try{ try{
logger.debug("Sleeping waiting for cassandra's update"); logger.info("Sleeping waiting for cassandra's update");
Thread.sleep(1000); Thread.sleep(1000);
}catch(Exception e){ }catch(Exception e){
@ -480,8 +448,7 @@ public class SocialUtils {
CassandraConnection.getInstance().getDatabookStore().saveFeedToVRETimeline(toShare.getKey(), vreId); CassandraConnection.getInstance().getDatabookStore().saveFeedToVRETimeline(toShare.getKey(), vreId);
if (hashtags != null && !hashtags.isEmpty()) if (hashtags != null && !hashtags.isEmpty())
CassandraConnection.getInstance().getDatabookStore().saveHashTags(toShare.getKey(), vreId, CassandraConnection.getInstance().getDatabookStore().saveHashTags(toShare.getKey(), vreId, hashtags);
hashtags);
} catch (FeedIDNotFoundException e) { } catch (FeedIDNotFoundException e) {
logger.error("Error writing onto VRES Time Line" + vreId); logger.error("Error writing onto VRES Time Line" + vreId);
@ -492,16 +459,13 @@ public class SocialUtils {
if (!result) if (!result)
return null; return null;
SocialNetworkingUser socialUser = new SocialNetworkingUser(userId, email, fullName, thumbnailURL); SocialNetworkingUser socialUser =
NotificationsManager nm = new ApplicationNotificationsManager( new SocialNetworkingUser(userId, email, fullName, thumbnailURL);
UserManagerWSBuilder.getInstance().getUserManager(), site, vreId, socialUser, NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, vreId, socialUser, NEWS_FEED_PORTLET_CLASSNAME);
NEWS_FEED_PORTLET_CLASSNAME);
if (!mentionedUsers.isEmpty()) if (!mentionedUsers.isEmpty())
new Thread(new MentionNotificationsThread(toShare.getKey(), toShare.getDescription(), nm, null, new Thread(new MentionNotificationsThread(toShare.getKey(), toShare.getDescription(), nm, null, mentionedUsers)).start();
mentionedUsers)).start();
// send the notification about this posts to everyone in the group if //send the notification about this posts to everyone in the group if notifyGroup is true
// notifyGroup is true
if (vreId != null && vreId.compareTo("") != 0 && notifyGroup) { if (vreId != null && vreId.compareTo("") != 0 && notifyGroup) {
try{ try{
@ -521,8 +485,8 @@ public class SocialUtils {
""+groupId, ""+groupId,
nm, nm,
new HashSet<String>(), new HashSet<String>(),
new HashSet<String>(hashtags))) new HashSet<String>(hashtags))
.start(); ).start();
logger.debug("Start sending notifications for post written by " + userId); logger.debug("Start sending notifications for post written by " + userId);
}catch(Exception e){ }catch(Exception e){
@ -531,235 +495,4 @@ public class SocialUtils {
} }
return toShare; 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,21 +2,19 @@ package org.gcube.portal.social.networking.ws.utils;
import org.gcube.common.authorization.library.ClientType; import org.gcube.common.authorization.library.ClientType;
import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.authorization.library.utils.Caller;
import org.slf4j.LoggerFactory;
/** /**
* Tokens utils methods * Tokens utils methods
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class TokensUtils { public class TokensUtils {
// a user context token (not qualified) has as qualifier the word "TOKEN" // a user context token (not qualified) has as qualifier the word "TOKEN"
private static final String DEFAULT_QUALIFIER_USER_TOKEN = "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 * Check if it is a service token
*
* @return a boolean value * @return a boolean value
*/ */
public static boolean isServiceToken(Caller caller){ public static boolean isServiceToken(Caller caller){
@ -27,7 +25,6 @@ public class TokensUtils {
/** /**
* Check if it is an application token * Check if it is an application token
*
* @return a boolean value * @return a boolean value
*/ */
public static boolean isApplicationToken(Caller caller){ public static boolean isApplicationToken(Caller caller){
@ -41,7 +38,6 @@ public class TokensUtils {
/** /**
* Check if it is a container token * Check if it is a container token
*
* @return a boolean value * @return a boolean value
*/ */
public static boolean isContainerToken(Caller caller){ public static boolean isContainerToken(Caller caller){
@ -52,12 +48,9 @@ public class TokensUtils {
/** /**
* Check if it is a user token * Check if it is a user token
*
* @return a boolean value * @return a boolean value
*/ */
public static boolean isUserToken(Caller caller){ 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(); String username = caller.getClient().getId();
if (username.startsWith("service-account-")) { if (username.startsWith("service-account-")) {
return false; return false;
@ -68,7 +61,6 @@ public class TokensUtils {
/** /**
* Check if it is a user token (not qualified) * Check if it is a user token (not qualified)
*
* @return a boolean value * @return a boolean value
*/ */
public static boolean isUserTokenDefault(Caller caller){ public static boolean isUserTokenDefault(Caller caller){
@ -77,13 +69,11 @@ public class TokensUtils {
/** /**
* Check if it is a user token (qualified) * Check if it is a user token (qualified)
*
* @return a boolean value * @return a boolean value
*/ */
public static boolean isUserTokenQualified(Caller caller){ public static boolean isUserTokenQualified(Caller caller){
return caller.getClient().getType().equals(ClientType.USER) return caller.getClient().getType().equals(ClientType.USER) && !caller.getTokenQualifier().equals(DEFAULT_QUALIFIER_USER_TOKEN);
&& !caller.getTokenQualifier().equals(DEFAULT_QUALIFIER_USER_TOKEN);
} }

View File

@ -188,4 +188,7 @@ public class UserProfileExtendedWithVerifiedEmail {
return builder.toString(); return builder.toString();
} }
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"> version="3.0">
<display-name>Restful Web Application</display-name> <display-name>Restful Web Application</display-name>

View File

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

View File

@ -43,28 +43,23 @@ public class GcoreEndpointReader {
query.addCondition(String.format("$resource/Profile/ServiceClass/text() eq '%s'",serviceClass)); query.addCondition(String.format("$resource/Profile/ServiceClass/text() eq '%s'",serviceClass));
query.addCondition("$resource/Profile/DeploymentData/Status/text() eq 'ready'"); query.addCondition("$resource/Profile/DeploymentData/Status/text() eq 'ready'");
query.addCondition(String.format("$resource/Profile/ServiceName/text() eq '%s'",serviceName)); query.addCondition(String.format("$resource/Profile/ServiceName/text() eq '%s'",serviceName));
query.setResult( query.setResult("$resource/Profile/AccessPoint/RunningInstanceInterfaces//Endpoint[@EntryName/string() eq \""+resource+"\"]/text()");
"$resource/Profile/AccessPoint/RunningInstanceInterfaces//Endpoint[@EntryName/string() eq \""
+ resource + "\"]/text()");
logger.debug("submitting quey "+query.toString()); logger.debug("submitting quey "+query.toString());
DiscoveryClient<String> client = client(); DiscoveryClient<String> client = client();
List<String> endpoints = client.submit(query); List<String> endpoints = client.submit(query);
if (endpoints == null || endpoints.isEmpty()) if (endpoints == null || endpoints.isEmpty()) throw new Exception("Cannot retrieve the GCoreEndpoint serviceName: "+serviceName +", serviceClass: " +serviceClass +", in scope: "+scope);
throw new Exception("Cannot retrieve the GCoreEndpoint serviceName: " + serviceName + ", serviceClass: "
+ serviceClass + ", in scope: " + scope);
this.resourceEntyName = endpoints.get(0); this.resourceEntyName = endpoints.get(0);
if(resourceEntyName==null) if(resourceEntyName==null)
throw new Exception("Endpoint:" + resource + ", is null for serviceName: " + serviceName throw new Exception("Endpoint:"+resource+", is null for serviceName: "+serviceName +", serviceClass: " +serviceClass +", in scope: "+scope);
+ ", serviceClass: " + serviceClass + ", in scope: " + scope);
logger.info("found entyname "+resourceEntyName+" for ckanResource: "+resource); logger.info("found entyname "+resourceEntyName+" for ckanResource: "+resource);
}catch(Exception e){ }catch(Exception e){
String error = "An error occurred during GCoreEndpoint discovery, serviceName: " + serviceName String error = "An error occurred during GCoreEndpoint discovery, serviceName: "+serviceName +", serviceClass: " +serviceClass +", in scope: "+scope +".";
+ ", serviceClass: " + serviceClass + ", in scope: " + scope + ".";
logger.error(error, e); logger.error(error, e);
throw new Exception(error); throw new Exception(error);
}finally{ }finally{

View File

@ -0,0 +1,201 @@
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);
}
}

View File

@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory;
/** /**
* Retrieves the base url of the social-networking service in the scope provided * Retrieves the base url of the social-networking service in the scope provided
*
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/ */
public class ServiceEndPointReaderSocial { public class ServiceEndPointReaderSocial {
@ -32,6 +31,7 @@ public class ServiceEndPointReaderSocial {
if(context == null || context.isEmpty()) if(context == null || context.isEmpty())
throw new IllegalArgumentException("A valid context is needed to discover the service"); throw new IllegalArgumentException("A valid context is needed to discover the service");
String oldContext = ScopeProvider.instance.get(); String oldContext = ScopeProvider.instance.get();
ScopeProvider.instance.set(context); ScopeProvider.instance.set(context);
@ -39,11 +39,10 @@ public class ServiceEndPointReaderSocial {
List<ServiceEndpoint> resources = getConfigurationFromIS(); List<ServiceEndpoint> resources = getConfigurationFromIS();
if (resources.size() == 0){ if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME + " and Category " logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Category " + CATEGORY + " in this scope.");
+ CATEGORY + " in this scope."); throw new Exception("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 {
} else {
for (ServiceEndpoint res : resources) { for (ServiceEndpoint res : resources) {
@ -80,7 +79,6 @@ public class ServiceEndPointReaderSocial {
/** /**
* Retrieve endpoints information from IS for DB * Retrieve endpoints information from IS for DB
*
* @return list of endpoints for ckan database * @return list of endpoints for ckan database
* @throws Exception * @throws Exception
*/ */
@ -97,7 +95,6 @@ public class ServiceEndPointReaderSocial {
/** /**
* Get the base path of the social networking service * Get the base path of the social networking service
*
* @return * @return
*/ */
public String getBasePath() { public String getBasePath() {