diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 00000000..df11f744 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,35 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: WiseMapping API + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'zulu' + cache: maven + - name: Build with Maven + run: mvn -B clean package --file wise-api/pom.xml + - name: Build the Docker image + run: docker build -t wisemapping/wisemapping-api:latest wise-api + + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + #- name: Update dependency graph + # uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..1a1dbff5 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,15 @@ +# WiseMapping Public License Version 1.0 (WPL) + +WiseMapping open source edition is licensed under the WiseMapping Public License Version 1.0. It is basically Apache License Version 2.0 plus the "powered by wisemapping" text requirement on every single page (the "License") unless we authorize you to remove it. +The WiseMapping Public License Version 1.0 ("WPL") consists of the [APACHE LICENSE, VERSION 2.0](http://www.apache.org/licenses/LICENSE-2.0), modified to be specific to WiseMapping, with the Additional Terms in Exhibit B. + +Unless Required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and limitations under the License. + +## EXHIBIT B - WiseMapping Public License. +Additional Terms applicable to the WiseMapping Public License. +I. Effect. +These additional terms described in this wiseMapping Public License - Additional Terms shall apply to the Covered Code under this License. +II. WiseMapping and "powered by WiseMapping" text. +This License does not grant any rights to use the trademarks "WiseMapping" even if such marks are included in the Original Code or Modifications. +However, in addition to the other notice obligations, unless wisemapping founders authorize you by email not to do it, (1) all copies of the Original Code in Executable and Source Code form must, as a form of attribution of the original author, include on each user interface screen (i) the "powered by WiseMapping" text; and (2) all derivative works and copies of derivative works of the Covered Code in Executable and Source Code form must include on each user interface screen (i) the "powered by WiseMapping" text. In addition, the "powered by WiseMapping" text, as appropriate, must be visible to all users, must appear in each user interface screen, and must be in the same position. When users click on the "powered by WiseMapping" text it must direct them to http://www.wisemapping.com. This obligation shall also apply to any copies or derivative works which are distributed under the alternative terms of Section 3.6 and this obligation must be included in any such license diff --git a/README.md b/README.md index b58b8417..80b52202 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,15 @@ WiseMapping is based on the same code product supporting [http://www.wisemapping The following products must be installed: - * OpenJDK 11 or higher + * JDK 21 or higher * Maven 3.x or higher ([http://maven.apache.org/]) - * npm 6 or higher ([https://www.npmjs.com/package/npm?activeTab=versions]) ### Compiling WiseMapping uses Maven as packaging and project management. It's composed of 5 maven sub-modules: * wise-ui: React font-end fetcher - * wise-webapp: J2EE web application + * wise-api: Springboot Backend API The full compilation of the project can be performed executing within : @@ -29,7 +28,7 @@ Once this command is executed, the file /wise-webapp/target/wisemap ### Local Development The previously generated war can be deployed locally executing within the directory /wise-webapp the following command: -`cd wise-webapp;mvn jetty:run-war` +`cd wise-api;spring-boot:run` This will start the application on the URL: [http://localhost:8080/] using file based database. @@ -96,5 +95,5 @@ After credential was created, Google will show you the clientId and clientSecret ## License The source code is Licensed under the WiseMapping Open License, Version 1.0 (the “License”); -You may obtain a copy of the License at: [https://wisemapping.atlassian.net/wiki/display/WS/License] +You may obtain a copy of the License at: [https://bitbucket.org/wisemapping/wisemapping-open-source/src/develop/license.md](https://bitbucket.org/wisemapping/wisemapping-open-source/src/develop/LICENSE.md) diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml deleted file mode 100644 index d744c8c4..00000000 --- a/bitbucket-pipelines.yml +++ /dev/null @@ -1,39 +0,0 @@ -# Template maven-build - -# This template allows you to test and build your Java project with Maven. -# The workflow allows running tests, code checkstyle and security scans on the default branch. - -# Prerequisites: pom.xml and appropriate project structure should exist in the repository. - -image: maven:3.6.3 - -pipelines: - branches: - '{master,develop}': - - step: - name: Build and Test - caches: - - node - - maven - - docker - script: - # Compile sources ... - - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash - - . $HOME/.nvm/nvm.sh && nvm install node - - mvn -B verify --file pom.xml - # Publish to docker repo ... - - docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD - - docker build -t wisemapping/wisemapping:latest -f distribution/Dockerfile wise-webapp/target/ - - docker push wisemapping/wisemapping:latest - after-script: - # Collect checkstyle results, if any, and convert to Bitbucket Code Insights. - - pipe: atlassian/checkstyle-report:0.3.0 - services: - - docker - - step: - name: Security Scan - script: - # Run a security scan for sensitive data. - # See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security - - pipe: atlassian/git-secrets-scan:0.5.1 - diff --git a/config/README.md b/config/README.md new file mode 100644 index 00000000..d30e1257 --- /dev/null +++ b/config/README.md @@ -0,0 +1,45 @@ +# Database Configuration + +## Overview + +WiseMapping supports a wide variety of databases. However, we run intensively tests over HSQL and MySQL database. + +* HyperSQL: Automatically configured when you compile WiseMapping and It's used primarily for testing. Additionally, the binary distribution already has an instance configured to provide a single click installation. +* MySQL: This version is the most tested database we support. MySQL is the database use in http://www.wisemapping.com and it's the suggested version for production environments. +* PostgreSQL: Scripts are distributed for the creation and configuration of the it. You will find them within "config/postgres" directory in the binary distribution. Additionally, JDBC driver need to be added to the container. +* Others: In spite of the fact that we don't provide yet initialization scripts for others databases, WiseMapping can be deployed in any relational database. Please, contact us if you have any particular question on this area. + +* In the following section, you are going to find a detailed explanation how to configure you WiseMapping using MySQL 5.5. + +## MySQL Installation +### Prerequisites +* Download and install MySQL. You can download it for free from: http://dev.mysql.com/downloads/ +Running SQL Scripts +Inside the WiseMapping binary distribution, you will find a directory "config/mysql". It contains all the SQL script required to configure a new WiseMapping database instance. + +You will find 4 scripts: +* create-database.sql: Create all wisemapping database and wisemapping user. +* create-schemas.sql: Create all database tables and index. +* apopulate-schemas.sql: Creates a mind map example and an a test user "test@wisemapping.org" with password "test". +* drop-schemas.sql: Drop all wisemapping tables in case you want to have a fresh installation. + +There are a lot of good tools you can use to run this scripts (eg: MySQLWorkbench). However, the simples way is to use the command line tool that is distributed as part of the MySQL installation. +If you are one brave hearts that is not afraid of the command line tools, open a terminar and execute the following lines: +~~~~ +cd /config/database/mysql +# Default MySQL installation creates a "root" user with empty password. You can connect to the database with this user if you are # logged in same machine where the database is installed and must be executed logged as "root" +# +# If you have changed the default database "root" password , you need to specify an additional -p parameter and provide the +# new password. +mysql -uroot < create-database.sql + +# Create tables and default tests user +mysql -uwisemapping -Dwisemapping -ppassword < create-schemas.sql +mysql -uwisemapping -Dwisemapping -ppassword < apopulate-schemas.sql +~~~~ + + + + +Great, you have configured you database !. Let's configure WiseMapping now. + diff --git a/config/database/hsql/apopulate-schemas.sql b/config/database/hsql/apopulate-schemas.sql deleted file mode 100644 index 90ad6018..00000000 --- a/config/database/hsql/apopulate-schemas.sql +++ /dev/null @@ -1,10 +0,0 @@ -INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (1, 'test@wisemapping.org', CURDATE()); -INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) - VALUES (1, 'Test', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURDATE(), 1,'D'); - -INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (2, 'admin@wisemapping.org', CURDATE()); -INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) - VALUES (2, 'Admin', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURDATE(), 1,'D'); - -COMMIT; -SHUTDOWN; diff --git a/config/database/hsql/create-schemas.sql b/config/database/hsql/create-schemas.sql deleted file mode 100644 index 50fe1d76..00000000 --- a/config/database/hsql/create-schemas.sql +++ /dev/null @@ -1,90 +0,0 @@ -CREATE TABLE COLLABORATOR ( - id INTEGER NOT NULL IDENTITY, - email VARCHAR(255) NOT NULL UNIQUE, - creation_date DATE -); - -CREATE TABLE USER ( - colaborator_id INTEGER NOT NULL IDENTITY, - authentication_type CHAR(1) NOT NULL, - authenticator_uri VARCHAR(255) NULL, - firstname VARCHAR(255) NOT NULL, - lastname VARCHAR(255) NOT NULL, - password VARCHAR(255) NOT NULL, - activation_code BIGINT NOT NULL, - activation_date DATE, - allow_send_email CHAR(1) NOT NULL, - locale VARCHAR(5), - google_sync BOOLEAN, - sync_code VARCHAR(255), - google_token VARCHAR(255), - FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) -); - -CREATE TABLE MINDMAP ( - id INTEGER NOT NULL IDENTITY, - title VARCHAR(255) NOT NULL, - description VARCHAR(255) NOT NULL, - xml LONGVARBINARY NOT NULL, - public BOOLEAN NOT NULL, - creation_date DATETIME, - edition_date DATETIME, - creator_id INTEGER NOT NULL, - last_editor_id INTEGER NOT NULL ---FOREIGN KEY(creator_id) REFERENCES USER(colaborator_id) -); - -CREATE TABLE LABEL ( - id INTEGER NOT NULL PRIMARY KEY IDENTITY, - title VARCHAR(30), - creator_id INTEGER NOT NULL, - parent_label_id INTEGER, - color VARCHAR(7) NOT NULL, - iconName VARCHAR(50) NOT NULL - --FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id) -); - -CREATE TABLE R_LABEL_MINDMAP ( - mindmap_id INTEGER NOT NULL, - label_id INTEGER NOT NULL, - PRIMARY KEY (mindmap_id, label_id), - FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id), - FOREIGN KEY (label_id) REFERENCES LABEL (id) ON DELETE CASCADE ON UPDATE NO ACTION -); - -CREATE TABLE MINDMAP_HISTORY ( - id INTEGER NOT NULL IDENTITY, - xml LONGVARBINARY NOT NULL, - mindmap_id INTEGER NOT NULL, - creation_date DATETIME, - editor_id INTEGER NOT NULL, - FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) -); - -CREATE TABLE COLLABORATION_PROPERTIES ( - id INTEGER NOT NULL IDENTITY, - starred BOOLEAN NOT NULL, - mindmap_properties VARCHAR(512) -); - -CREATE TABLE COLLABORATION ( - id INTEGER NOT NULL IDENTITY, - colaborator_id INTEGER NOT NULL, - properties_id INTEGER NOT NULL, - mindmap_id INTEGER NOT NULL, - role_id INTEGER NOT NULL, - FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id), - FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id), - FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id) -); - -CREATE TABLE ACCESS_AUDITORY ( - id INTEGER NOT NULL IDENTITY, - user_id INTEGER NOT NULL, - login_date DATE, - FOREIGN KEY (user_id) REFERENCES USER (colaborator_id) - ON DELETE CASCADE - ON UPDATE NO ACTION -); - -COMMIT; diff --git a/config/database/hsql/drop-schemas.sql b/config/database/hsql/drop-schemas.sql deleted file mode 100644 index 22dc8016..00000000 --- a/config/database/hsql/drop-schemas.sql +++ /dev/null @@ -1,10 +0,0 @@ -DROP TABLE IF EXISTS ACCESS_AUDITORY; -DROP TABLE IF EXISTS COLLABORATION; -DROP TABLE IF EXISTS COLLABORATION_PROPERTIES; -DROP TABLE IF EXISTS MINDMAP_HISTORY; -DROP TABLE IF EXISTS R_LABEL_MINDMAP; -DROP TABLE IF EXISTS LABEL; -DROP TABLE IF EXISTS MINDMAP; -DROP TABLE IF EXISTS USER; -DROP TABLE IF EXISTS COLLABORATOR; -COMMIT; diff --git a/config/database/migration/5.0->6.0.sql b/config/database/migration/5.0->6.0.sql new file mode 100644 index 00000000..ef28e498 --- /dev/null +++ b/config/database/migration/5.0->6.0.sql @@ -0,0 +1,10 @@ +RENAME TABLE USER TO ACCOUNT; +RENAME TABLE LABEL TO MINDMAP_LABEL; + +ALTER TABLE COLLABORATION +RENAME COLUMN colaborator_id to collaborator_id; + +ALTER TABLE ACCOUNT +RENAME COLUMN colaborator_id to collaborator_id; + +ALTER TABLE MINDMAP_LABEL DROP COLUMN iconName; diff --git a/config/database/mysql/apopulate-schemas.sql b/config/database/mysql/apopulate-schemas.sql deleted file mode 100644 index a4daf933..00000000 --- a/config/database/mysql/apopulate-schemas.sql +++ /dev/null @@ -1,13 +0,0 @@ -# -# Command: mysql -u root -p < apopulate_schemas.sql -# - -INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (1, 'test@wisemapping.org', CURRENT_DATE()); -INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) - VALUES (1, 'Test', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); - -INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (2, 'admin@wisemapping.org', CURRENT_DATE()); -INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) - VALUES (2, 'Admin', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); - -COMMIT; diff --git a/config/database/mysql/app-mysql.yaml b/config/database/mysql/app-mysql.yaml new file mode 100644 index 00000000..be89a7db --- /dev/null +++ b/config/database/mysql/app-mysql.yaml @@ -0,0 +1,14 @@ + +spring: + datasource: + url: jdbc:mysql://localhost:3306/wisemapping?useUnicode=yes&characterEncoding=UTF-8 + driver-class-name: com.mysql.cj.jdbc.Driver + password: password + username: wisemapping + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQLDialect + sql: + init: + platform: mysql \ No newline at end of file diff --git a/config/database/mysql/create-database.sql b/config/database/mysql/create-database.sql index 6d2cd226..940c5af7 100644 --- a/config/database/mysql/create-database.sql +++ b/config/database/mysql/create-database.sql @@ -1,10 +1,12 @@ -# -# Command: mysql -u root -p < create_database.sql -# -DROP DATABASE IF EXISTS wisemapping; - -CREATE DATABASE IF NOT EXISTS wisemapping - CHARACTER SET = 'utf8' - COLLATE = 'utf8_unicode_ci'; -GRANT ALL ON wisemapping.* TO 'wisemapping'@'localhost'; -SET PASSWORD FOR 'wisemapping'@'localhost' = PASSWORD('password'); \ No newline at end of file +# +# Command: mysql -u root -p < create-database.sql +# +DROP DATABASE IF EXISTS wisemapping; + +CREATE DATABASE IF NOT EXISTS wisemapping + CHARACTER SET = 'utf8' + COLLATE = 'utf8_unicode_ci'; + +CREATE USER 'wisemapping'@'%' IDENTIFIED BY 'password'; +GRANT ALL PRIVILEGES ON wisemapping.* TO 'wisemapping'@'%' WITH GRANT OPTION; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/config/database/mysql/create-schemas.sql b/config/database/mysql/create-schemas.sql deleted file mode 100644 index e8d67e90..00000000 --- a/config/database/mysql/create-schemas.sql +++ /dev/null @@ -1,128 +0,0 @@ -# -# Command: mysql -u root -p < create_schemas.sql -# - -USE wisemapping; - -CREATE TABLE COLLABORATOR ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - email VARCHAR(255) - CHARACTER SET utf8 NOT NULL UNIQUE, - creation_date DATE -) - CHARACTER SET utf8; - -CREATE TABLE USER ( - colaborator_id INTEGER NOT NULL PRIMARY KEY, - authentication_type CHAR(1) - CHARACTER SET utf8 NOT NULL, - authenticator_uri VARCHAR(255) - CHARACTER SET utf8, - firstname VARCHAR(255) CHARACTER SET utf8 NOT NULL, - lastname VARCHAR(255) CHARACTER SET utf8 NOT NULL, - password VARCHAR(255) CHARACTER SET utf8 NOT NULL, - activation_code BIGINT(20) NOT NULL, - activation_date DATE, - allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0, - locale VARCHAR(5), - google_sync BOOL, - sync_code VARCHAR(255), - google_token VARCHAR(255), - FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) - ON DELETE CASCADE - ON UPDATE NO ACTION -) - CHARACTER SET utf8; - -CREATE TABLE MINDMAP ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - title VARCHAR(255) - CHARACTER SET utf8 NOT NULL, - description VARCHAR(255) - CHARACTER SET utf8 NOT NULL, - xml MEDIUMBLOB NOT NULL, - public BOOL NOT NULL DEFAULT 0, - creation_date DATETIME, - edition_date DATETIME, - creator_id INTEGER NOT NULL, - last_editor_id INTEGER NOT NULL, - FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id) - ON DELETE CASCADE - ON UPDATE NO ACTION -) - CHARACTER SET utf8; - -CREATE TABLE LABEL ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - title VARCHAR(30) - CHARACTER SET utf8 NOT NULL, - creator_id INTEGER NOT NULL, - parent_label_id INTEGER, - color VARCHAR(7) NOT NULL, - iconName VARCHAR(50) NOT NULL, - FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id), - FOREIGN KEY (parent_label_id) REFERENCES LABEL (id) - ON DELETE CASCADE - ON UPDATE NO ACTION -) - CHARACTER SET utf8; - -CREATE TABLE R_LABEL_MINDMAP ( - mindmap_id INTEGER NOT NULL, - label_id INTEGER NOT NULL, - PRIMARY KEY (mindmap_id, label_id), - FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id), - FOREIGN KEY (label_id) REFERENCES LABEL (id) - ON DELETE CASCADE - ON UPDATE NO ACTION -) - CHARACTER SET utf8; - -CREATE TABLE MINDMAP_HISTORY -(id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - xml MEDIUMBLOB NOT NULL, - mindmap_id INTEGER NOT NULL, - creation_date DATETIME, - editor_id INTEGER NOT NULL, - FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) - ON DELETE CASCADE - ON UPDATE NO ACTION -) - CHARACTER SET utf8; - -CREATE TABLE COLLABORATION_PROPERTIES ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - starred BOOL NOT NULL DEFAULT 0, - mindmap_properties VARCHAR(512) - CHARACTER SET utf8 -) - CHARACTER SET utf8; - -CREATE TABLE COLLABORATION ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - colaborator_id INTEGER NOT NULL, - properties_id INTEGER NOT NULL, - mindmap_id INTEGER NOT NULL, - role_id INTEGER NOT NULL, - FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id), - FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) - ON DELETE CASCADE - ON UPDATE NO ACTION, - FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id) - ON DELETE CASCADE - ON UPDATE NO ACTION - UNIQUE KEY UC_ROLE (mindmap_id,colaborator_id) -) - CHARACTER SET utf8; - -CREATE TABLE ACCESS_AUDITORY ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - login_date DATE, - user_id INTEGER NOT NULL, - FOREIGN KEY (user_id) REFERENCES USER (colaborator_id) - ON DELETE CASCADE - ON UPDATE NO ACTION -) - CHARACTER SET utf8; - -COMMIT; \ No newline at end of file diff --git a/config/database/mysql/drop-schemas.sql b/config/database/mysql/drop-schemas.sql deleted file mode 100644 index d1a1e95d..00000000 --- a/config/database/mysql/drop-schemas.sql +++ /dev/null @@ -1,10 +0,0 @@ -DROP TABLE IF EXISTS ACCESS_AUDITORY; -DROP TABLE IF EXISTS COLLABORATION; -DROP TABLE IF EXISTS COLLABORATION_PROPERTIES; -DROP TABLE IF EXISTS MINDMAP_HISTORY; -DROP TABLE IF EXISTS LABEL; -DROP TABLE IF EXISTS MINDMAP; -DROP TABLE IF EXISTS R_LABEL_MINDMAP -DROP TABLE IF EXISTS USER; -DROP TABLE IF EXISTS COLLABORATOR; -COMMIT; \ No newline at end of file diff --git a/config/database/postgres/create-database.sql b/config/database/postgres/create-database.sql deleted file mode 100644 index 7000f0e2..00000000 --- a/config/database/postgres/create-database.sql +++ /dev/null @@ -1,3 +0,0 @@ -CREATE DATABASE wisemapping; -CREATE USER wisemapping WITH PASSWORD 'password'; -GRANT ALL PRIVILEGES ON DATABASE wisemapping TO wisemapping; diff --git a/config/database/postgres/drop-schemas.sql b/config/database/postgres/drop-schemas.sql deleted file mode 100644 index 0db61fdf..00000000 --- a/config/database/postgres/drop-schemas.sql +++ /dev/null @@ -1,11 +0,0 @@ -DROP TABLE TAG; -DROP TABLE ACCESS_AUDITORY; -DROP TABLE COLLABORATION; -DROP TABLE COLLABORATION_PROPERTIES; -DROP TABLE MINDMAP_HISTORY; -DROP TABLE R_LABEL_MINDMAP; -DROP TABLE LABEL; -DROP TABLE MINDMAP; -DROP TABLE "user"; -DROP TABLE COLLABORATOR; -COMMIT; \ No newline at end of file diff --git a/config/database/postgresql/app-postgresql.yaml b/config/database/postgresql/app-postgresql.yaml new file mode 100644 index 00000000..5f69c5cd --- /dev/null +++ b/config/database/postgresql/app-postgresql.yaml @@ -0,0 +1,14 @@ + +spring: + datasource: + url: jdbc:postgresql://localhost/wisemapping + driver-class-name: org.postgresql.Driver + password: password + username: wisemapping + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + sql: + init: + platform: postgresql \ No newline at end of file diff --git a/config/database/postgresql/create-database.sql b/config/database/postgresql/create-database.sql new file mode 100644 index 00000000..8d231264 --- /dev/null +++ b/config/database/postgresql/create-database.sql @@ -0,0 +1,7 @@ + +CREATE DATABASE wisemapping; +CREATE USER wisemapping WITH PASSWORD 'password'; +GRANT ALL PRIVILEGES ON DATABASE wisemapping TO wisemapping; + +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO wisemapping; +GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO wisemapping; diff --git a/distribution/Dockerfile b/distribution/Dockerfile index e185fa35..7ad26b4f 100644 --- a/distribution/Dockerfile +++ b/distribution/Dockerfile @@ -2,7 +2,8 @@ # Based on ubuntu:latest, installs WiseMapping (http://ww.wisemapping.org) # Based info setup ... -FROM tomcat:jdk17 +#FROM --platform=$BUILDPLATFORM tomcat:9.0.71-jdk17 +FROM tomcat:10.1.11-jdk17 LABEL maintainer="Paulo Gustavo Veiga " # Build variables ... @@ -20,7 +21,7 @@ RUN cd ${WEBAPP_TARGET_DIR} && jar -xvf /tmp/wisemapping.war RUN rm /tmp/wisemapping.war # Change logger to -RUN cp ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j-stdout.properties ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j.properties +RUN cp ${WEBAPP_TARGET_DIR}/WEB-INF/log4j2-stdout.xml ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j2.xml # Add support for proxy RUN sed -i 's|\ @@ -31,9 +32,6 @@ RUN sed -i 's|\ |' \ /usr/local/tomcat/conf/server.xml -RUN sed -i 's||\ - |' \ - /usr/local/tomcat/conf/context.xml # Copy default HSQL DB for testing ... RUN mkdir -p ${DB_BASE_DIR}/db COPY db/ ${DB_BASE_DIR}/db diff --git a/distribution/build-image.sh b/distribution/build-image.sh index ad4f6232..9862e7c2 100755 --- a/distribution/build-image.sh +++ b/distribution/build-image.sh @@ -5,3 +5,6 @@ set -u mvn -f ../pom.xml clean package docker build --platform linux/amd64 -t wisemapping/wisemapping:latest -f ./Dockerfile ../wise-webapp/target/ +#docker buildx create --use --platform=linux/arm64,linux/amd64 --name multi-platform-builder +#docker buildx inspect --bootstrap +#docker buildx build --platform=linux/amd64,linux/arm64 --push -t wisemapping/wisemapping:latest -f ./Dockerfile ../wise-webapp/target/ diff --git a/distribution/mysql-init/0001create-database.sql b/distribution/mysql-init/0001create-database.sql deleted file mode 100644 index 6d2cd226..00000000 --- a/distribution/mysql-init/0001create-database.sql +++ /dev/null @@ -1,10 +0,0 @@ -# -# Command: mysql -u root -p < create_database.sql -# -DROP DATABASE IF EXISTS wisemapping; - -CREATE DATABASE IF NOT EXISTS wisemapping - CHARACTER SET = 'utf8' - COLLATE = 'utf8_unicode_ci'; -GRANT ALL ON wisemapping.* TO 'wisemapping'@'localhost'; -SET PASSWORD FOR 'wisemapping'@'localhost' = PASSWORD('password'); \ No newline at end of file diff --git a/distribution/mysql-init/0003apopulate-schemas.sql b/distribution/mysql-init/0003apopulate-schemas.sql deleted file mode 100644 index a4daf933..00000000 --- a/distribution/mysql-init/0003apopulate-schemas.sql +++ /dev/null @@ -1,13 +0,0 @@ -# -# Command: mysql -u root -p < apopulate_schemas.sql -# - -INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (1, 'test@wisemapping.org', CURRENT_DATE()); -INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) - VALUES (1, 'Test', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); - -INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (2, 'admin@wisemapping.org', CURRENT_DATE()); -INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) - VALUES (2, 'Admin', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); - -COMMIT; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..d824f268 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' + +services: + wise-api: + container_name: wise-api + image: wise-api:latest + build: + context: ./wise-api + dockerfile: Dockerfile + ports: + - "8080:8080" + wise-ui: + container_name: wise-ui + image: wise-ui:latest + build: + context: ./wise-ui + dockerfile: Dockerfile + depends_on: + - wise-api + ports: + - "80:80" \ No newline at end of file diff --git a/license.txt b/license.txt deleted file mode 100644 index fa41cbdd..00000000 --- a/license.txt +++ /dev/null @@ -1,15 +0,0 @@ - Copyright [2014] [wisemapping] - - Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the - "powered by wisemapping" text requirement on every single page; - you may not use this file except in compliance with the License. - You may obtain a copy of the license at - - http://www.wisemapping.org/license - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 771be4c5..00000000 --- a/pom.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - - 5.0.19 - ${project.basedir}/wise-webapps - - - - scm:git:git@bitbucket.org:wisemapping/wisemapping-open-source.git - - - 4.0.0 - org.wisemapping - wisemapping - WiseMapping Project - 5.0.19 - pom - - - - WiseMapping Public License Version 1.0 - http://www.wisemapping.org/wisemapping-public-license-version-1-0-wpl - A business-friendly OSS license - - - - - - maven2-repository.dev.java.net - Java.net Maven 2 Repository - http://download.java.net/maven/2/ - default - - - - - WiseMapping - http://www.wisemapping.org/ - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.12 - - - exec-maven-plugin - org.codehaus.mojo - 3.0.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.16 - - - org.apache.maven.plugins - maven-resources-plugin - 2.6 - - - org.apache.maven.plugins - maven-site-plugin - 3.1 - - - org.apache.maven.plugins - maven-project-info-reports-plugin - 2.4 - - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 - - - net.alchim31.maven - yuicompressor-maven-plugin - 1.1 - - - org.apache.maven.plugins - maven-antrun-plugin - 1.7 - - - org.codehaus.mojo - native2ascii-maven-plugin - 1.0-beta-1 - - - com.github.searls - jasmine-maven-plugin - 1.3.1.5 - - - org.apache.maven.plugins - maven-release-plugin - 2.5 - - - - - - org.apache.maven.plugins - maven-resources-plugin - - UTF-8 - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 11 - 11 - UTF-8 - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.2.2 - - - distribution/assembly/standalone-editor.xml - - - - - - - - - www.wisemapping.org - scp://www.wisemapping.org/docs/project/ - - - - - - wise-ui - wise-webapp - - - - - diff --git a/wise-api/Dockerfile b/wise-api/Dockerfile new file mode 100644 index 00000000..8be77e00 --- /dev/null +++ b/wise-api/Dockerfile @@ -0,0 +1,7 @@ +FROM amazoncorretto:21.0.2 +LABEL maintainer="Paulo Gustavo Veiga " + +VOLUME /tmp +COPY target/wisemapping-api.jar wisemapping-api.jar + +ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /wisemapping-api.jar ${0} ${@}"] \ No newline at end of file diff --git a/wise-webapp/doc/REST Services.md b/wise-api/doc/REST Services.md similarity index 89% rename from wise-webapp/doc/REST Services.md rename to wise-api/doc/REST Services.md index ed5b0805..8e376a12 100644 --- a/wise-webapp/doc/REST Services.md +++ b/wise-api/doc/REST Services.md @@ -37,6 +37,6 @@ Template Path: /service/admin/users/{userId}/password Creating a new user: * Template Path: /service/admin/users/ * Method: Post - * curl "http://{host.name}:{host.port}/{context.path}/service/admin/users" --request POST --basic -u "admin@wisemapping.org:test" -H "Content-Type:application/json" --data '{"email": "te2@mydomain.de", "lastname": "lastname", "firstname":"myfirstname","password":"password"}' + * curl "http://{host.name}:{host.port}/{context.path}/service/admin/users/" --request POST --basic -u "admin@wisemapping.org:test" -H "Content-Type:application/json" --data '{"email": "te2@mydomain.de", "lastname": "lastname", "firstname":"myfirstname","password":"password"}' diff --git a/wise-api/pom.xml b/wise-api/pom.xml new file mode 100644 index 00000000..5aceb20a --- /dev/null +++ b/wise-api/pom.xml @@ -0,0 +1,232 @@ + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.3 + + + org.wisemapping + wise-api + 6.0.0-SNAPSHOT + + WiseMapping API + https://www.wisemapping.org + + + 6.0.0-SNAPSHOT + 21 + 21 + + + + + org.apache.velocity + velocity + 1.7 + compile + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + org.springframework + spring-test + 6.1.3 + test + + + + org.junit.jupiter + junit-jupiter-api + 5.9.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.9.2 + test + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-mail + + + com.intellij + annotations + 12.0 + compile + + + org.postgresql + postgresql + 42.5.4 + + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + + + + + org.hibernate.validator + hibernate-validator + 8.0.1.Final + + + jakarta.mail + jakarta.mail-api + 2.1.2 + + + com.mysql + mysql-connector-j + 8.1.0 + + + org.eclipse.angus + jakarta.mail + 2.0.2 + + + org.apache.logging.log4j + log4j-core + 2.20.0 + + + + commons-validator + commons-validator + 1.7 + + + + + com.zaxxer + HikariCP + 5.1.0 + + + + + org.hsqldb + hsqldb + 2.7.1 + runtime + + + + com.fasterxml.jackson.core + jackson-databind + 2.15.1 + + + + jakarta.transaction + jakarta.transaction-api + 2.0.1 + + + + commons-io + commons-io + 2.11.0 + + + + org.apache.httpcomponents + fluent-hc + 4.5.14 + + + + org.springframework.security + spring-security-test + 6.2.1 + test + + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + repackage + + repackage + + + wisemapping-api + + + + + + + + + + + + + + spring-snapshots + https://repo.spring.io/snapshot + + + spring-milestones + https://repo.spring.io/milestone + + + \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/Application.java b/wise-api/src/main/java/com/wisemapping/Application.java new file mode 100644 index 00000000..52729b81 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/Application.java @@ -0,0 +1,26 @@ +package com.wisemapping; + +import com.wisemapping.config.common.CommonConfig; +import com.wisemapping.config.rest.RestAppConfig; +import com.wisemapping.config.rest.WebConfig; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.security.web.firewall.StrictHttpFirewall; + +public class Application { + + public static void main(String[] args) { + new SpringApplicationBuilder() + .parent(CommonConfig.class).web(WebApplicationType.NONE) + .child(RestAppConfig.class, WebConfig.class).web(WebApplicationType.SERVLET) + .run(args); + } + + @Bean + public StrictHttpFirewall httpFirewall() { + StrictHttpFirewall firewall = new StrictHttpFirewall(); + firewall.setAllowSemicolon(true); + return firewall; + } +} diff --git a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java new file mode 100644 index 00000000..d068f10c --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java @@ -0,0 +1,48 @@ +package com.wisemapping.config.common; + +import com.wisemapping.dao.LabelManagerImpl; +import com.wisemapping.model.Account; +import com.wisemapping.security.AuthenticationProvider; +import com.wisemapping.security.Utils; +import com.wisemapping.service.MindmapServiceImpl; +import com.wisemapping.util.VelocityEngineUtils; +import jakarta.servlet.http.HttpServletRequest; +import org.jetbrains.annotations.NotNull; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; + +import java.util.Locale; + +@ComponentScan(basePackageClasses = {AuthenticationProvider.class, MindmapServiceImpl.class, LabelManagerImpl.class, VelocityEngineUtils.class}) +@Import({JPAConfig.class, SecurityConfig.class}) +@EnableAutoConfiguration +public class CommonConfig { + @Bean + public LocaleResolver localeResolver() { + return new AcceptHeaderLocaleResolver() { + @Override + public Locale resolveLocale(@NotNull HttpServletRequest request) { + final Account user = Utils.getUser(); + Locale result; + if (user != null && user.getLocale() != null) { + String locale = user.getLocale(); + final String locales[] = locale.split("_"); + + Locale.Builder builder = new Locale.Builder().setLanguage(locales[0]); + if (locales.length > 1) { + builder.setVariant(locales[1]); + } + result = builder.build(); + } else { + result = super.resolveLocale(request); + } + return result; + } + }; + } +} + diff --git a/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java new file mode 100644 index 00000000..87796cdf --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java @@ -0,0 +1,16 @@ +package com.wisemapping.config.common; + +import com.wisemapping.dao.MindmapManagerImpl; +import com.wisemapping.model.Account; +import com.wisemapping.service.MindmapServiceImpl; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + + +@Configuration +@EnableJpaRepositories(basePackageClasses={MindmapServiceImpl.class, MindmapManagerImpl.class}) +@EntityScan(basePackageClasses= Account.class) +public class JPAConfig { + +} diff --git a/wise-api/src/main/java/com/wisemapping/config/common/SecurityConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/SecurityConfig.java new file mode 100644 index 00000000..74a17f01 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/config/common/SecurityConfig.java @@ -0,0 +1,76 @@ +package com.wisemapping.config.common; + +import com.wisemapping.security.*; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity( + securedEnabled = true, + jsr250Enabled = true) +public class SecurityConfig { + + @Autowired + private ReadSecurityAdvise readAdvice; + + @Autowired + private UpdateSecurityAdvise updateAdvice; + + @Autowired + private UserDetailsService userDetailsService; + + @Bean + protected MethodSecurityExpressionHandler createExpressionHandler() { + DefaultMethodSecurityExpressionHandler expressionHandler = + new DefaultMethodSecurityExpressionHandler(); + + final MapAccessPermissionEvaluation permissionEvaluator = new MapAccessPermissionEvaluation(readAdvice, updateAdvice); + expressionHandler.setPermissionEvaluator(permissionEvaluator); + return expressionHandler; + } + + @Bean + public PasswordEncoder passwordEncoder() { + return DefaultPasswordEncoderFactories.createDelegatingPasswordEncoder(); + } + + @Bean + public AuthenticationProvider googleAuthenticationProvider() { + return new GoogleAuthenticationProvider(userDetailsService); + + } + + @Bean + public AuthenticationProvider dbAuthenticationProvider() { + final com.wisemapping.security.AuthenticationProvider provider = + new com.wisemapping.security.AuthenticationProvider(); + provider.setEncoder(passwordEncoder()); + provider.setUserDetailsService(userDetailsService); + return provider; + } + + @Bean + public AuthenticationManager authenticationManager(@NotNull HttpSecurity http) + throws Exception { + final AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class); + builder.userDetailsService(userDetailsService) + .passwordEncoder(passwordEncoder()); + + builder.authenticationProvider(dbAuthenticationProvider()); + builder.authenticationProvider(googleAuthenticationProvider()); + + return builder.build(); + } +} diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java new file mode 100644 index 00000000..15b99e2c --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -0,0 +1,70 @@ +package com.wisemapping.config.rest; + +import com.wisemapping.filter.JwtAuthenticationFilter; +import com.wisemapping.rest.MindmapController; +import jakarta.servlet.http.HttpServletResponse; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; + +import static org.springframework.security.config.Customizer.withDefaults; + + +@SpringBootApplication(scanBasePackageClasses = {MindmapController.class, JwtAuthenticationFilter.class}) +@EnableWebSecurity +public class RestAppConfig { + + @Value("${app.api.http-basic-enabled:false}") + private boolean enableHttpBasic; + + @Autowired + private JwtAuthenticationFilter jwtAuthenticationFilter; + + @Bean + MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { + return new MvcRequestMatcher.Builder(introspector); + } + + @Bean + SecurityFilterChain apiSecurityFilterChain(@NotNull final HttpSecurity http, @NotNull final MvcRequestMatcher.Builder mvc) throws Exception { + http + .securityMatcher("/**") + .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) + .authorizeHttpRequests(auth -> auth + .requestMatchers(mvc.pattern("/error")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/authenticate")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/users/")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/app/config")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/maps/*/document/xml-pub")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/users/resetPassword")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/oauth2/googlecallback")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/oauth2/confirmaccountsync")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/admin/**")).hasAnyRole("ADMIN") + .requestMatchers(mvc.pattern("/**")).hasAnyRole("USER", "ADMIN") + .anyRequest().authenticated() + ) + .logout(logout -> logout.permitAll() + .logoutSuccessHandler((request, response, authentication) -> { + response.setStatus(HttpServletResponse.SC_OK); + })) + .csrf(AbstractHttpConfigurer::disable) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + + // Http basic is mainly used by automation tests. + if (enableHttpBasic) { + http.httpBasic(withDefaults()); + } + + return http.build(); + } +} diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/WebConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/WebConfig.java new file mode 100644 index 00000000..86adf932 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/config/rest/WebConfig.java @@ -0,0 +1,27 @@ +package com.wisemapping.config.rest; + +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +public class WebConfig implements WebMvcConfigurer { + @Value("${app.security.corsAllowedOrigins:}") + private String corsAllowedOrigins; + + @Override + public void addCorsMappings(@NotNull CorsRegistry registry) { + if (!corsAllowedOrigins.isEmpty()) { + registry.addMapping("/api/**") + .exposedHeaders("*") + .allowedHeaders("*") + .allowedMethods("*") + .allowedOrigins(corsAllowedOrigins) + .maxAge(3600); + } + } +} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java b/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java new file mode 100644 index 00000000..8a6f1c6d --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java @@ -0,0 +1,26 @@ +package com.wisemapping.dao; + +import com.wisemapping.model.MindmapLabel; +import com.wisemapping.model.Account; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public interface LabelManager { + + void addLabel(@NotNull final MindmapLabel label); + + void saveLabel(@NotNull final MindmapLabel label); + + @NotNull + List getAllLabels(@NotNull final Account user); + + @Nullable + MindmapLabel getLabelById(int id, @NotNull final Account user); + + @Nullable + MindmapLabel getLabelByTitle(@NotNull final String title, @NotNull final Account user); + + void removeLabel(@NotNull final MindmapLabel label); +} diff --git a/wise-api/src/main/java/com/wisemapping/dao/LabelManagerImpl.java b/wise-api/src/main/java/com/wisemapping/dao/LabelManagerImpl.java new file mode 100644 index 00000000..ae6b7616 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/dao/LabelManagerImpl.java @@ -0,0 +1,89 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.wisemapping.dao; + +import com.wisemapping.model.MindmapLabel; +import com.wisemapping.model.Account; +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository("labelManager") +public class LabelManagerImpl + implements LabelManager { + @Autowired + private EntityManager entityManager; + + @Override + public void addLabel(@NotNull final MindmapLabel label) { + saveLabel(label); + } + + @Override + public void saveLabel(@NotNull final MindmapLabel label) { + entityManager.persist(label); + } + + @NotNull + @Override + public List getAllLabels(@NotNull final Account user) { + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.MindmapLabel wisemapping where creator=:creatorId", MindmapLabel.class); + query.setParameter("creatorId", user); + return query.getResultList(); + } + + @Nullable + @Override + public MindmapLabel getLabelById(int id, @NotNull final Account user) { + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.MindmapLabel wisemapping where id=:id and creator=:creator", MindmapLabel.class); + query.setParameter("id", id); + query.setParameter("creator", user); + + final List resultList = query.getResultList(); + return getFirst(resultList); + } + + @Nullable + @Override + public MindmapLabel getLabelByTitle(@NotNull String title, @NotNull final Account user) { + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.MindmapLabel wisemapping where title=:title and creator=:creator", MindmapLabel.class); + query.setParameter("title", title); + query.setParameter("creator", user); + return query.getResultList().stream().findFirst().orElse(null); + } + + @Override + public void removeLabel(@NotNull MindmapLabel label) { + entityManager.remove(label); + } + + @Nullable + private MindmapLabel getFirst(final List labels) { + MindmapLabel result = null; + if (labels != null && !labels.isEmpty()) { + result = labels.get(0); + } + return result; + } + +} diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java b/wise-api/src/main/java/com/wisemapping/dao/MindmapManager.java similarity index 81% rename from wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java rename to wise-api/src/main/java/com/wisemapping/dao/MindmapManager.java index 2d0b298d..7913a90c 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java +++ b/wise-api/src/main/java/com/wisemapping/dao/MindmapManager.java @@ -22,7 +22,6 @@ import com.wisemapping.model.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; import java.util.List; public interface MindmapManager { @@ -34,11 +33,11 @@ public interface MindmapManager { @Nullable Mindmap getMindmapById(int mindmapId); - Mindmap getMindmapByTitle(final String name, final User user); + Mindmap getMindmapByTitle(final String name, final Account user); void addCollaborator(Collaborator collaborator); - void addMindmap(User user, Mindmap mindmap); + void addMindmap(Account user, Mindmap mindmap); void saveMindmap(Mindmap mindmap); @@ -50,17 +49,11 @@ public interface MindmapManager { void removeCollaboration(Collaboration collaboration); - List search(MindMapCriteria criteria); - - List search(MindMapCriteria criteria, int maxResult); - List getHistoryFrom(int mindmapId); MindMapHistory getHistory(int historyId); void updateCollaboration(@NotNull Collaboration collaboration); - void purgeHistory(int mapId) throws IOException; - - List findMindmapByUser(User user); + List findMindmapByUser(Account user); } diff --git a/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java b/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java new file mode 100644 index 00000000..1fc24503 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java @@ -0,0 +1,188 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.dao; + +import com.wisemapping.model.*; +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.Calendar; +import java.util.List; + +@Repository("mindmapManager") +public class MindmapManagerImpl + implements MindmapManager { + + @Autowired + private EntityManager entityManager; + + @Override + public Collaborator findCollaborator(@NotNull final String email) { + final Collaborator collaborator; + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.Collaborator collaborator where email=:email", Collaborator.class); + query.setParameter("email", email); + + final List collaborators = query.getResultList(); + if (collaborators != null && !collaborators.isEmpty()) { + assert collaborators.size() == 1 : "More than one user with the same email!"; + collaborator = collaborators.get(0); + } else { + collaborator = null; + } + return collaborator; + } + + @Override + public List getHistoryFrom(int mindmapId) { + final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + + final CriteriaQuery cr = cb.createQuery(MindMapHistory.class); + final Root root = cr.from(MindMapHistory.class); + + final CriteriaQuery select = cr.select(root) + .where(cb.equal(root.get("mindmapId"), mindmapId)) + .orderBy(cb.desc(root.get("creationTime"))); + + return entityManager. + createQuery(select) + .setMaxResults(30) + .getResultList(); + } + + @Override + public MindMapHistory getHistory(int historyId) { + return entityManager.find(MindMapHistory.class, historyId); + } + + @Override + public void updateCollaboration(@NotNull Collaboration collaboration) { + entityManager.persist(collaboration); + } + + @Override + public List findMindmapByUser(@NotNull Account user) { + + final TypedQuery query = entityManager + .createQuery("from com.wisemapping.model.Mindmap m where m.id in (select c.mindMap.id from com.wisemapping.model.Collaboration as c where c.collaborator.id=:collabId )", Mindmap.class); + query.setParameter("collabId", user.getId()); + + return query.getResultList(); + } + + @Override + public List findCollaboration(final int collaboratorId) { + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.Collaboration c where c.collaborator.id=:collaboratorId", Collaboration.class); + query.setParameter("collaboratorId", collaboratorId); + return query.getResultList(); + } + + @Override + public void addCollaborator(@NotNull Collaborator collaborator) { + assert collaborator != null : "ADD MINDMAP COLLABORATOR: Collaborator is required!"; + entityManager.persist(collaborator); + } + + @Override + public void removeCollaboration(Collaboration collaboration) { + entityManager.remove(collaboration); + } + + @Override + public void removeCollaborator(@NotNull Collaborator collaborator) { + entityManager.remove(collaborator); + } + + @Override + @Nullable + public Mindmap getMindmapById(int id) { + return entityManager.find(Mindmap.class, id); + } + + @Override + public Mindmap getMindmapByTitle(final String title, final Account user) { + + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.Mindmap wisemapping where title=:title and creator=:creator", Mindmap.class); + query.setParameter("title", title); + query.setParameter("creator", user); + + List mindMaps = query.getResultList(); + + Mindmap result = null; + if (mindMaps != null && !mindMaps.isEmpty()) { + result = mindMaps.get(0); + } + return result; + } + + @Override + public void addMindmap(Account user, Mindmap mindMap) { + saveMindmap(mindMap); + } + + @Override + public void saveMindmap(Mindmap mindMap) { + assert mindMap != null : "Save Mindmap: Mindmap is required!"; + entityManager.persist(mindMap); + } + + @Override + public void updateMindmap(@NotNull Mindmap mindMap, boolean saveHistory) { + assert mindMap != null : "Save Mindmap: Mindmap is required!"; + entityManager.merge(mindMap); + if (saveHistory) { + saveHistory(mindMap); + } + } + + @Override + public void removeMindmap(@NotNull final Mindmap mindmap) { + // Delete history first ... + final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + + final CriteriaDelete cr = cb.createCriteriaDelete(MindMapHistory.class); + final Root root = cr.from(MindMapHistory.class); + + final CriteriaDelete deleteStatement = cr.where(cb.equal(root.get("mindmapId"), mindmap.getId())); + entityManager.createQuery(deleteStatement).executeUpdate(); + + // Remove collaborations ... + mindmap.removedCollaboration(mindmap.getCollaborations()); + + // Delete mindmap .... + entityManager.remove(mindmap); + } + + private void saveHistory(@NotNull final Mindmap mindMap) { + final MindMapHistory history = new MindMapHistory(); + + history.setZippedXml(mindMap.getZippedXml()); + history.setCreationTime(Calendar.getInstance()); + history.setEditor(mindMap.getLastEditor()); + history.setMindmapId(mindMap.getId()); + entityManager.merge(history); + } +} diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/UserManager.java b/wise-api/src/main/java/com/wisemapping/dao/UserManager.java similarity index 72% rename from wise-webapp/src/main/java/com/wisemapping/dao/UserManager.java rename to wise-api/src/main/java/com/wisemapping/dao/UserManager.java index 8ca7056a..774f6b87 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/UserManager.java +++ b/wise-api/src/main/java/com/wisemapping/dao/UserManager.java @@ -20,31 +20,31 @@ package com.wisemapping.dao; import com.wisemapping.model.AccessAuditory; import com.wisemapping.model.Collaborator; -import com.wisemapping.model.User; +import com.wisemapping.model.Account; import org.jetbrains.annotations.NotNull; import java.util.List; public interface UserManager { - List getAllUsers(); + List getAllUsers(); - User getUserBy(String email); + Account getUserBy(String email); - User getUserBy(int id); + Account getUserBy(int id); - void createUser(User user); + void createUser(Account user); void auditLogin(@NotNull AccessAuditory accessAuditory); - void updateUser(User user); + void updateUser(Account user); - User getUserByActivationCode(long code); + Account getUserByActivationCode(long code); Collaborator getCollaboratorBy(String email); - User createUser(User user, Collaborator col); + Account createUser(Account user, Collaborator col); - void removeUser(@NotNull User user); + void removeUser(@NotNull Account user); } diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java b/wise-api/src/main/java/com/wisemapping/dao/UserManagerImpl.java similarity index 61% rename from wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java rename to wise-api/src/main/java/com/wisemapping/dao/UserManagerImpl.java index e568f0ad..81358c54 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java +++ b/wise-api/src/main/java/com/wisemapping/dao/UserManagerImpl.java @@ -18,49 +18,49 @@ package com.wisemapping.dao; -import com.wisemapping.model.AccessAuditory; -import com.wisemapping.model.AuthenticationType; -import com.wisemapping.model.Collaboration; -import com.wisemapping.model.Collaborator; -import com.wisemapping.model.User; +import com.wisemapping.model.*; import com.wisemapping.security.DefaultPasswordEncoderFactories; import com.wisemapping.security.LegacyPasswordEncoder; -import org.hibernate.ObjectNotFoundException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.springframework.orm.hibernate5.HibernateTemplate; -import org.springframework.orm.hibernate5.support.HibernateDaoSupport; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Repository; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; +@Repository public class UserManagerImpl - extends HibernateDaoSupport implements UserManager { - + @Autowired + private EntityManager entityManager; + @Autowired private PasswordEncoder passwordEncoder; + public UserManagerImpl() { + } + public void setEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } - @SuppressWarnings("unchecked") - public List getAllUsers() { - return currentSession().createQuery("from com.wisemapping.model.User user").list(); + public List getAllUsers() { + return entityManager.createQuery("from com.wisemapping.model.Account user", Account.class).getResultList(); } - @Override @Nullable - public User getUserBy(@NotNull final String email) { - User user = null; + public Account getUserBy(@NotNull final String email) { + Account user = null; - var query = currentSession().createQuery("from com.wisemapping.model.User colaborator where email=:email"); + TypedQuery query = entityManager.createQuery("from com.wisemapping.model.Account colaborator where email=:email", Account.class); query.setParameter("email", email); - final List users = query.list(); + final List users = query.getResultList(); if (users != null && !users.isEmpty()) { assert users.size() == 1 : "More than one user with the same email!"; user = users.get(0); @@ -71,53 +71,47 @@ public class UserManagerImpl @Override public Collaborator getCollaboratorBy(final String email) { - final Collaborator cola; - var query = currentSession().createQuery("from com.wisemapping.model.Collaborator colaborator where " + - "email=:email"); + final Collaborator result; + + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.Collaborator colaborator where " + + "email=:email", Collaborator.class); query.setParameter("email", email); - final List cols = query.list(); + final List cols = query.getResultList(); if (cols != null && !cols.isEmpty()) { assert cols.size() == 1 : "More than one colaborator with the same email!"; - cola = cols.get(0); + result = cols.get(0); } else { - cola = null; + result = null; } - return cola; + return result; } @Nullable @Override - public User getUserBy(int id) { - User user = null; - try { - user = getHibernateTemplate().get(User.class, id); - } catch (ObjectNotFoundException e) { - // Ignore ... - } - return user; + public Account getUserBy(int id) { + return entityManager.find(Account.class, id); } @Override - public void createUser(User user) { + public void createUser(Account user) { assert user != null : "Trying to store a null user"; if (!AuthenticationType.GOOGLE_OAUTH2.equals(user.getAuthenticationType())) { user.setPassword(passwordEncoder.encode(user.getPassword())); } else { user.setPassword(""); } - getHibernateTemplate().saveOrUpdate(user); + entityManager.persist(user); } @Override - public User createUser(@NotNull User user, @NotNull Collaborator collaborator) { + public Account createUser(@NotNull Account user, @NotNull Collaborator collaborator) { assert user != null : "Trying to store a null user"; // Migrate from previous temporal collab to new user ... - final HibernateTemplate template = getHibernateTemplate(); collaborator.setEmail(collaborator.getEmail() + "_toRemove"); - template.saveOrUpdate(collaborator); - template.flush(); + entityManager.merge(collaborator); + entityManager.flush(); // Save all new... this.createUser(user); @@ -129,21 +123,21 @@ public class UserManagerImpl } // Delete old user ... - template.delete(collaborator); + entityManager.remove(collaborator); return user; } @Override - public void removeUser(@NotNull final User user) { - getHibernateTemplate().delete(user); + public void removeUser(@NotNull final Account user) { + entityManager.remove(user); } public void auditLogin(@NotNull AccessAuditory accessAuditory) { assert accessAuditory != null : "accessAuditory is null"; - getHibernateTemplate().save(accessAuditory); + entityManager.persist(accessAuditory); } - public void updateUser(@NotNull User user) { + public void updateUser(@NotNull Account user) { assert user != null : "user is null"; // Does the password need to be encrypted ? @@ -152,21 +146,21 @@ public class UserManagerImpl user.setPassword(passwordEncoder.encode(user.getPassword())); } - getHibernateTemplate().update(user); + entityManager.merge(user); } - public User getUserByActivationCode(long code) { - final User user; + public Account getUserByActivationCode(long code) { + final Account user; - var query = currentSession().createQuery("from com.wisemapping.model.User user where " + - "activationCode=:activationCode"); + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.User user where " + + "activationCode=:activationCode", Account.class); query.setParameter("activationCode", code); - final List users = query.list(); + final List users = query.getResultList(); if (users != null && !users.isEmpty()) { assert users.size() == 1 : "More than one user with the same username!"; - user = (User) users.get(0); + user = users.get(0); } else { user = null; } diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/AccessDeniedSecurityException.java b/wise-api/src/main/java/com/wisemapping/exceptions/AccessDeniedSecurityException.java similarity index 88% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/AccessDeniedSecurityException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/AccessDeniedSecurityException.java index b6bdef87..19ddf5e3 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/AccessDeniedSecurityException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/AccessDeniedSecurityException.java @@ -19,7 +19,6 @@ package com.wisemapping.exceptions; import com.wisemapping.model.Collaborator; -import com.wisemapping.model.User; import org.jetbrains.annotations.NotNull; public class AccessDeniedSecurityException @@ -31,7 +30,7 @@ public class AccessDeniedSecurityException } public AccessDeniedSecurityException(@NotNull long mapId, Collaborator user) { - super("No enough permissions to access map. Id: " + mapId + ", User: " + user, Severity.FATAL); + super("You do not have enough right access to see this map. This map has been changed to private or deleted.", Severity.FATAL); } @NotNull diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/ClientException.java b/wise-api/src/main/java/com/wisemapping/exceptions/ClientException.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/ClientException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/ClientException.java diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/EditionSessionExpiredException.java b/wise-api/src/main/java/com/wisemapping/exceptions/EditionSessionExpiredException.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/EditionSessionExpiredException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/EditionSessionExpiredException.java diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/EmailNotExistsException.java b/wise-api/src/main/java/com/wisemapping/exceptions/EmailNotExistsException.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/EmailNotExistsException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/EmailNotExistsException.java diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/InvalidEmailException.java b/wise-api/src/main/java/com/wisemapping/exceptions/InvalidEmailException.java similarity index 93% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/InvalidEmailException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/InvalidEmailException.java index 92739682..97cac72d 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/InvalidEmailException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/InvalidEmailException.java @@ -21,7 +21,7 @@ package com.wisemapping.exceptions; import org.springframework.lang.Nullable; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class InvalidEmailException extends ClientException { diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/InvalidMindmapException.java b/wise-api/src/main/java/com/wisemapping/exceptions/InvalidMindmapException.java similarity index 95% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/InvalidMindmapException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/InvalidMindmapException.java index 59dcc5e9..d7db2b99 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/InvalidMindmapException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/InvalidMindmapException.java @@ -21,7 +21,7 @@ package com.wisemapping.exceptions; import org.springframework.lang.Nullable; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class InvalidMindmapException extends ClientException { diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/LabelCouldNotFoundException.java b/wise-api/src/main/java/com/wisemapping/exceptions/LabelCouldNotFoundException.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/LabelCouldNotFoundException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/LabelCouldNotFoundException.java diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/LockException.java b/wise-api/src/main/java/com/wisemapping/exceptions/LockException.java similarity index 93% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/LockException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/LockException.java index 31f2c07f..b9347efc 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/LockException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/LockException.java @@ -19,7 +19,7 @@ package com.wisemapping.exceptions; import com.wisemapping.model.Mindmap; -import com.wisemapping.model.User; +import com.wisemapping.model.Account; import com.wisemapping.service.LockManager; import org.jetbrains.annotations.NotNull; @@ -32,7 +32,7 @@ public class LockException super(message, Severity.INFO); } - public static LockException createLockLost(@NotNull Mindmap mindmap, @NotNull User user, @NotNull LockManager manager) { + public static LockException createLockLost(@NotNull Mindmap mindmap, @NotNull Account user, @NotNull LockManager manager) { return new LockException("Lock can not be granted to " + user.getEmail() + ". The lock is assigned to " + manager.getLockInfo(mindmap)); } diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/MapCouldNotFoundException.java b/wise-api/src/main/java/com/wisemapping/exceptions/MapCouldNotFoundException.java similarity index 92% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/MapCouldNotFoundException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/MapCouldNotFoundException.java index ee8a641e..5ed7c5f3 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/MapCouldNotFoundException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/MapCouldNotFoundException.java @@ -19,7 +19,7 @@ package com.wisemapping.exceptions; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class MapCouldNotFoundException extends ClientException diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/MapNonPublicException.java b/wise-api/src/main/java/com/wisemapping/exceptions/MapNotPublicSecurityException.java similarity index 88% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/MapNonPublicException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/MapNotPublicSecurityException.java index 93a6b6ec..6d30fcff 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/MapNonPublicException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/MapNotPublicSecurityException.java @@ -20,11 +20,11 @@ package com.wisemapping.exceptions; import org.jetbrains.annotations.NotNull; -public class MapNonPublicException +public class MapNotPublicSecurityException extends ClientException { public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED"; - public MapNonPublicException(@NotNull String msg) { + public MapNotPublicSecurityException(@NotNull String msg) { super(msg, Severity.FATAL); } diff --git a/wise-api/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java b/wise-api/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java new file mode 100644 index 00000000..816c423c --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java @@ -0,0 +1,13 @@ +package com.wisemapping.exceptions; + + +import com.wisemapping.service.google.http.HttpInvokerException; + +import jakarta.validation.constraints.NotNull; + +public class OAuthAuthenticationException extends WiseMappingException { + + public OAuthAuthenticationException(@NotNull HttpInvokerException exception) { + super(exception.getMessage()); + } +} \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/OwnerCannotChangeException.java b/wise-api/src/main/java/com/wisemapping/exceptions/OwnerCannotChangeException.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/OwnerCannotChangeException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/OwnerCannotChangeException.java diff --git a/wise-webapp/src/main/java/com/wisemapping/security/CSFRRequestMatcher.java b/wise-api/src/main/java/com/wisemapping/exceptions/PasswordTooLongException.java old mode 100644 new mode 100755 similarity index 51% rename from wise-webapp/src/main/java/com/wisemapping/security/CSFRRequestMatcher.java rename to wise-api/src/main/java/com/wisemapping/exceptions/PasswordTooLongException.java index 4f3421eb..fca34aad --- a/wise-webapp/src/main/java/com/wisemapping/security/CSFRRequestMatcher.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/PasswordTooLongException.java @@ -1,44 +1,37 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.wisemapping.security; - -import org.springframework.security.web.util.matcher.RequestMatcher; - -import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; - -public class CSFRRequestMatcher implements RequestMatcher { - - private String prefix; - static String[] supportedMethods = {"POST", "PUT", "GET", "DELETE", "PATCH"}; - - @Override - public boolean matches(HttpServletRequest request) { - final String requestURI = request.getRequestURI(); - return Arrays.stream(supportedMethods).anyMatch(p -> request.getMethod().toUpperCase().equals(p)) - && requestURI.startsWith(prefix); - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } -} +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.exceptions; + + +import jakarta.validation.constraints.NotNull; + +public class PasswordTooLongException + extends ClientException { + private static final String PASSWORD_TOO_LONG = "PASSWORD_TOO_LONG"; + + public PasswordTooLongException() { + super("Password length must be less than 40 characters", Severity.WARNING); + } + + @NotNull + @Override + protected String getMsgBundleKey() { + return PASSWORD_TOO_LONG; + } +} diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/SessionExpiredException.java b/wise-api/src/main/java/com/wisemapping/exceptions/SessionExpiredException.java similarity index 92% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/SessionExpiredException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/SessionExpiredException.java index 6d34d39f..f535ccc6 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/SessionExpiredException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/SessionExpiredException.java @@ -18,15 +18,15 @@ package com.wisemapping.exceptions; -import com.wisemapping.model.User; +import com.wisemapping.model.Account; import org.jetbrains.annotations.NotNull; public class SessionExpiredException extends ClientException { private static final String MSG_KEY = "MINDMAP_TIMESTAMP_OUTDATED"; - private final User lastUpdater; + private final Account lastUpdater; - public SessionExpiredException(@NotNull String debugInfo, @NotNull User lastUpdater) { + public SessionExpiredException(@NotNull String debugInfo, @NotNull Account lastUpdater) { super(debugInfo, Severity.FATAL); this.lastUpdater = lastUpdater; } diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/Severity.java b/wise-api/src/main/java/com/wisemapping/exceptions/Severity.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/Severity.java rename to wise-api/src/main/java/com/wisemapping/exceptions/Severity.java diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/TooManyInactiveAccountsExceptions.java b/wise-api/src/main/java/com/wisemapping/exceptions/TooManyInactiveAccountsExceptions.java similarity index 93% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/TooManyInactiveAccountsExceptions.java rename to wise-api/src/main/java/com/wisemapping/exceptions/TooManyInactiveAccountsExceptions.java index dc2c8428..dcdf5815 100755 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/TooManyInactiveAccountsExceptions.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/TooManyInactiveAccountsExceptions.java @@ -19,7 +19,7 @@ package com.wisemapping.exceptions; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class TooManyInactiveAccountsExceptions extends ClientException { diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/ValidationException.java b/wise-api/src/main/java/com/wisemapping/exceptions/ValidationException.java similarity index 97% rename from wise-webapp/src/main/java/com/wisemapping/rest/ValidationException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/ValidationException.java index a3962513..e5464ea5 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/ValidationException.java +++ b/wise-api/src/main/java/com/wisemapping/exceptions/ValidationException.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package com.wisemapping.rest; +package com.wisemapping.exceptions; import com.wisemapping.exceptions.WiseMappingException; diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/WiseMappingException.java b/wise-api/src/main/java/com/wisemapping/exceptions/WiseMappingException.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/exceptions/WiseMappingException.java rename to wise-api/src/main/java/com/wisemapping/exceptions/WiseMappingException.java diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java new file mode 100644 index 00000000..927cb650 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -0,0 +1,87 @@ +package com.wisemapping.filter; + +import com.wisemapping.security.JwtTokenUtil; +import com.wisemapping.security.UserDetails; +import com.wisemapping.security.UserDetailsService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.Optional; + +import static com.wisemapping.security.JwtTokenUtil.BEARER_TOKEN_PREFIX; + +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private JwtTokenUtil jwtTokenUtil; + + final private static Logger logger = LogManager.getLogger(); + + @Override + protected void doFilterInternal(@NotNull final HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) + throws ServletException, IOException { + final Optional token = getJwtTokenFromRequest(request); + + if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) { + // Extract email from token ... + final Optional email = extractEmailFromToken(token.get()); + + if (email.isPresent() && jwtTokenUtil.validateJwtToken(token.get())) { + // Is it an existing user ? + try { + final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get()); + final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } catch (UsernameNotFoundException e) { + logger.trace("User " + email.get() + " could not be found"); + } + } + } + filterChain.doFilter(request, response); + } + + private Optional extractEmailFromToken(final @NotNull String token) { + Optional result = Optional.empty(); + try { + result = Optional.ofNullable(jwtTokenUtil.extractFromJwtToken(token)); + } catch (Exception e) { + // Handle token extraction/validation errors + logger.debug("Error extracting email from token: " + e.getMessage()); + } + logger.trace("JWT token email:" + result); + return result; + } + + private static Optional getJwtTokenFromRequest(@NotNull HttpServletRequest request) { + Optional result = Optional.empty(); + + final String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION); + if (authorizationHeader != null) { + if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) { + logger.trace("JWT Bearer token found."); + final String token = authorizationHeader.substring(BEARER_TOKEN_PREFIX.length()); + result = Optional.of(token); + } + } + return result; + } +} diff --git a/wise-webapp/src/main/java/com/wisemapping/listener/UnlockOnExpireListener.java b/wise-api/src/main/java/com/wisemapping/listener/UnlockOnExpireListener.java similarity index 88% rename from wise-webapp/src/main/java/com/wisemapping/listener/UnlockOnExpireListener.java rename to wise-api/src/main/java/com/wisemapping/listener/UnlockOnExpireListener.java index 008c8155..9e3b68d7 100644 --- a/wise-webapp/src/main/java/com/wisemapping/listener/UnlockOnExpireListener.java +++ b/wise-api/src/main/java/com/wisemapping/listener/UnlockOnExpireListener.java @@ -20,7 +20,7 @@ package com.wisemapping.listener; import com.wisemapping.exceptions.AccessDeniedSecurityException; import com.wisemapping.exceptions.LockException; -import com.wisemapping.model.User; +import com.wisemapping.model.Account; import com.wisemapping.security.Utils; import com.wisemapping.service.LockManager; import com.wisemapping.service.MindmapService; @@ -31,9 +31,9 @@ import org.apache.logging.log4j.Logger; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpSessionEvent; +import jakarta.servlet.http.HttpSessionListener; public class UnlockOnExpireListener implements HttpSessionListener { private static final Logger logger = LogManager.getLogger(); @@ -51,7 +51,7 @@ public class UnlockOnExpireListener implements HttpSessionListener { final MindmapService mindmapService = (MindmapService) wc.getBean("mindmapService"); final LockManager lockManager = mindmapService.getLockManager(); - final User user = Utils.getUser(false); + final Account user = Utils.getUser(false); if (user != null) { synchronized (mindmapService.getLockManager()) { try { diff --git a/wise-webapp/src/main/java/com/wisemapping/model/AccessAuditory.java b/wise-api/src/main/java/com/wisemapping/model/AccessAuditory.java similarity index 88% rename from wise-webapp/src/main/java/com/wisemapping/model/AccessAuditory.java rename to wise-api/src/main/java/com/wisemapping/model/AccessAuditory.java index 9b021285..873629a5 100755 --- a/wise-webapp/src/main/java/com/wisemapping/model/AccessAuditory.java +++ b/wise-api/src/main/java/com/wisemapping/model/AccessAuditory.java @@ -20,7 +20,7 @@ package com.wisemapping.model; import org.jetbrains.annotations.NotNull; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; import java.util.Calendar; @@ -38,7 +38,7 @@ public class AccessAuditory @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = true) - private User user = null; + private Account user = null; public AccessAuditory() { } @@ -59,11 +59,11 @@ public class AccessAuditory return loginDate; } - public void setUser(@NotNull User user) { + public void setUser(@NotNull Account user) { this.user = user; } - public User getUser() { + public Account getUser() { return this.user; } } \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/model/User.java b/wise-api/src/main/java/com/wisemapping/model/Account.java similarity index 80% rename from wise-webapp/src/main/java/com/wisemapping/model/User.java rename to wise-api/src/main/java/com/wisemapping/model/Account.java index 4040e4f2..18e040d8 100644 --- a/wise-webapp/src/main/java/com/wisemapping/model/User.java +++ b/wise-api/src/main/java/com/wisemapping/model/Account.java @@ -21,47 +21,50 @@ package com.wisemapping.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.persistence.*; +import jakarta.persistence.*; + import java.io.Serializable; import java.util.Calendar; @Entity -@Table(name = "USER") -@PrimaryKeyJoinColumn(name = "colaborator_id") -public class User +@Table(name = "ACCOUNT") +@PrimaryKeyJoinColumn(name = "collaborator_id") +public class Account extends Collaborator implements Serializable { + public static final int MAX_PASSWORD_LENGTH_SIZE = 40; + private String firstname; private String lastname; private String password; private String locale; - + @Column(name = "activation_code") private long activationCode; - + @Column(name = "activation_date") private Calendar activationDate; - + @Column(name = "allow_send_email") private boolean allowSendEmail = false; - + @Column(name = "authentication_type") private Character authenticationTypeCode = AuthenticationType.DATABASE.getCode(); - + @Column(name = "authenticator_uri") private String authenticatorUri; - + @Column(name = "google_sync") - private Boolean googleSync; + private Boolean googleSync; @Column(name = "sync_code") - private String syncCode; + private String syncCode; @Column(name = "google_token") - private String googleToken; + private String googleToken; - public User() { + public Account() { } public String getFullName() { @@ -88,7 +91,7 @@ public class User return password; } - public void setPassword(String password) { + public void setPassword(@jakarta.validation.constraints.NotNull String password) { this.password = password; } @@ -158,34 +161,34 @@ public class User } public void setAuthenticationTypeCode(Character authenticationTypeCode) { - this.authenticationTypeCode = authenticationTypeCode; - } + this.authenticationTypeCode = authenticationTypeCode; + } - public Boolean getGoogleSync() { - return googleSync; - } + public Boolean getGoogleSync() { + return googleSync != null && googleSync; + } - public void setGoogleSync(Boolean googleSync) { - this.googleSync = googleSync; - } - - public String getSyncCode() { - return syncCode; - } - - public void setSyncCode(String syncCode) { - this.syncCode = syncCode; - } + public void setGoogleSync(Boolean googleSync) { + this.googleSync = googleSync; + } - public String getGoogleToken() { - return googleToken; - } + public String getSyncCode() { + return syncCode; + } - public void setGoogleToken(String googleToken) { - this.googleToken = googleToken; - } - - @Override + public void setSyncCode(String syncCode) { + this.syncCode = syncCode; + } + + public String getGoogleToken() { + return googleToken; + } + + public void setGoogleToken(String googleToken) { + this.googleToken = googleToken; + } + + @Override public String toString() { return "User{" + "firstname='" + firstname + '\'' + diff --git a/wise-webapp/src/main/java/com/wisemapping/model/AuthenticationType.java b/wise-api/src/main/java/com/wisemapping/model/AuthenticationType.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/model/AuthenticationType.java rename to wise-api/src/main/java/com/wisemapping/model/AuthenticationType.java diff --git a/wise-webapp/src/main/java/com/wisemapping/model/Collaboration.java b/wise-api/src/main/java/com/wisemapping/model/Collaboration.java similarity index 96% rename from wise-webapp/src/main/java/com/wisemapping/model/Collaboration.java rename to wise-api/src/main/java/com/wisemapping/model/Collaboration.java index 40d892b8..d58cf297 100644 --- a/wise-webapp/src/main/java/com/wisemapping/model/Collaboration.java +++ b/wise-api/src/main/java/com/wisemapping/model/Collaboration.java @@ -21,8 +21,8 @@ package com.wisemapping.model; import org.jetbrains.annotations.Nullable; -import javax.persistence.*; -import javax.validation.constraints.NotNull; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; import java.io.Serializable; import java.util.Objects; @@ -42,7 +42,7 @@ public class Collaboration implements Serializable { private Mindmap mindMap; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "colaborator_id", nullable = false) + @JoinColumn(name = "collaborator_id", nullable = false) private Collaborator collaborator; @ManyToOne(cascade = CascadeType.ALL) diff --git a/wise-webapp/src/main/java/com/wisemapping/model/CollaborationEmail.java b/wise-api/src/main/java/com/wisemapping/model/CollaborationEmail.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/model/CollaborationEmail.java rename to wise-api/src/main/java/com/wisemapping/model/CollaborationEmail.java diff --git a/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java b/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java new file mode 100644 index 00000000..5dc578e7 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java @@ -0,0 +1,67 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.model; + +import org.jetbrains.annotations.NotNull; + +import jakarta.persistence.*; + +import java.io.Serializable; + +@Entity +@Table(name = "COLLABORATION_PROPERTIES") +public class CollaborationProperties implements Serializable { + public static final String DEFAULT_JSON_PROPERTIES = "{\"zoom\":0.8}"; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + private boolean starred; + @Column(name = "mindmap_properties") + private String mindmapProperties; + + public CollaborationProperties() { + + } + + public boolean getStarred() { + return starred; + } + + public void setStarred(boolean starred) { + this.starred = starred; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @NotNull + public String getMindmapProperties() { + return mindmapProperties == null ? DEFAULT_JSON_PROPERTIES : mindmapProperties; + } + + public void setMindmapProperties(@NotNull String mindmapProperties) { + this.mindmapProperties = mindmapProperties; + } +} diff --git a/wise-webapp/src/main/java/com/wisemapping/model/CollaborationRole.java b/wise-api/src/main/java/com/wisemapping/model/CollaborationRole.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/model/CollaborationRole.java rename to wise-api/src/main/java/com/wisemapping/model/CollaborationRole.java diff --git a/wise-webapp/src/main/java/com/wisemapping/model/Collaborator.java b/wise-api/src/main/java/com/wisemapping/model/Collaborator.java similarity index 99% rename from wise-webapp/src/main/java/com/wisemapping/model/Collaborator.java rename to wise-api/src/main/java/com/wisemapping/model/Collaborator.java index 02e507b7..4fa9def0 100755 --- a/wise-webapp/src/main/java/com/wisemapping/model/Collaborator.java +++ b/wise-api/src/main/java/com/wisemapping/model/Collaborator.java @@ -22,7 +22,7 @@ import org.hibernate.annotations.CacheConcurrencyStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; import java.util.Calendar; import java.util.HashSet; diff --git a/wise-webapp/src/main/java/com/wisemapping/model/Constants.java b/wise-api/src/main/java/com/wisemapping/model/Constants.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/model/Constants.java rename to wise-api/src/main/java/com/wisemapping/model/Constants.java diff --git a/wise-webapp/src/main/java/com/wisemapping/model/MindMapCriteria.java b/wise-api/src/main/java/com/wisemapping/model/MindMapCriteria.java similarity index 100% rename from wise-webapp/src/main/java/com/wisemapping/model/MindMapCriteria.java rename to wise-api/src/main/java/com/wisemapping/model/MindMapCriteria.java diff --git a/wise-webapp/src/main/java/com/wisemapping/model/MindMapHistory.java b/wise-api/src/main/java/com/wisemapping/model/MindMapHistory.java similarity index 90% rename from wise-webapp/src/main/java/com/wisemapping/model/MindMapHistory.java rename to wise-api/src/main/java/com/wisemapping/model/MindMapHistory.java index 5ef3c1c5..7b5ca62a 100755 --- a/wise-webapp/src/main/java/com/wisemapping/model/MindMapHistory.java +++ b/wise-api/src/main/java/com/wisemapping/model/MindMapHistory.java @@ -22,7 +22,7 @@ import com.wisemapping.util.ZipUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.IOException; import java.util.Calendar; @@ -38,7 +38,7 @@ public class MindMapHistory { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "editor_id", nullable = true,unique = false) - private User editor; + private Account editor; @Column(name = "xml") private byte[] zippedXml; @@ -76,11 +76,11 @@ public class MindMapHistory { } @Nullable - public User getEditor() { + public Account getEditor() { return editor; } - public void setEditor(@Nullable User editor) { + public void setEditor(@Nullable Account editor) { this.editor = editor; } diff --git a/wise-webapp/src/main/java/com/wisemapping/model/Mindmap.java b/wise-api/src/main/java/com/wisemapping/model/Mindmap.java similarity index 90% rename from wise-webapp/src/main/java/com/wisemapping/model/Mindmap.java rename to wise-api/src/main/java/com/wisemapping/model/Mindmap.java index e134d514..52b471bb 100644 --- a/wise-webapp/src/main/java/com/wisemapping/model/Mindmap.java +++ b/wise-api/src/main/java/com/wisemapping/model/Mindmap.java @@ -22,7 +22,6 @@ import com.wisemapping.exceptions.AccessDeniedSecurityException; import com.wisemapping.exceptions.InvalidMindmapException; import com.wisemapping.exceptions.WiseMappingException; import com.wisemapping.util.ZipUtils; -import org.apache.commons.lang.StringEscapeUtils; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.NotFound; @@ -30,7 +29,8 @@ import org.hibernate.annotations.NotFoundAction; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.persistence.*; +import jakarta.persistence.*; + import java.io.IOException; import java.io.Serializable; import java.io.UnsupportedEncodingException; @@ -51,14 +51,14 @@ public class Mindmap implements Serializable { @Column(name = "edition_date") private Calendar lastModificationTime; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "creator_id", unique = true) - private User creator; + private Account creator; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "last_editor_id", nullable = false) @NotFound(action = NotFoundAction.IGNORE) - private User lastEditor; + private Account lastEditor; private String description; @@ -75,7 +75,7 @@ public class Mindmap implements Serializable { name = "R_LABEL_MINDMAP", joinColumns = @JoinColumn(name = "mindmap_id"), inverseJoinColumns = @JoinColumn(name = "label_id")) - private Set