Merge branch 'develop'
commit
749c43c379
|
@ -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
|
|
@ -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
|
|
@ -9,16 +9,15 @@ WiseMapping is based on the same code product supporting [http://www.wisemapping
|
||||||
|
|
||||||
The following products must be installed:
|
The following products must be installed:
|
||||||
|
|
||||||
* OpenJDK 11 or higher
|
* JDK 21 or higher
|
||||||
* Maven 3.x or higher ([http://maven.apache.org/])
|
* Maven 3.x or higher ([http://maven.apache.org/])
|
||||||
* npm 6 or higher ([https://www.npmjs.com/package/npm?activeTab=versions])
|
|
||||||
|
|
||||||
### Compiling
|
### Compiling
|
||||||
|
|
||||||
WiseMapping uses Maven as packaging and project management. It's composed of 5 maven sub-modules:
|
WiseMapping uses Maven as packaging and project management. It's composed of 5 maven sub-modules:
|
||||||
|
|
||||||
* wise-ui: React font-end fetcher
|
* 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 <project-dir>:
|
The full compilation of the project can be performed executing within <project-dir>:
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ Once this command is executed, the file <project-dir>/wise-webapp/target/wisemap
|
||||||
### Local Development
|
### Local Development
|
||||||
The previously generated war can be deployed locally executing within the directory <project-dir>/wise-webapp the following command:
|
The previously generated war can be deployed locally executing within the directory <project-dir>/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.
|
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
|
## License
|
||||||
|
|
||||||
The source code is Licensed under the WiseMapping Open License, Version 1.0 (the “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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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 <WISEMAPPING-DIR>/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.
|
||||||
|
|
|
@ -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;
|
|
|
@ -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;
|
|
|
@ -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;
|
|
|
@ -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;
|
|
@ -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;
|
|
|
@ -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
|
|
@ -1,10 +1,12 @@
|
||||||
#
|
#
|
||||||
# Command: mysql -u root -p < create_database.sql
|
# Command: mysql -u root -p < create-database.sql
|
||||||
#
|
#
|
||||||
DROP DATABASE IF EXISTS wisemapping;
|
DROP DATABASE IF EXISTS wisemapping;
|
||||||
|
|
||||||
CREATE DATABASE IF NOT EXISTS wisemapping
|
CREATE DATABASE IF NOT EXISTS wisemapping
|
||||||
CHARACTER SET = 'utf8'
|
CHARACTER SET = 'utf8'
|
||||||
COLLATE = 'utf8_unicode_ci';
|
COLLATE = 'utf8_unicode_ci';
|
||||||
GRANT ALL ON wisemapping.* TO 'wisemapping'@'localhost';
|
|
||||||
SET PASSWORD FOR 'wisemapping'@'localhost' = PASSWORD('password');
|
CREATE USER 'wisemapping'@'%' IDENTIFIED BY 'password';
|
||||||
|
GRANT ALL PRIVILEGES ON wisemapping.* TO 'wisemapping'@'%' WITH GRANT OPTION;
|
||||||
|
FLUSH PRIVILEGES;
|
|
@ -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;
|
|
|
@ -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;
|
|
|
@ -1,3 +0,0 @@
|
||||||
CREATE DATABASE wisemapping;
|
|
||||||
CREATE USER wisemapping WITH PASSWORD 'password';
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE wisemapping TO wisemapping;
|
|
|
@ -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;
|
|
|
@ -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
|
|
@ -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;
|
|
@ -2,7 +2,8 @@
|
||||||
# Based on ubuntu:latest, installs WiseMapping (http://ww.wisemapping.org)
|
# Based on ubuntu:latest, installs WiseMapping (http://ww.wisemapping.org)
|
||||||
|
|
||||||
# Based info setup ...
|
# 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 <pveiga@wisemapping.com>"
|
LABEL maintainer="Paulo Gustavo Veiga <pveiga@wisemapping.com>"
|
||||||
|
|
||||||
# Build variables ...
|
# Build variables ...
|
||||||
|
@ -20,7 +21,7 @@ RUN cd ${WEBAPP_TARGET_DIR} && jar -xvf /tmp/wisemapping.war
|
||||||
RUN rm /tmp/wisemapping.war
|
RUN rm /tmp/wisemapping.war
|
||||||
|
|
||||||
# Change logger to
|
# 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
|
# Add support for proxy
|
||||||
RUN sed -i 's|\
|
RUN sed -i 's|\
|
||||||
|
@ -31,9 +32,6 @@ RUN sed -i 's|\
|
||||||
</Host>|' \
|
</Host>|' \
|
||||||
/usr/local/tomcat/conf/server.xml
|
/usr/local/tomcat/conf/server.xml
|
||||||
|
|
||||||
RUN sed -i 's|<Context>|<Context>\
|
|
||||||
<Loader jakartaConverter="TOMCAT" />|' \
|
|
||||||
/usr/local/tomcat/conf/context.xml
|
|
||||||
# Copy default HSQL DB for testing ...
|
# Copy default HSQL DB for testing ...
|
||||||
RUN mkdir -p ${DB_BASE_DIR}/db
|
RUN mkdir -p ${DB_BASE_DIR}/db
|
||||||
COPY db/ ${DB_BASE_DIR}/db
|
COPY db/ ${DB_BASE_DIR}/db
|
||||||
|
|
|
@ -5,3 +5,6 @@ set -u
|
||||||
|
|
||||||
mvn -f ../pom.xml clean package
|
mvn -f ../pom.xml clean package
|
||||||
docker build --platform linux/amd64 -t wisemapping/wisemapping:latest -f ./Dockerfile ../wise-webapp/target/
|
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/
|
||||||
|
|
|
@ -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');
|
|
|
@ -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;
|
|
|
@ -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"
|
15
license.txt
15
license.txt
|
@ -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.
|
|
155
pom.xml
155
pom.xml
|
@ -1,155 +0,0 @@
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
|
||||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<com.wisemapping.version>5.0.19</com.wisemapping.version>
|
|
||||||
<superpom.dir>${project.basedir}/wise-webapps</superpom.dir>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<scm>
|
|
||||||
<developerConnection>scm:git:git@bitbucket.org:wisemapping/wisemapping-open-source.git</developerConnection>
|
|
||||||
</scm>
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>org.wisemapping</groupId>
|
|
||||||
<artifactId>wisemapping</artifactId>
|
|
||||||
<name>WiseMapping Project</name>
|
|
||||||
<version>5.0.19</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
|
|
||||||
<licenses>
|
|
||||||
<license>
|
|
||||||
<name>WiseMapping Public License Version 1.0</name>
|
|
||||||
<url>http://www.wisemapping.org/wisemapping-public-license-version-1-0-wpl</url>
|
|
||||||
<comments>A business-friendly OSS license</comments>
|
|
||||||
</license>
|
|
||||||
</licenses>
|
|
||||||
|
|
||||||
<pluginRepositories>
|
|
||||||
<pluginRepository>
|
|
||||||
<id>maven2-repository.dev.java.net</id>
|
|
||||||
<name>Java.net Maven 2 Repository</name>
|
|
||||||
<url>http://download.java.net/maven/2/</url>
|
|
||||||
<layout>default</layout>
|
|
||||||
</pluginRepository>
|
|
||||||
</pluginRepositories>
|
|
||||||
|
|
||||||
<organization>
|
|
||||||
<name>WiseMapping</name>
|
|
||||||
<url>http://www.wisemapping.org/</url>
|
|
||||||
</organization>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
|
||||||
<version>2.12</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.16</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
|
||||||
<version>3.1</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
|
||||||
<version>2.4</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<version>2.10</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>net.alchim31.maven</groupId>
|
|
||||||
<artifactId>yuicompressor-maven-plugin</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
|
||||||
<version>1.7</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>native2ascii-maven-plugin</artifactId>
|
|
||||||
<version>1.0-beta-1</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.github.searls</groupId>
|
|
||||||
<artifactId>jasmine-maven-plugin</artifactId>
|
|
||||||
<version>1.3.1.5</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-release-plugin</artifactId>
|
|
||||||
<version>2.5</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.8.0</version>
|
|
||||||
<configuration>
|
|
||||||
<source>11</source>
|
|
||||||
<target>11</target>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<version>2.2.2</version>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>distribution/assembly/standalone-editor.xml</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<distributionManagement>
|
|
||||||
<site>
|
|
||||||
<id>www.wisemapping.org</id>
|
|
||||||
<url>scp://www.wisemapping.org/docs/project/</url>
|
|
||||||
</site>
|
|
||||||
</distributionManagement>
|
|
||||||
|
|
||||||
<!-- Module Dependencies -->
|
|
||||||
<modules>
|
|
||||||
<module>wise-ui</module>
|
|
||||||
<module>wise-webapp</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
FROM amazoncorretto:21.0.2
|
||||||
|
LABEL maintainer="Paulo Gustavo Veiga <pveiga@wisemapping.com>"
|
||||||
|
|
||||||
|
VOLUME /tmp
|
||||||
|
COPY target/wisemapping-api.jar wisemapping-api.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /wisemapping-api.jar ${0} ${@}"]
|
|
@ -37,6 +37,6 @@ Template Path: /service/admin/users/{userId}/password
|
||||||
Creating a new user:
|
Creating a new user:
|
||||||
* Template Path: /service/admin/users/
|
* Template Path: /service/admin/users/
|
||||||
* Method: Post
|
* 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"}'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,232 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.2.3</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>org.wisemapping</groupId>
|
||||||
|
<artifactId>wise-api</artifactId>
|
||||||
|
<version>6.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>WiseMapping API</name>
|
||||||
|
<url>https://www.wisemapping.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<com.wisemapping.version>6.0.0-SNAPSHOT</com.wisemapping.version>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
<artifactId>velocity</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.junit.vintage</groupId>
|
||||||
|
<artifactId>junit-vintage-engine</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>6.1.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.9.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.9.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.intellij</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>12.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.5.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Hibernate Validator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.validator</groupId>
|
||||||
|
<artifactId>hibernate-validator</artifactId>
|
||||||
|
<version>8.0.1.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.mail</groupId>
|
||||||
|
<artifactId>jakarta.mail-api</artifactId>
|
||||||
|
<version>2.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<version>8.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.angus</groupId>
|
||||||
|
<artifactId>jakarta.mail</artifactId>
|
||||||
|
<version>2.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>2.20.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-validator</groupId>
|
||||||
|
<artifactId>commons-validator</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Connection Pool-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.zaxxer</groupId>
|
||||||
|
<artifactId>HikariCP</artifactId>
|
||||||
|
<version>5.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Only for test purposes -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<version>2.7.1</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.15.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.transaction</groupId>
|
||||||
|
<artifactId>jakarta.transaction-api</artifactId>
|
||||||
|
<version>2.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>fluent-hc</artifactId>
|
||||||
|
<version>4.5.14</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<version>6.2.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JWT dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>repackage</id>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<finalName>wisemapping-api</finalName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<!-- <configuration>-->
|
||||||
|
<!-- <jvmArguments>-->
|
||||||
|
<!-- -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005-->
|
||||||
|
<!-- </jvmArguments>-->
|
||||||
|
<!-- </configuration>-->
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>spring-snapshots</id>
|
||||||
|
<url>https://repo.spring.io/snapshot</url>
|
||||||
|
</pluginRepository>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>spring-milestones</id>
|
||||||
|
<url>https://repo.spring.io/milestone</url>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
</project>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<MindmapLabel> 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);
|
||||||
|
}
|
|
@ -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<MindmapLabel> getAllLabels(@NotNull final Account user) {
|
||||||
|
final TypedQuery<MindmapLabel> 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<MindmapLabel> 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<MindmapLabel> resultList = query.getResultList();
|
||||||
|
return getFirst(resultList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public MindmapLabel getLabelByTitle(@NotNull String title, @NotNull final Account user) {
|
||||||
|
final TypedQuery<MindmapLabel> 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<MindmapLabel> labels) {
|
||||||
|
MindmapLabel result = null;
|
||||||
|
if (labels != null && !labels.isEmpty()) {
|
||||||
|
result = labels.get(0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ import com.wisemapping.model.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface MindmapManager {
|
public interface MindmapManager {
|
||||||
|
@ -34,11 +33,11 @@ public interface MindmapManager {
|
||||||
@Nullable
|
@Nullable
|
||||||
Mindmap getMindmapById(int mindmapId);
|
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 addCollaborator(Collaborator collaborator);
|
||||||
|
|
||||||
void addMindmap(User user, Mindmap mindmap);
|
void addMindmap(Account user, Mindmap mindmap);
|
||||||
|
|
||||||
void saveMindmap(Mindmap mindmap);
|
void saveMindmap(Mindmap mindmap);
|
||||||
|
|
||||||
|
@ -50,17 +49,11 @@ public interface MindmapManager {
|
||||||
|
|
||||||
void removeCollaboration(Collaboration collaboration);
|
void removeCollaboration(Collaboration collaboration);
|
||||||
|
|
||||||
List<Mindmap> search(MindMapCriteria criteria);
|
|
||||||
|
|
||||||
List<Mindmap> search(MindMapCriteria criteria, int maxResult);
|
|
||||||
|
|
||||||
List<MindMapHistory> getHistoryFrom(int mindmapId);
|
List<MindMapHistory> getHistoryFrom(int mindmapId);
|
||||||
|
|
||||||
MindMapHistory getHistory(int historyId);
|
MindMapHistory getHistory(int historyId);
|
||||||
|
|
||||||
void updateCollaboration(@NotNull Collaboration collaboration);
|
void updateCollaboration(@NotNull Collaboration collaboration);
|
||||||
|
|
||||||
void purgeHistory(int mapId) throws IOException;
|
List<Mindmap> findMindmapByUser(Account user);
|
||||||
|
|
||||||
List<Mindmap> findMindmapByUser(User user);
|
|
||||||
}
|
}
|
|
@ -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<Collaborator> query = entityManager.createQuery("from com.wisemapping.model.Collaborator collaborator where email=:email", Collaborator.class);
|
||||||
|
query.setParameter("email", email);
|
||||||
|
|
||||||
|
final List<Collaborator> 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<MindMapHistory> getHistoryFrom(int mindmapId) {
|
||||||
|
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
|
|
||||||
|
final CriteriaQuery<MindMapHistory> cr = cb.createQuery(MindMapHistory.class);
|
||||||
|
final Root<MindMapHistory> root = cr.from(MindMapHistory.class);
|
||||||
|
|
||||||
|
final CriteriaQuery<MindMapHistory> 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<Mindmap> findMindmapByUser(@NotNull Account user) {
|
||||||
|
|
||||||
|
final TypedQuery<Mindmap> 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<Collaboration> findCollaboration(final int collaboratorId) {
|
||||||
|
final TypedQuery<Collaboration> 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<Mindmap> 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<Mindmap> 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<MindMapHistory> cr = cb.createCriteriaDelete(MindMapHistory.class);
|
||||||
|
final Root<MindMapHistory> root = cr.from(MindMapHistory.class);
|
||||||
|
|
||||||
|
final CriteriaDelete<MindMapHistory> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,31 +20,31 @@ package com.wisemapping.dao;
|
||||||
|
|
||||||
import com.wisemapping.model.AccessAuditory;
|
import com.wisemapping.model.AccessAuditory;
|
||||||
import com.wisemapping.model.Collaborator;
|
import com.wisemapping.model.Collaborator;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface UserManager {
|
public interface UserManager {
|
||||||
|
|
||||||
List<User> getAllUsers();
|
List<Account> 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 auditLogin(@NotNull AccessAuditory accessAuditory);
|
||||||
|
|
||||||
void updateUser(User user);
|
void updateUser(Account user);
|
||||||
|
|
||||||
User getUserByActivationCode(long code);
|
Account getUserByActivationCode(long code);
|
||||||
|
|
||||||
Collaborator getCollaboratorBy(String email);
|
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);
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,49 +18,49 @@
|
||||||
|
|
||||||
package com.wisemapping.dao;
|
package com.wisemapping.dao;
|
||||||
|
|
||||||
import com.wisemapping.model.AccessAuditory;
|
import com.wisemapping.model.*;
|
||||||
import com.wisemapping.model.AuthenticationType;
|
|
||||||
import com.wisemapping.model.Collaboration;
|
|
||||||
import com.wisemapping.model.Collaborator;
|
|
||||||
import com.wisemapping.model.User;
|
|
||||||
import com.wisemapping.security.DefaultPasswordEncoderFactories;
|
import com.wisemapping.security.DefaultPasswordEncoderFactories;
|
||||||
import com.wisemapping.security.LegacyPasswordEncoder;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.springframework.orm.hibernate5.HibernateTemplate;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
@Repository
|
||||||
public class UserManagerImpl
|
public class UserManagerImpl
|
||||||
extends HibernateDaoSupport
|
|
||||||
implements UserManager {
|
implements UserManager {
|
||||||
|
@Autowired
|
||||||
|
private EntityManager entityManager;
|
||||||
|
@Autowired
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
public UserManagerImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
public void setEncoder(PasswordEncoder passwordEncoder) {
|
public void setEncoder(PasswordEncoder passwordEncoder) {
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public List<Account> getAllUsers() {
|
||||||
public List<User> getAllUsers() {
|
return entityManager.createQuery("from com.wisemapping.model.Account user", Account.class).getResultList();
|
||||||
return currentSession().createQuery("from com.wisemapping.model.User user").list();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public User getUserBy(@NotNull final String email) {
|
public Account getUserBy(@NotNull final String email) {
|
||||||
User user = null;
|
Account user = null;
|
||||||
|
|
||||||
var query = currentSession().createQuery("from com.wisemapping.model.User colaborator where email=:email");
|
TypedQuery<Account> query = entityManager.createQuery("from com.wisemapping.model.Account colaborator where email=:email", Account.class);
|
||||||
query.setParameter("email", email);
|
query.setParameter("email", email);
|
||||||
|
|
||||||
final List<User> users = query.list();
|
final List<Account> users = query.getResultList();
|
||||||
if (users != null && !users.isEmpty()) {
|
if (users != null && !users.isEmpty()) {
|
||||||
assert users.size() == 1 : "More than one user with the same email!";
|
assert users.size() == 1 : "More than one user with the same email!";
|
||||||
user = users.get(0);
|
user = users.get(0);
|
||||||
|
@ -71,53 +71,47 @@ public class UserManagerImpl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collaborator getCollaboratorBy(final String email) {
|
public Collaborator getCollaboratorBy(final String email) {
|
||||||
final Collaborator cola;
|
final Collaborator result;
|
||||||
var query = currentSession().createQuery("from com.wisemapping.model.Collaborator colaborator where " +
|
|
||||||
"email=:email");
|
final TypedQuery<Collaborator> query = entityManager.createQuery("from com.wisemapping.model.Collaborator colaborator where " +
|
||||||
|
"email=:email", Collaborator.class);
|
||||||
query.setParameter("email", email);
|
query.setParameter("email", email);
|
||||||
|
|
||||||
final List<User> cols = query.list();
|
final List<Collaborator> cols = query.getResultList();
|
||||||
if (cols != null && !cols.isEmpty()) {
|
if (cols != null && !cols.isEmpty()) {
|
||||||
assert cols.size() == 1 : "More than one colaborator with the same email!";
|
assert cols.size() == 1 : "More than one colaborator with the same email!";
|
||||||
cola = cols.get(0);
|
result = cols.get(0);
|
||||||
} else {
|
} else {
|
||||||
cola = null;
|
result = null;
|
||||||
}
|
}
|
||||||
return cola;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public User getUserBy(int id) {
|
public Account getUserBy(int id) {
|
||||||
User user = null;
|
return entityManager.find(Account.class, id);
|
||||||
try {
|
|
||||||
user = getHibernateTemplate().get(User.class, id);
|
|
||||||
} catch (ObjectNotFoundException e) {
|
|
||||||
// Ignore ...
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createUser(User user) {
|
public void createUser(Account user) {
|
||||||
assert user != null : "Trying to store a null user";
|
assert user != null : "Trying to store a null user";
|
||||||
if (!AuthenticationType.GOOGLE_OAUTH2.equals(user.getAuthenticationType())) {
|
if (!AuthenticationType.GOOGLE_OAUTH2.equals(user.getAuthenticationType())) {
|
||||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||||
} else {
|
} else {
|
||||||
user.setPassword("");
|
user.setPassword("");
|
||||||
}
|
}
|
||||||
getHibernateTemplate().saveOrUpdate(user);
|
entityManager.persist(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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";
|
assert user != null : "Trying to store a null user";
|
||||||
|
|
||||||
// Migrate from previous temporal collab to new user ...
|
// Migrate from previous temporal collab to new user ...
|
||||||
final HibernateTemplate template = getHibernateTemplate();
|
|
||||||
collaborator.setEmail(collaborator.getEmail() + "_toRemove");
|
collaborator.setEmail(collaborator.getEmail() + "_toRemove");
|
||||||
template.saveOrUpdate(collaborator);
|
entityManager.merge(collaborator);
|
||||||
template.flush();
|
entityManager.flush();
|
||||||
|
|
||||||
// Save all new...
|
// Save all new...
|
||||||
this.createUser(user);
|
this.createUser(user);
|
||||||
|
@ -129,21 +123,21 @@ public class UserManagerImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete old user ...
|
// Delete old user ...
|
||||||
template.delete(collaborator);
|
entityManager.remove(collaborator);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUser(@NotNull final User user) {
|
public void removeUser(@NotNull final Account user) {
|
||||||
getHibernateTemplate().delete(user);
|
entityManager.remove(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void auditLogin(@NotNull AccessAuditory accessAuditory) {
|
public void auditLogin(@NotNull AccessAuditory accessAuditory) {
|
||||||
assert accessAuditory != null : "accessAuditory is null";
|
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";
|
assert user != null : "user is null";
|
||||||
|
|
||||||
// Does the password need to be encrypted ?
|
// Does the password need to be encrypted ?
|
||||||
|
@ -152,21 +146,21 @@ public class UserManagerImpl
|
||||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||||
}
|
}
|
||||||
|
|
||||||
getHibernateTemplate().update(user);
|
entityManager.merge(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getUserByActivationCode(long code) {
|
public Account getUserByActivationCode(long code) {
|
||||||
final User user;
|
final Account user;
|
||||||
|
|
||||||
var query = currentSession().createQuery("from com.wisemapping.model.User user where " +
|
final TypedQuery<Account> query = entityManager.createQuery("from com.wisemapping.model.User user where " +
|
||||||
"activationCode=:activationCode");
|
"activationCode=:activationCode", Account.class);
|
||||||
query.setParameter("activationCode", code);
|
query.setParameter("activationCode", code);
|
||||||
final List users = query.list();
|
|
||||||
|
|
||||||
|
final List<Account> users = query.getResultList();
|
||||||
if (users != null && !users.isEmpty()) {
|
if (users != null && !users.isEmpty()) {
|
||||||
|
|
||||||
assert users.size() == 1 : "More than one user with the same username!";
|
assert users.size() == 1 : "More than one user with the same username!";
|
||||||
user = (User) users.get(0);
|
user = users.get(0);
|
||||||
} else {
|
} else {
|
||||||
user = null;
|
user = null;
|
||||||
}
|
}
|
|
@ -19,7 +19,6 @@
|
||||||
package com.wisemapping.exceptions;
|
package com.wisemapping.exceptions;
|
||||||
|
|
||||||
import com.wisemapping.model.Collaborator;
|
import com.wisemapping.model.Collaborator;
|
||||||
import com.wisemapping.model.User;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class AccessDeniedSecurityException
|
public class AccessDeniedSecurityException
|
||||||
|
@ -31,7 +30,7 @@ public class AccessDeniedSecurityException
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccessDeniedSecurityException(@NotNull long mapId, Collaborator user) {
|
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
|
@NotNull
|
|
@ -21,7 +21,7 @@ package com.wisemapping.exceptions;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
public class InvalidEmailException
|
public class InvalidEmailException
|
||||||
extends ClientException {
|
extends ClientException {
|
|
@ -21,7 +21,7 @@ package com.wisemapping.exceptions;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
public class InvalidMindmapException
|
public class InvalidMindmapException
|
||||||
extends ClientException {
|
extends ClientException {
|
|
@ -19,7 +19,7 @@
|
||||||
package com.wisemapping.exceptions;
|
package com.wisemapping.exceptions;
|
||||||
|
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.service.LockManager;
|
import com.wisemapping.service.LockManager;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public class LockException
|
||||||
super(message, Severity.INFO);
|
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));
|
return new LockException("Lock can not be granted to " + user.getEmail() + ". The lock is assigned to " + manager.getLockInfo(mindmap));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package com.wisemapping.exceptions;
|
package com.wisemapping.exceptions;
|
||||||
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
public class MapCouldNotFoundException
|
public class MapCouldNotFoundException
|
||||||
extends ClientException
|
extends ClientException
|
|
@ -20,11 +20,11 @@ package com.wisemapping.exceptions;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class MapNonPublicException
|
public class MapNotPublicSecurityException
|
||||||
extends ClientException {
|
extends ClientException {
|
||||||
public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED";
|
public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED";
|
||||||
|
|
||||||
public MapNonPublicException(@NotNull String msg) {
|
public MapNotPublicSecurityException(@NotNull String msg) {
|
||||||
super(msg, Severity.FATAL);
|
super(msg, Severity.FATAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,44 +1,37 @@
|
||||||
/*
|
/*
|
||||||
* Copyright [2022] [wisemapping]
|
* Copyright [2022] [wisemapping]
|
||||||
*
|
*
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
* "powered by wisemapping" text requirement on every single page;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the license at
|
* You may obtain a copy of the license at
|
||||||
*
|
*
|
||||||
* http://www.wisemapping.org/license
|
* http://www.wisemapping.org/license
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.wisemapping.security;
|
|
||||||
|
package com.wisemapping.exceptions;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import java.util.Arrays;
|
|
||||||
|
public class PasswordTooLongException
|
||||||
public class CSFRRequestMatcher implements RequestMatcher {
|
extends ClientException {
|
||||||
|
private static final String PASSWORD_TOO_LONG = "PASSWORD_TOO_LONG";
|
||||||
private String prefix;
|
|
||||||
static String[] supportedMethods = {"POST", "PUT", "GET", "DELETE", "PATCH"};
|
public PasswordTooLongException() {
|
||||||
|
super("Password length must be less than 40 characters", Severity.WARNING);
|
||||||
@Override
|
}
|
||||||
public boolean matches(HttpServletRequest request) {
|
|
||||||
final String requestURI = request.getRequestURI();
|
@NotNull
|
||||||
return Arrays.stream(supportedMethods).anyMatch(p -> request.getMethod().toUpperCase().equals(p))
|
@Override
|
||||||
&& requestURI.startsWith(prefix);
|
protected String getMsgBundleKey() {
|
||||||
}
|
return PASSWORD_TOO_LONG;
|
||||||
|
}
|
||||||
public String getPrefix() {
|
}
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrefix(String prefix) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,15 +18,15 @@
|
||||||
|
|
||||||
package com.wisemapping.exceptions;
|
package com.wisemapping.exceptions;
|
||||||
|
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class SessionExpiredException
|
public class SessionExpiredException
|
||||||
extends ClientException {
|
extends ClientException {
|
||||||
private static final String MSG_KEY = "MINDMAP_TIMESTAMP_OUTDATED";
|
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);
|
super(debugInfo, Severity.FATAL);
|
||||||
this.lastUpdater = lastUpdater;
|
this.lastUpdater = lastUpdater;
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
package com.wisemapping.exceptions;
|
package com.wisemapping.exceptions;
|
||||||
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
public class TooManyInactiveAccountsExceptions
|
public class TooManyInactiveAccountsExceptions
|
||||||
extends ClientException {
|
extends ClientException {
|
|
@ -16,7 +16,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.wisemapping.rest;
|
package com.wisemapping.exceptions;
|
||||||
|
|
||||||
|
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
|
@ -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<String> token = getJwtTokenFromRequest(request);
|
||||||
|
|
||||||
|
if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
|
// Extract email from token ...
|
||||||
|
final Optional<String> 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<String> extractEmailFromToken(final @NotNull String token) {
|
||||||
|
Optional<String> 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<String> getJwtTokenFromRequest(@NotNull HttpServletRequest request) {
|
||||||
|
Optional<String> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ package com.wisemapping.listener;
|
||||||
|
|
||||||
import com.wisemapping.exceptions.AccessDeniedSecurityException;
|
import com.wisemapping.exceptions.AccessDeniedSecurityException;
|
||||||
import com.wisemapping.exceptions.LockException;
|
import com.wisemapping.exceptions.LockException;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.security.Utils;
|
import com.wisemapping.security.Utils;
|
||||||
import com.wisemapping.service.LockManager;
|
import com.wisemapping.service.LockManager;
|
||||||
import com.wisemapping.service.MindmapService;
|
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.WebApplicationContext;
|
||||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpSessionEvent;
|
import jakarta.servlet.http.HttpSessionEvent;
|
||||||
import javax.servlet.http.HttpSessionListener;
|
import jakarta.servlet.http.HttpSessionListener;
|
||||||
|
|
||||||
public class UnlockOnExpireListener implements HttpSessionListener {
|
public class UnlockOnExpireListener implements HttpSessionListener {
|
||||||
private static final Logger logger = LogManager.getLogger();
|
private static final Logger logger = LogManager.getLogger();
|
||||||
|
@ -51,7 +51,7 @@ public class UnlockOnExpireListener implements HttpSessionListener {
|
||||||
final MindmapService mindmapService = (MindmapService) wc.getBean("mindmapService");
|
final MindmapService mindmapService = (MindmapService) wc.getBean("mindmapService");
|
||||||
|
|
||||||
final LockManager lockManager = mindmapService.getLockManager();
|
final LockManager lockManager = mindmapService.getLockManager();
|
||||||
final User user = Utils.getUser(false);
|
final Account user = Utils.getUser(false);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
synchronized (mindmapService.getLockManager()) {
|
synchronized (mindmapService.getLockManager()) {
|
||||||
try {
|
try {
|
|
@ -20,7 +20,7 @@ package com.wisemapping.model;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public class AccessAuditory
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "user_id", nullable = true)
|
@JoinColumn(name = "user_id", nullable = true)
|
||||||
private User user = null;
|
private Account user = null;
|
||||||
|
|
||||||
public AccessAuditory() {
|
public AccessAuditory() {
|
||||||
}
|
}
|
||||||
|
@ -59,11 +59,11 @@ public class AccessAuditory
|
||||||
return loginDate;
|
return loginDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUser(@NotNull User user) {
|
public void setUser(@NotNull Account user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getUser() {
|
public Account getUser() {
|
||||||
return this.user;
|
return this.user;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,47 +21,50 @@ package com.wisemapping.model;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "USER")
|
@Table(name = "ACCOUNT")
|
||||||
@PrimaryKeyJoinColumn(name = "colaborator_id")
|
@PrimaryKeyJoinColumn(name = "collaborator_id")
|
||||||
public class User
|
public class Account
|
||||||
extends Collaborator
|
extends Collaborator
|
||||||
implements Serializable {
|
implements Serializable {
|
||||||
|
|
||||||
|
public static final int MAX_PASSWORD_LENGTH_SIZE = 40;
|
||||||
|
|
||||||
private String firstname;
|
private String firstname;
|
||||||
private String lastname;
|
private String lastname;
|
||||||
private String password;
|
private String password;
|
||||||
private String locale;
|
private String locale;
|
||||||
|
|
||||||
@Column(name = "activation_code")
|
@Column(name = "activation_code")
|
||||||
private long activationCode;
|
private long activationCode;
|
||||||
|
|
||||||
@Column(name = "activation_date")
|
@Column(name = "activation_date")
|
||||||
private Calendar activationDate;
|
private Calendar activationDate;
|
||||||
|
|
||||||
@Column(name = "allow_send_email")
|
@Column(name = "allow_send_email")
|
||||||
private boolean allowSendEmail = false;
|
private boolean allowSendEmail = false;
|
||||||
|
|
||||||
@Column(name = "authentication_type")
|
@Column(name = "authentication_type")
|
||||||
private Character authenticationTypeCode = AuthenticationType.DATABASE.getCode();
|
private Character authenticationTypeCode = AuthenticationType.DATABASE.getCode();
|
||||||
|
|
||||||
@Column(name = "authenticator_uri")
|
@Column(name = "authenticator_uri")
|
||||||
private String authenticatorUri;
|
private String authenticatorUri;
|
||||||
|
|
||||||
@Column(name = "google_sync")
|
@Column(name = "google_sync")
|
||||||
private Boolean googleSync;
|
private Boolean googleSync;
|
||||||
|
|
||||||
@Column(name = "sync_code")
|
@Column(name = "sync_code")
|
||||||
private String syncCode;
|
private String syncCode;
|
||||||
|
|
||||||
@Column(name = "google_token")
|
@Column(name = "google_token")
|
||||||
private String googleToken;
|
private String googleToken;
|
||||||
|
|
||||||
public User() {
|
public Account() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFullName() {
|
public String getFullName() {
|
||||||
|
@ -88,7 +91,7 @@ public class User
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(String password) {
|
public void setPassword(@jakarta.validation.constraints.NotNull String password) {
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,34 +161,34 @@ public class User
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthenticationTypeCode(Character authenticationTypeCode) {
|
public void setAuthenticationTypeCode(Character authenticationTypeCode) {
|
||||||
this.authenticationTypeCode = authenticationTypeCode;
|
this.authenticationTypeCode = authenticationTypeCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getGoogleSync() {
|
public Boolean getGoogleSync() {
|
||||||
return googleSync;
|
return googleSync != null && googleSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGoogleSync(Boolean googleSync) {
|
public void setGoogleSync(Boolean googleSync) {
|
||||||
this.googleSync = googleSync;
|
this.googleSync = googleSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSyncCode() {
|
|
||||||
return syncCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSyncCode(String syncCode) {
|
|
||||||
this.syncCode = syncCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGoogleToken() {
|
public String getSyncCode() {
|
||||||
return googleToken;
|
return syncCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGoogleToken(String googleToken) {
|
public void setSyncCode(String syncCode) {
|
||||||
this.googleToken = googleToken;
|
this.syncCode = syncCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String getGoogleToken() {
|
||||||
|
return googleToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoogleToken(String googleToken) {
|
||||||
|
this.googleToken = googleToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "User{" +
|
return "User{" +
|
||||||
"firstname='" + firstname + '\'' +
|
"firstname='" + firstname + '\'' +
|
|
@ -21,8 +21,8 @@ package com.wisemapping.model;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class Collaboration implements Serializable {
|
||||||
private Mindmap mindMap;
|
private Mindmap mindMap;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "colaborator_id", nullable = false)
|
@JoinColumn(name = "collaborator_id", nullable = false)
|
||||||
private Collaborator collaborator;
|
private Collaborator collaborator;
|
||||||
|
|
||||||
@ManyToOne(cascade = CascadeType.ALL)
|
@ManyToOne(cascade = CascadeType.ALL)
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
|
@ -22,7 +22,7 @@ import com.wisemapping.util.ZipUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public class MindMapHistory {
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "editor_id", nullable = true,unique = false)
|
@JoinColumn(name = "editor_id", nullable = true,unique = false)
|
||||||
private User editor;
|
private Account editor;
|
||||||
|
|
||||||
@Column(name = "xml")
|
@Column(name = "xml")
|
||||||
private byte[] zippedXml;
|
private byte[] zippedXml;
|
||||||
|
@ -76,11 +76,11 @@ public class MindMapHistory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public User getEditor() {
|
public Account getEditor() {
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEditor(@Nullable User editor) {
|
public void setEditor(@Nullable Account editor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import com.wisemapping.exceptions.AccessDeniedSecurityException;
|
||||||
import com.wisemapping.exceptions.InvalidMindmapException;
|
import com.wisemapping.exceptions.InvalidMindmapException;
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.util.ZipUtils;
|
import com.wisemapping.util.ZipUtils;
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
|
||||||
import org.hibernate.annotations.Fetch;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
import org.hibernate.annotations.NotFound;
|
import org.hibernate.annotations.NotFound;
|
||||||
|
@ -30,7 +29,8 @@ import org.hibernate.annotations.NotFoundAction;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -51,14 +51,14 @@ public class Mindmap implements Serializable {
|
||||||
@Column(name = "edition_date")
|
@Column(name = "edition_date")
|
||||||
private Calendar lastModificationTime;
|
private Calendar lastModificationTime;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
@JoinColumn(name = "creator_id", unique = true)
|
@JoinColumn(name = "creator_id", unique = true)
|
||||||
private User creator;
|
private Account creator;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne
|
||||||
@JoinColumn(name = "last_editor_id", nullable = false)
|
@JoinColumn(name = "last_editor_id", nullable = false)
|
||||||
@NotFound(action = NotFoundAction.IGNORE)
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
private User lastEditor;
|
private Account lastEditor;
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ public class Mindmap implements Serializable {
|
||||||
name = "R_LABEL_MINDMAP",
|
name = "R_LABEL_MINDMAP",
|
||||||
joinColumns = @JoinColumn(name = "mindmap_id"),
|
joinColumns = @JoinColumn(name = "mindmap_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "label_id"))
|
inverseJoinColumns = @JoinColumn(name = "label_id"))
|
||||||
private Set<Label> labels = new LinkedHashSet<>();
|
private Set<MindmapLabel> labels = new LinkedHashSet<>();
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
|
@ -152,15 +152,15 @@ public class Mindmap implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<Label> getLabels() {
|
public Set<MindmapLabel> getLabels() {
|
||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLabels(@NotNull final Set<Label> labels) {
|
public void setLabels(@NotNull final Set<MindmapLabel> labels) {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLabel(@NotNull final Label label) {
|
public void addLabel(@NotNull final MindmapLabel label) {
|
||||||
this.labels.add(label);
|
this.labels.add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ public class Mindmap implements Serializable {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCreator(@NotNull User user) {
|
public boolean isCreator(@NotNull Account user) {
|
||||||
return this.getCreator() != null && this.getCreator().identityEquality(user);
|
return this.getCreator() != null && this.getCreator().identityEquality(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,11 +205,11 @@ public class Mindmap implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public User getLastEditor() {
|
public Account getLastEditor() {
|
||||||
return lastEditor;
|
return lastEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastEditor(@Nullable User lastEditor) {
|
public void setLastEditor(@Nullable Account lastEditor) {
|
||||||
this.lastEditor = lastEditor;
|
this.lastEditor = lastEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,11 +263,11 @@ public class Mindmap implements Serializable {
|
||||||
this.creationTime = creationTime;
|
this.creationTime = creationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreator(@NotNull User creator) {
|
public void setCreator(@NotNull Account creator) {
|
||||||
this.creator = creator;
|
this.creator = creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getCreator() {
|
public Account getCreator() {
|
||||||
return creator;
|
return creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,13 +310,10 @@ public class Mindmap implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDefaultMindmapXml(@NotNull final String title) {
|
public static String getDefaultMindmapXml(@NotNull final String title) {
|
||||||
|
return "<map version=\"tango\" theme=\"prism\">" +
|
||||||
final StringBuilder result = new StringBuilder();
|
"<topic central=\"true\" text=\"" +
|
||||||
result.append("<map version=\"tango\">");
|
escapeXmlAttribute(title) +
|
||||||
result.append("<topic central=\"true\" text=\"");
|
"\"/></map>";
|
||||||
result.append(escapeXmlAttribute(title));
|
|
||||||
result.append("\"/></map>");
|
|
||||||
return result.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static private String escapeXmlAttribute(String attValue) {
|
static private String escapeXmlAttribute(String attValue) {
|
||||||
|
@ -350,7 +347,7 @@ public class Mindmap implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasLabel(@NotNull final String name) {
|
public boolean hasLabel(@NotNull final String name) {
|
||||||
for (Label label : this.labels) {
|
for (MindmapLabel label : this.labels) {
|
||||||
if (label.getTitle().equals(name)) {
|
if (label.getTitle().equals(name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +355,7 @@ public class Mindmap implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLabel(@NotNull final Label label) {
|
public void removeLabel(@NotNull final MindmapLabel label) {
|
||||||
this.labels.remove(label);
|
this.labels.remove(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,15 +22,15 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "LABEL")
|
@Table(name = "MINDMAP_LABEL")
|
||||||
@Cacheable
|
@Cacheable
|
||||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||||
public class Label implements Serializable {
|
public class MindmapLabel implements Serializable {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private int id;
|
private int id;
|
||||||
|
@ -39,34 +39,32 @@ public class Label implements Serializable {
|
||||||
private String title;
|
private String title;
|
||||||
@NotNull
|
@NotNull
|
||||||
private String color;
|
private String color;
|
||||||
@Nullable
|
|
||||||
private String iconName;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "creator_id", nullable = true, unique = true)
|
@JoinColumn(name = "creator_id", nullable = true, unique = true)
|
||||||
@NotNull
|
@NotNull
|
||||||
private User creator;
|
private Account creator;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "parent_label_id", nullable = true)
|
@JoinColumn(name = "parent_label_id", nullable = true)
|
||||||
@Nullable
|
@Nullable
|
||||||
private Label parent;
|
private MindmapLabel parent;
|
||||||
|
|
||||||
public void setParent(@Nullable Label parent) {
|
public void setParent(@Nullable MindmapLabel parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Label getParent() {
|
public MindmapLabel getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreator(@NotNull User creator) {
|
public void setCreator(@NotNull Account creator) {
|
||||||
this.creator = creator;
|
this.creator = creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public User getCreator() {
|
public Account getCreator() {
|
||||||
return creator;
|
return creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +73,7 @@ public class Label implements Serializable {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle(@NotNull String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,30 +85,22 @@ public class Label implements Serializable {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
public String getColor() {
|
public String getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColor(@NotNull String color) {
|
public void setColor(String color) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getIconName() {
|
|
||||||
return iconName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIconName(@NotNull String iconName) {
|
|
||||||
this.iconName = iconName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (!(o instanceof Label)) return false;
|
if (!(o instanceof MindmapLabel)) return false;
|
||||||
|
|
||||||
final Label label = (Label) o;
|
final MindmapLabel label = (MindmapLabel) o;
|
||||||
return id == label.id && creator.getId() == label.creator.getId()
|
return id == label.id && creator.getId() == label.creator.getId()
|
||||||
&& Objects.equals(parent, label.parent);
|
&& Objects.equals(parent, label.parent);
|
||||||
}
|
}
|
|
@ -18,11 +18,12 @@
|
||||||
|
|
||||||
package com.wisemapping.rest;
|
package com.wisemapping.rest;
|
||||||
|
|
||||||
|
import com.wisemapping.exceptions.PasswordTooLongException;
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.model.Collaboration;
|
import com.wisemapping.model.Collaboration;
|
||||||
import com.wisemapping.model.Label;
|
import com.wisemapping.model.MindmapLabel;
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.rest.model.RestUser;
|
import com.wisemapping.rest.model.RestUser;
|
||||||
import com.wisemapping.security.Utils;
|
import com.wisemapping.security.Utils;
|
||||||
import com.wisemapping.service.LabelService;
|
import com.wisemapping.service.LabelService;
|
||||||
|
@ -31,15 +32,14 @@ import com.wisemapping.service.UserService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/account")
|
||||||
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
public class AccountController extends BaseController {
|
public class AccountController extends BaseController {
|
||||||
@Qualifier("userService")
|
@Qualifier("userService")
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -53,49 +53,53 @@ public class AccountController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private LabelService labelService;
|
private LabelService labelService;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "account/password", consumes = {"text/plain"})
|
@RequestMapping(method = RequestMethod.PUT, value = "/password", consumes = {"text/plain"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void changePassword(@RequestBody String password) {
|
public void changePassword(@RequestBody String password) throws PasswordTooLongException {
|
||||||
if (password == null) {
|
if (password == null) {
|
||||||
throw new IllegalArgumentException("Password can not be null");
|
throw new IllegalArgumentException("Password can not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
final User user = Utils.getUser(true);
|
if (password.length() > Account.MAX_PASSWORD_LENGTH_SIZE) {
|
||||||
|
throw new PasswordTooLongException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Account user = Utils.getUser(true);
|
||||||
user.setPassword(password);
|
user.setPassword(password);
|
||||||
userService.changePassword(user);
|
userService.changePassword(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/account", produces = {"application/json"})
|
@RequestMapping(method = RequestMethod.GET, value = "", produces = {"application/json"})
|
||||||
public RestUser fetchAccount() {
|
public RestUser fetchAccount() {
|
||||||
final User user = Utils.getUser(true);
|
final Account user = Utils.getUser(true);
|
||||||
return new RestUser(user);
|
return new RestUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "account/firstname", consumes = {"text/plain"})
|
@RequestMapping(method = RequestMethod.PUT, value = "/firstname", consumes = {"text/plain"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void changeFirstname(@RequestBody String firstname) {
|
public void changeFirstname(@RequestBody String firstname) {
|
||||||
if (firstname == null) {
|
if (firstname == null) {
|
||||||
throw new IllegalArgumentException("Firstname can not be null");
|
throw new IllegalArgumentException("Firstname can not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
final User user = Utils.getUser(true);
|
final Account user = Utils.getUser(true);
|
||||||
user.setFirstname(firstname);
|
user.setFirstname(firstname);
|
||||||
userService.updateUser(user);
|
userService.updateUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "account/lastname", consumes = {"text/plain"})
|
@RequestMapping(method = RequestMethod.PUT, value = "/lastname", consumes = {"text/plain"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void changeLastName(@RequestBody String lastname) {
|
public void changeLastName(@RequestBody String lastname) {
|
||||||
if (lastname == null) {
|
if (lastname == null) {
|
||||||
throw new IllegalArgumentException("lastname can not be null");
|
throw new IllegalArgumentException("lastname can not be null");
|
||||||
|
|
||||||
}
|
}
|
||||||
final User user = Utils.getUser(true);
|
final Account user = Utils.getUser(true);
|
||||||
user.setLastname(lastname);
|
user.setLastname(lastname);
|
||||||
userService.updateUser(user);
|
userService.updateUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "account/locale", consumes = {"text/plain"})
|
@RequestMapping(method = RequestMethod.PUT, value = "/locale", consumes = {"text/plain"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void changeLanguage(@RequestBody String language) {
|
public void changeLanguage(@RequestBody String language) {
|
||||||
if (language == null) {
|
if (language == null) {
|
||||||
|
@ -103,16 +107,16 @@ public class AccountController extends BaseController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final User user = Utils.getUser(true);
|
final Account user = Utils.getUser(true);
|
||||||
user.setLocale(language);
|
user.setLocale(language);
|
||||||
userService.updateUser(user);
|
userService.updateUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "account")
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
|
@RequestMapping(method = RequestMethod.DELETE, value = "")
|
||||||
public void deleteUser() throws WiseMappingException {
|
public void deleteUser() throws WiseMappingException {
|
||||||
// Delete collaborations ...
|
// Delete collaborations ...
|
||||||
final User user = Utils.getUser(true);
|
final Account user = Utils.getUser(true);
|
||||||
final List<Collaboration> collaborations = mindmapService.findCollaborations(user);
|
final List<Collaboration> collaborations = mindmapService.findCollaborations(user);
|
||||||
for (Collaboration collaboration : collaborations) {
|
for (Collaboration collaboration : collaborations) {
|
||||||
final Mindmap mindmap = collaboration.getMindMap();
|
final Mindmap mindmap = collaboration.getMindMap();
|
||||||
|
@ -120,7 +124,7 @@ public class AccountController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete labels ....
|
// Delete labels ....
|
||||||
final List<Label> labels = labelService.getAll(user);
|
final List<MindmapLabel> labels = labelService.getAll(user);
|
||||||
labels.forEach(l -> {
|
labels.forEach(l -> {
|
||||||
try {
|
try {
|
||||||
labelService.removeLabel(l, user);
|
labelService.removeLabel(l, user);
|
|
@ -22,22 +22,22 @@ import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.model.AuthenticationType;
|
import com.wisemapping.model.AuthenticationType;
|
||||||
import com.wisemapping.model.Collaboration;
|
import com.wisemapping.model.Collaboration;
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.rest.model.RestUser;
|
import com.wisemapping.rest.model.RestUser;
|
||||||
import com.wisemapping.service.MindmapService;
|
import com.wisemapping.service.MindmapService;
|
||||||
import com.wisemapping.service.UserService;
|
import com.wisemapping.service.UserService;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/admin")
|
||||||
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_ADMIN')")
|
||||||
public class AdminController extends BaseController {
|
public class AdminController extends BaseController {
|
||||||
@Qualifier("userService")
|
@Qualifier("userService")
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -47,29 +47,29 @@ public class AdminController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private MindmapService mindmapService;
|
private MindmapService mindmapService;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "admin/users/{id}", produces = {"application/json"})
|
@RequestMapping(method = RequestMethod.GET, value = "/users/{id}", produces = {"application/json"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestUser getUserById(@PathVariable int id) throws IOException {
|
public RestUser getUserById(@PathVariable int id) {
|
||||||
final User userBy = userService.getUserBy(id);
|
final Account userBy = userService.getUserBy(id);
|
||||||
if (userBy == null) {
|
if (userBy == null) {
|
||||||
throw new IllegalArgumentException("User could not be found");
|
throw new IllegalArgumentException("User could not be found");
|
||||||
}
|
}
|
||||||
return new RestUser(userBy);
|
return new RestUser(userBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "admin/users/email/{email:.+}", produces = {"application/json"})
|
@RequestMapping(method = RequestMethod.GET, value = "/users/email/{email:.+}", produces = {"application/json"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestUser getUserByEmail(@PathVariable String email) throws IOException {
|
public RestUser getUserByEmail(@PathVariable String email) {
|
||||||
final User user = userService.getUserBy(email);
|
final Account user = userService.getUserBy(email);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException("User '" + email + "' could not be found");
|
throw new IllegalArgumentException("User '" + email + "' could not be found");
|
||||||
}
|
}
|
||||||
return new RestUser(user);
|
return new RestUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "admin/users", consumes = {"application/json"}, produces = {"application/json"})
|
@RequestMapping(method = RequestMethod.POST, value = "/users", consumes = {"application/json"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.CREATED)
|
@ResponseStatus(value = HttpStatus.CREATED)
|
||||||
public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws WiseMappingException {
|
public void createUser(@RequestBody RestUser user, final HttpServletResponse response) throws WiseMappingException {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException("User could not be found");
|
throw new IllegalArgumentException("User could not be found");
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ public class AdminController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run some other validations ...
|
// Run some other validations ...
|
||||||
final User delegated = user.getDelegated();
|
final Account delegated = user.getDelegated();
|
||||||
final String lastname = delegated.getLastname();
|
final String lastname = delegated.getLastname();
|
||||||
if (lastname == null || lastname.isEmpty()) {
|
if (lastname == null || lastname.isEmpty()) {
|
||||||
throw new IllegalArgumentException("lastname can not be null");
|
throw new IllegalArgumentException("lastname can not be null");
|
||||||
|
@ -101,17 +101,17 @@ public class AdminController extends BaseController {
|
||||||
// Finally create the user ...
|
// Finally create the user ...
|
||||||
delegated.setAuthenticationType(AuthenticationType.DATABASE);
|
delegated.setAuthenticationType(AuthenticationType.DATABASE);
|
||||||
userService.createUser(delegated, false, true);
|
userService.createUser(delegated, false, true);
|
||||||
response.setHeader("Location", "/service/admin/users/" + user.getId());
|
response.setHeader("Location", "/api/restful/admin/users/" + user.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "admin/users/{id}/password", consumes = {"text/plain"})
|
@RequestMapping(method = RequestMethod.PUT, value = "/users/{id}/password", consumes = {"text/plain"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void changePassword(@RequestBody String password, @PathVariable int id) throws WiseMappingException {
|
public void changePassword(@RequestBody String password, @PathVariable int id) {
|
||||||
if (password == null) {
|
if (password == null) {
|
||||||
throw new IllegalArgumentException("Password can not be null");
|
throw new IllegalArgumentException("Password can not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
final User user = userService.getUserBy(id);
|
final Account user = userService.getUserBy(id);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException("User '" + id + "' could not be found");
|
throw new IllegalArgumentException("User '" + id + "' could not be found");
|
||||||
}
|
}
|
||||||
|
@ -119,10 +119,10 @@ public class AdminController extends BaseController {
|
||||||
userService.changePassword(user);
|
userService.changePassword(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "admin/users/{id}")
|
@RequestMapping(method = RequestMethod.DELETE, value = "/users/{id}")
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void deleteUserByEmail(@PathVariable int id) throws WiseMappingException {
|
public void deleteUserByEmail(@PathVariable int id) throws WiseMappingException {
|
||||||
final User user = userService.getUserBy(id);
|
final Account user = userService.getUserBy(id);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException("User '" + id + "' could not be found");
|
throw new IllegalArgumentException("User '" + id + "' could not be found");
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,6 @@ public class AdminController extends BaseController {
|
||||||
final Mindmap mindmap = collaboration.getMindMap();
|
final Mindmap mindmap = collaboration.getMindMap();
|
||||||
mindmapService.removeMindmap(mindmap, user);
|
mindmapService.removeMindmap(mindmap, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
userService.removeUser(user);
|
userService.removeUser(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import com.wisemapping.rest.model.RestAppConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/app")
|
||||||
|
public class AppController extends BaseController {
|
||||||
|
|
||||||
|
@Value("${app.security.oauth2.google.url:}")
|
||||||
|
private String googleOauth2Url;
|
||||||
|
|
||||||
|
@Value("${app.registration.enabled:true}")
|
||||||
|
private Boolean isRegistrationEnabled;
|
||||||
|
|
||||||
|
@Value("${app.registration.captcha.enabled:false}")
|
||||||
|
private Boolean isCaptchaEnabled;
|
||||||
|
|
||||||
|
@Value("${app.registration.captcha.siteKey:}")
|
||||||
|
private String captchaSiteKey;
|
||||||
|
|
||||||
|
@Value("${app.site.api-base-url:}")
|
||||||
|
private String apiBaseUrl;
|
||||||
|
|
||||||
|
@Value("${app.site.ui-base-url:}")
|
||||||
|
private String uiBaseUrl;
|
||||||
|
|
||||||
|
@Value("${app.analytics.account:}")
|
||||||
|
private String analyticsAccount;
|
||||||
|
|
||||||
|
@Value("${app.jwt.expirationMin:10080}")
|
||||||
|
private int jwtExpirationMin;
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/config")
|
||||||
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
public RestAppConfig appConfig() {
|
||||||
|
return new RestAppConfig.RestAppConfigBuilder()
|
||||||
|
.setApiUrl(apiBaseUrl)
|
||||||
|
.setUiUrl(uiBaseUrl)
|
||||||
|
.setCaptchaSiteKey(captchaSiteKey)
|
||||||
|
.setGoogleOauth2Url(googleOauth2Url)
|
||||||
|
.setAnalyticsAccount(analyticsAccount)
|
||||||
|
.setRegistrationEnabled(isRegistrationEnabled)
|
||||||
|
.setJwtExpirationMin(jwtExpirationMin)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGoogleOauth2Url() {
|
||||||
|
return googleOauth2Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoogleOauth2Url(String googleOauth2Url) {
|
||||||
|
this.googleOauth2Url = googleOauth2Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getRegistrationEnabled() {
|
||||||
|
return isRegistrationEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegistrationEnabled(Boolean registrationEnabled) {
|
||||||
|
isRegistrationEnabled = registrationEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getCaptchaEnabled() {
|
||||||
|
return isCaptchaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCaptchaEnabled(Boolean captchaEnabled) {
|
||||||
|
isCaptchaEnabled = captchaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCaptchaSiteKey() {
|
||||||
|
return captchaSiteKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCaptchaSiteKey(String captchaSiteKey) {
|
||||||
|
this.captchaSiteKey = captchaSiteKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiBaseUrl() {
|
||||||
|
return apiBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiBaseUrl(String apiBaseUrl) {
|
||||||
|
this.apiBaseUrl = apiBaseUrl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,13 +17,15 @@
|
||||||
*/
|
*/
|
||||||
package com.wisemapping.rest;
|
package com.wisemapping.rest;
|
||||||
|
|
||||||
import com.wisemapping.exceptions.ClientException;
|
import com.wisemapping.exceptions.*;
|
||||||
import com.wisemapping.exceptions.Severity;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.mail.NotificationService;
|
|
||||||
import com.wisemapping.model.User;
|
|
||||||
import com.wisemapping.rest.model.RestErrors;
|
import com.wisemapping.rest.model.RestErrors;
|
||||||
import com.wisemapping.security.Utils;
|
import com.wisemapping.security.Utils;
|
||||||
|
import com.wisemapping.service.NotificationService;
|
||||||
import com.wisemapping.service.RegistrationException;
|
import com.wisemapping.service.RegistrationException;
|
||||||
|
import jakarta.servlet.ServletContext;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -32,12 +34,11 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -50,34 +51,40 @@ public class BaseController {
|
||||||
private ResourceBundleMessageSource messageSource;
|
private ResourceBundleMessageSource messageSource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
ServletContext context;
|
private ServletContext context;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NotificationService notificationService;
|
|
||||||
|
|
||||||
@ExceptionHandler(IllegalArgumentException.class)
|
@ExceptionHandler(IllegalArgumentException.class)
|
||||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestErrors handleClientErrors(@NotNull IllegalArgumentException ex) {
|
public RestErrors handleClientErrors(@NotNull IllegalArgumentException ex) {
|
||||||
logger.error(ex.getMessage(), ex);
|
|
||||||
return new RestErrors(ex.getMessage(), Severity.WARNING);
|
return new RestErrors(ex.getMessage(), Severity.WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(AuthenticationCredentialsNotFoundException.class)
|
||||||
|
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||||
|
public RestErrors handleAuthException(@NotNull final AuthenticationCredentialsNotFoundException ex) {
|
||||||
|
logger.debug(ex.getMessage(), ex);
|
||||||
|
return new RestErrors("Authentication exception. Session must be expired. Try logging again.", Severity.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
@ExceptionHandler(ValidationException.class)
|
@ExceptionHandler(ValidationException.class)
|
||||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
public RestErrors handleValidationErrors(@NotNull ValidationException ex) {
|
public RestErrors handleValidationErrors(@NotNull final ValidationException ex) {
|
||||||
|
logger.debug(ex.getMessage(), ex);
|
||||||
return new RestErrors(ex.getErrors(), messageSource);
|
return new RestErrors(ex.getErrors(), messageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(JsonHttpMessageNotReadableException.class)
|
@ExceptionHandler(JsonHttpMessageNotReadableException.class)
|
||||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
public RestErrors handleJSONErrors(@NotNull JsonHttpMessageNotReadableException ex) {
|
public RestErrors handleJSONErrors(@NotNull JsonHttpMessageNotReadableException ex) {
|
||||||
|
logger.error(ex.getMessage(), ex);
|
||||||
return new RestErrors("Communication error", Severity.SEVERE);
|
return new RestErrors("Communication error", Severity.SEVERE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(java.lang.reflect.UndeclaredThrowableException.class)
|
@ExceptionHandler(java.lang.reflect.UndeclaredThrowableException.class)
|
||||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
public RestErrors handleSecurityErrors(@NotNull UndeclaredThrowableException ex) {
|
public RestErrors handleSecurityErrors(@NotNull UndeclaredThrowableException ex) {
|
||||||
|
logger.error(ex.getMessage(), ex);
|
||||||
final Throwable cause = ex.getCause();
|
final Throwable cause = ex.getCause();
|
||||||
RestErrors result;
|
RestErrors result;
|
||||||
if (cause instanceof ClientException) {
|
if (cause instanceof ClientException) {
|
||||||
|
@ -95,21 +102,41 @@ public class BaseController {
|
||||||
return new RestErrors(ex.getMessage(messageSource, locale), ex.getSeverity(), ex.getTechInfo());
|
return new RestErrors(ex.getMessage(messageSource, locale), ex.getSeverity(), ex.getTechInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ExceptionHandler(AccessDeniedSecurityException.class)
|
||||||
|
@ResponseBody
|
||||||
|
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||||
|
public RestErrors handleAccessDeniedSecurityException(@NotNull AccessDeniedSecurityException ex) {
|
||||||
|
return new RestErrors(ex.getMessage(), ex.getSeverity(), ex.getTechInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(OAuthAuthenticationException.class)
|
||||||
|
@ResponseBody
|
||||||
|
public OAuthAuthenticationException handleOAuthErrors(@NotNull OAuthAuthenticationException ex, HttpServletResponse response) {
|
||||||
|
// @todo: Further research needed for this error. No clear why this happens.
|
||||||
|
// Caused by: com.wisemapping.service.http.HttpInvokerException: error invoking https://oauth2.googleapis.com/token, response: {
|
||||||
|
// "error": "invalid_grant",
|
||||||
|
// "error_description": "Bad Request"
|
||||||
|
//}, status: 400
|
||||||
|
//
|
||||||
|
logger.error(ex.getMessage(), ex);
|
||||||
|
response.setStatus(response.getStatus());
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestErrors handleServerErrors(@NotNull Exception ex, @NotNull HttpServletRequest request) {
|
public RestErrors handleServerErrors(@NotNull Exception ex, @NotNull HttpServletRequest request) {
|
||||||
final User user = Utils.getUser(false);
|
logger.error(ex.getMessage(), ex);
|
||||||
notificationService.reportJavaException(ex, user, request);
|
final Account user = Utils.getUser(false);
|
||||||
logger.error(ex);
|
|
||||||
|
|
||||||
return new RestErrors(ex.getMessage(), Severity.SEVERE);
|
return new RestErrors(ex.getMessage(), Severity.SEVERE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(RegistrationException.class)
|
@ExceptionHandler(RegistrationException.class)
|
||||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestErrors handleRegistrationErrors(@NotNull RegistrationException exception) {
|
public RestErrors handleRegistrationErrors(@NotNull RegistrationException ex) {
|
||||||
return new RestErrors(exception, messageSource);
|
return new RestErrors(ex, messageSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
|
import com.wisemapping.rest.model.RestJwtUser;
|
||||||
|
import com.wisemapping.security.JwtTokenUtil;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.DisabledException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/restful")
|
||||||
|
public class JwtAuthController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
|
|
||||||
|
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
|
||||||
|
public ResponseEntity<String> createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws WiseMappingException {
|
||||||
|
// Is a valid user ?
|
||||||
|
authenticate(user.getEmail(), user.getPassword());
|
||||||
|
final String result = jwtTokenUtil.doLogin(response, user.getEmail());
|
||||||
|
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void authenticate(@NotNull String username, @NotNull String password) throws WiseMappingException {
|
||||||
|
try {
|
||||||
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
|
||||||
|
} catch (DisabledException | BadCredentialsException e) {
|
||||||
|
throw new WiseMappingException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,35 +18,37 @@
|
||||||
package com.wisemapping.rest;
|
package com.wisemapping.rest;
|
||||||
|
|
||||||
import com.wisemapping.exceptions.LabelCouldNotFoundException;
|
import com.wisemapping.exceptions.LabelCouldNotFoundException;
|
||||||
|
import com.wisemapping.exceptions.ValidationException;
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.model.Label;
|
import com.wisemapping.model.MindmapLabel;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.rest.model.RestLabel;
|
import com.wisemapping.rest.model.RestLabel;
|
||||||
import com.wisemapping.rest.model.RestLabelList;
|
import com.wisemapping.rest.model.RestLabelList;
|
||||||
import com.wisemapping.security.Utils;
|
import com.wisemapping.security.Utils;
|
||||||
import com.wisemapping.service.LabelService;
|
import com.wisemapping.service.LabelService;
|
||||||
import com.wisemapping.validator.LabelValidator;
|
import com.wisemapping.validator.LabelValidator;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/labels")
|
||||||
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
public class LabelController extends BaseController {
|
public class LabelController extends BaseController {
|
||||||
|
|
||||||
@Qualifier("labelService")
|
@Qualifier("labelService")
|
||||||
@Autowired
|
@Autowired
|
||||||
private LabelService labelService;
|
private LabelService labelService;
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "", consumes = {"application/json"})
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/labels", consumes = {"application/json"})
|
|
||||||
@ResponseStatus(value = HttpStatus.CREATED)
|
@ResponseStatus(value = HttpStatus.CREATED)
|
||||||
public void createLabel(@RequestBody RestLabel restLabel, @NotNull HttpServletResponse response, @RequestParam(required = false) String title) throws WiseMappingException {
|
public void createLabel(@RequestBody RestLabel restLabel, @NotNull HttpServletResponse response, @RequestParam(required = false) String title) throws WiseMappingException {
|
||||||
// Overwrite title if it was specified by parameter.
|
// Overwrite title if it was specified by parameter.
|
||||||
|
@ -57,26 +59,26 @@ public class LabelController extends BaseController {
|
||||||
// Validate ...
|
// Validate ...
|
||||||
validate(restLabel);
|
validate(restLabel);
|
||||||
|
|
||||||
final Label label = createLabel(restLabel);
|
final MindmapLabel label = createLabel(restLabel);
|
||||||
|
|
||||||
// Return the new created label ...
|
// Return the new created label ...
|
||||||
response.setHeader("Location", "/service/labels/" + label.getId());
|
response.setHeader("Location", "/api/restful/labels/" + label.getId());
|
||||||
response.setHeader("ResourceId", Long.toString(label.getId()));
|
response.setHeader("ResourceId", Long.toString(label.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/labels", produces = {"application/json"})
|
@RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"})
|
||||||
public RestLabelList retrieveList() {
|
public RestLabelList retrieveList() {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
assert user != null;
|
assert user != null;
|
||||||
final List<Label> all = labelService.getAll(user);
|
final List<MindmapLabel> all = labelService.getAll(user);
|
||||||
return new RestLabelList(all);
|
return new RestLabelList(all);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "/labels/{id}")
|
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void deleteLabelById(@PathVariable int id) throws WiseMappingException {
|
public void deleteLabelById(@PathVariable int id) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
final Label label = labelService.findLabelById(id, user);
|
final MindmapLabel label = labelService.findLabelById(id, user);
|
||||||
if (label == null) {
|
if (label == null) {
|
||||||
throw new LabelCouldNotFoundException("Label could not be found. Id: " + id);
|
throw new LabelCouldNotFoundException("Label could not be found. Id: " + id);
|
||||||
}
|
}
|
||||||
|
@ -84,10 +86,10 @@ public class LabelController extends BaseController {
|
||||||
labelService.removeLabel(label, user);
|
labelService.removeLabel(label, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Label createLabel(@NotNull final RestLabel restLabel) throws WiseMappingException {
|
@NotNull private MindmapLabel createLabel(@NotNull final RestLabel restLabel) throws WiseMappingException {
|
||||||
final Label label = restLabel.getDelegated();
|
final MindmapLabel label = restLabel.getDelegated();
|
||||||
// Add new label ...
|
// Add new label ...
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
assert user != null;
|
assert user != null;
|
||||||
labelService.addLabel(label, user);
|
labelService.addLabel(label, user);
|
||||||
return label;
|
return label;
|
|
@ -24,6 +24,8 @@ import com.wisemapping.rest.model.*;
|
||||||
import com.wisemapping.security.Utils;
|
import com.wisemapping.security.Utils;
|
||||||
import com.wisemapping.service.*;
|
import com.wisemapping.service.*;
|
||||||
import com.wisemapping.validator.MapInfoValidator;
|
import com.wisemapping.validator.MapInfoValidator;
|
||||||
|
import com.wisemapping.view.MindMapBean;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.apache.commons.validator.routines.EmailValidator;
|
import org.apache.commons.validator.routines.EmailValidator;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
@ -33,21 +35,21 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@Controller
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/maps")
|
||||||
public class MindmapController extends BaseController {
|
public class MindmapController extends BaseController {
|
||||||
final Logger logger = LogManager.getLogger();
|
private final Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
private static final String LATEST_HISTORY_REVISION = "latest";
|
private static final String LATEST_HISTORY_REVISION = "latest";
|
||||||
|
|
||||||
|
@ -63,32 +65,56 @@ public class MindmapController extends BaseController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@Value("${accounts.maxInactive:20}")
|
@Value("${app.accounts.max-inactive:20}")
|
||||||
private int maxAccountsInactive;
|
private int maxAccountsInactive;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}", produces = {"application/json"})
|
|
||||||
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException {
|
public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser(true);
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
return new RestMindmap(mindMap, user);
|
return new RestMindmap(mindMap, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/maps/", produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/{id}/metadata", produces = {"application/json"})
|
||||||
|
@ResponseBody
|
||||||
|
public RestMindmapMetadata retrieveMetadata(@PathVariable int id) throws WiseMappingException {
|
||||||
|
final Account user = Utils.getUser(true);
|
||||||
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
|
final MindMapBean mindMapBean = new MindMapBean(mindmap, user);
|
||||||
|
|
||||||
|
// Is the mindmap locked ?.
|
||||||
|
boolean isLocked = false;
|
||||||
|
final LockManager lockManager = this.mindmapService.getLockManager();
|
||||||
|
String lockFullName = null;
|
||||||
|
if (lockManager.isLocked(mindmap) && !lockManager.isLockedBy(mindmap, user)) {
|
||||||
|
final LockInfo lockInfo = lockManager.getLockInfo(mindmap);
|
||||||
|
isLocked = true;
|
||||||
|
lockFullName = lockInfo.getUser().getFullName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RestMindmapMetadata(mindmap.getTitle(), mindMapBean.getProperties(), mindmap.getCreator().getFullName(), isLocked, lockFullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"})
|
||||||
public RestMindmapList retrieveList(@RequestParam(required = false) String q) {
|
public RestMindmapList retrieveList(@RequestParam(required = false) String q) {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser(true);
|
||||||
|
|
||||||
final MindmapFilter filter = MindmapFilter.parse(q);
|
final MindmapFilter filter = MindmapFilter.parse(q);
|
||||||
List<Mindmap> mindmaps = mindmapService.findMindmapsByUser(user);
|
List<Mindmap> mindmaps = mindmapService.findMindmapsByUser(user);
|
||||||
mindmaps = mindmaps
|
mindmaps = mindmaps
|
||||||
.stream()
|
.stream()
|
||||||
.filter(m -> filter.accept(m, user))
|
.filter(m -> filter.accept(m, user)).toList();
|
||||||
.collect(Collectors.toUnmodifiableList());
|
|
||||||
|
|
||||||
return new RestMindmapList(mindmaps, user);
|
return new RestMindmapList(mindmaps, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}/history/", produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/{id}/history/", produces = {"application/json"})
|
||||||
public RestMindmapHistoryList fetchHistory(@PathVariable int id) {
|
public RestMindmapHistoryList fetchHistory(@PathVariable int id) {
|
||||||
final List<MindMapHistory> histories = mindmapService.findMindmapHistory(id);
|
final List<MindMapHistory> histories = mindmapService.findMindmapHistory(id);
|
||||||
final RestMindmapHistoryList result = new RestMindmapHistoryList();
|
final RestMindmapHistoryList result = new RestMindmapHistoryList();
|
||||||
|
@ -98,31 +124,13 @@ public class MindmapController extends BaseController {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/maps/{id}/history/{hid}", method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/document", consumes = {"application/json"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
|
||||||
public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException, IOException {
|
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
|
||||||
final User user = Utils.getUser();
|
|
||||||
|
|
||||||
if (LATEST_HISTORY_REVISION.equals(hid)) {
|
|
||||||
// Revert to the latest stored version ...
|
|
||||||
List<MindMapHistory> mindmapHistory = mindmapService.findMindmapHistory(id);
|
|
||||||
if (mindmapHistory.size() > 0) {
|
|
||||||
final MindMapHistory mindMapHistory = mindmapHistory.get(0);
|
|
||||||
mindmap.setZippedXml(mindMapHistory.getZippedXml());
|
|
||||||
saveMindmapDocument(true, mindmap, user);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mindmapService.revertChange(mindmap, Integer.parseInt(hid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/document", consumes = {"application/json"}, produces = {"application/json"})
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
public void updateDocument(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws WiseMappingException, IOException {
|
public void updateDocument(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws WiseMappingException, IOException {
|
||||||
|
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser(true);
|
||||||
|
|
||||||
// Validate arguments ...
|
// Validate arguments ...
|
||||||
final String properties = restMindmap.getProperties();
|
final String properties = restMindmap.getProperties();
|
||||||
|
@ -146,7 +154,28 @@ public class MindmapController extends BaseController {
|
||||||
saveMindmapDocument(minor, mindmap, user);
|
saveMindmapDocument(minor, mindmap, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = {"/maps/{id}/document/xml", "/maps/{id}/document/xml-pub"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(value = "/{id}/history/{hid}", method = RequestMethod.POST)
|
||||||
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
|
public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException, IOException {
|
||||||
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
|
final Account user = Utils.getUser(true);
|
||||||
|
|
||||||
|
if (LATEST_HISTORY_REVISION.equals(hid)) {
|
||||||
|
// Revert to the latest stored version ...
|
||||||
|
List<MindMapHistory> mindmapHistory = mindmapService.findMindmapHistory(id);
|
||||||
|
if (mindmapHistory.size() > 0) {
|
||||||
|
final MindMapHistory mindMapHistory = mindmapHistory.get(0);
|
||||||
|
mindmap.setZippedXml(mindMapHistory.getZippedXml());
|
||||||
|
saveMindmapDocument(true, mindmap, user);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mindmapService.revertChange(mindmap, Integer.parseInt(hid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("permitAll()")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = {"/{id}/document/xml", "/{id}/document/xml-pub"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public byte[] retrieveDocument(@PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
public byte[] retrieveDocument(@PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
|
@ -155,34 +184,36 @@ public class MindmapController extends BaseController {
|
||||||
return xmlStr.getBytes(StandardCharsets.UTF_8);
|
return xmlStr.getBytes(StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = {"/maps/{id}/document/xml"}, consumes = {"text/plain"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = {"/{id}/document/xml"}, consumes = {"text/plain"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public void updateDocument(@PathVariable int id, @RequestBody String xmlDoc) throws WiseMappingException, IOException {
|
public void updateDocument(@PathVariable int id, @RequestBody String xmlDoc) throws WiseMappingException {
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser(true);
|
||||||
mindmap.setXmlStr(xmlDoc);
|
mindmap.setXmlStr(xmlDoc);
|
||||||
|
|
||||||
saveMindmapDocument(false, mindmap, user);
|
saveMindmapDocument(false, mindmap, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = {"/maps/{id}/{hid}/document/xml"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = {"/{id}/{hid}/document/xml"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public byte[] retrieveDocument(@PathVariable int id, @PathVariable int hid, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
public byte[] retrieveDocument(@PathVariable int id, @PathVariable int hid, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
||||||
final MindMapHistory mindmapHistory = mindmapService.findMindmapHistory(id, hid);
|
final MindMapHistory mindmapHistory = mindmapService.findMindmapHistory(id, hid);
|
||||||
return mindmapHistory.getUnzipXml();
|
return mindmapHistory.getUnzipXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The intention of this method is the update of several properties at once ...
|
* The intention of this method is the update of several properties at once ...
|
||||||
*/
|
*/
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}", consumes = {"application/json"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}", consumes = {"application/json"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void updateProperties(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException {
|
public void updateProperties(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException {
|
||||||
|
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser(true);
|
||||||
|
|
||||||
final String xml = restMindmap.getXml();
|
final String xml = restMindmap.getXml();
|
||||||
if (xml != null && !xml.isEmpty()) {
|
if (xml != null && !xml.isEmpty()) {
|
||||||
|
@ -193,7 +224,7 @@ public class MindmapController extends BaseController {
|
||||||
final String title = restMindmap.getTitle();
|
final String title = restMindmap.getTitle();
|
||||||
if (title != null && !title.equals(mindmap.getTitle())) {
|
if (title != null && !title.equals(mindmap.getTitle())) {
|
||||||
if (mindmapService.getMindmapByTitle(title, user) != null) {
|
if (mindmapService.getMindmapByTitle(title, user) != null) {
|
||||||
throw buildValidationException("title", "You already have a map with this title");
|
throw buildValidationException("You already have a map with this title");
|
||||||
}
|
}
|
||||||
mindmap.setTitle(title);
|
mindmap.setTitle(title);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +249,7 @@ public class MindmapController extends BaseController {
|
||||||
@NotNull
|
@NotNull
|
||||||
private Mindmap findMindmapById(int id) throws MapCouldNotFoundException, AccessDeniedSecurityException {
|
private Mindmap findMindmapById(int id) throws MapCouldNotFoundException, AccessDeniedSecurityException {
|
||||||
// Has enough permissions ?
|
// Has enough permissions ?
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) {
|
if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) {
|
||||||
throw new AccessDeniedSecurityException(id, user);
|
throw new AccessDeniedSecurityException(id, user);
|
||||||
}
|
}
|
||||||
|
@ -231,16 +262,17 @@ public class MindmapController extends BaseController {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/title", consumes = {"text/plain"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/title", consumes = {"text/plain"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void updateTitle(@RequestBody String title, @PathVariable int id) throws WiseMappingException {
|
public void updateTitle(@RequestBody String title, @PathVariable int id) throws WiseMappingException {
|
||||||
|
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser(true);
|
||||||
|
|
||||||
// Is there a map with the same name ?
|
// Is there a map with the same name ?
|
||||||
if (mindmapService.getMindmapByTitle(title, user) != null) {
|
if (mindmapService.getMindmapByTitle(title, user) != null) {
|
||||||
throw buildValidationException("title", "You already have a mindmap with this title");
|
throw buildValidationException("You already have a mindmap with this title");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update map ...
|
// Update map ...
|
||||||
|
@ -249,13 +281,14 @@ public class MindmapController extends BaseController {
|
||||||
mindmapService.updateMindmap(mindMap, false);
|
mindmapService.updateMindmap(mindMap, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/maps/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void updateCollabs(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions {
|
public void updateCollabs(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions {
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
|
|
||||||
// Only owner can change collaborators...
|
// Only owner can change collaborators...
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
|
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
|
||||||
throw new IllegalArgumentException("No enough permissions");
|
throw new IllegalArgumentException("No enough permissions");
|
||||||
}
|
}
|
||||||
|
@ -298,13 +331,14 @@ public class MindmapController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void addCollab(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions, OwnerCannotChangeException {
|
public void addCollab(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions, OwnerCannotChangeException {
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
|
|
||||||
// Only owner can change collaborators...
|
// Only owner can change collaborators...
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
|
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
|
||||||
throw new AccessDeniedSecurityException("User must be owner to share mindmap");
|
throw new AccessDeniedSecurityException("User must be owner to share mindmap");
|
||||||
}
|
}
|
||||||
|
@ -365,7 +399,8 @@ public class MindmapController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}/collabs", produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/{id}/collabs", produces = {"application/json"})
|
||||||
public RestCollaborationList retrieveList(@PathVariable int id) throws MapCouldNotFoundException, AccessDeniedSecurityException {
|
public RestCollaborationList retrieveList(@PathVariable int id) throws MapCouldNotFoundException, AccessDeniedSecurityException {
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
|
|
||||||
|
@ -381,7 +416,8 @@ public class MindmapController extends BaseController {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/description", consumes = {"text/plain"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/description", consumes = {"text/plain"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void updateDescription(@RequestBody String description, @PathVariable int id) throws WiseMappingException {
|
public void updateDescription(@RequestBody String description, @PathVariable int id) throws WiseMappingException {
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
|
@ -389,13 +425,14 @@ public class MindmapController extends BaseController {
|
||||||
mindmapService.updateMindmap(mindmap, false);
|
mindmapService.updateMindmap(mindmap, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/publish", consumes = {"text/plain"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/publish", consumes = {"text/plain"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void updatePublishState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
|
public void updatePublishState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
|
||||||
|
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
|
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
|
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
|
||||||
throw new IllegalArgumentException("No enough to execute this operation");
|
throw new IllegalArgumentException("No enough to execute this operation");
|
||||||
}
|
}
|
||||||
|
@ -406,17 +443,19 @@ public class MindmapController extends BaseController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/{id}")
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void deleteMapById(@PathVariable int id) throws IOException, WiseMappingException {
|
public void deleteMapById(@PathVariable int id) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
mindmapService.removeMindmap(mindmap, user);
|
mindmapService.removeMindmap(mindmap, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/{id}/collabs")
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}/collabs")
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws IOException, WiseMappingException {
|
public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws WiseMappingException {
|
||||||
logger.debug("Deleting permission for email:" + email);
|
logger.debug("Deleting permission for email:" + email);
|
||||||
|
|
||||||
// Is a valid email address ?
|
// Is a valid email address ?
|
||||||
|
@ -426,7 +465,7 @@ public class MindmapController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
|
|
||||||
// Only owner can change collaborators...
|
// Only owner can change collaborators...
|
||||||
if (!mindmap.hasPermissions(user, CollaborationRole.OWNER)) {
|
if (!mindmap.hasPermissions(user, CollaborationRole.OWNER)) {
|
||||||
|
@ -445,42 +484,45 @@ public class MindmapController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/starred", consumes = {"text/plain"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/starred", consumes = {"text/plain"}, produces = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void updateStarredState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
|
public void updateStarredState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
|
||||||
|
|
||||||
logger.debug("Update starred:" + value);
|
logger.debug("Update starred:" + value);
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
|
|
||||||
// Update map status ...
|
// Update map status ...
|
||||||
final boolean starred = Boolean.parseBoolean(value);
|
final boolean starred = Boolean.parseBoolean(value);
|
||||||
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
|
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
|
||||||
if (!collaboration.isPresent()) {
|
if (collaboration.isEmpty()) {
|
||||||
throw new WiseMappingException("No enough permissions.");
|
throw new WiseMappingException("No enough permissions.");
|
||||||
}
|
}
|
||||||
collaboration.get().getCollaborationProperties().setStarred(starred);
|
collaboration.get().getCollaborationProperties().setStarred(starred);
|
||||||
mindmapService.updateCollaboration(user, collaboration.get());
|
mindmapService.updateCollaboration(user, collaboration.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}/starred", produces = {"text/plain"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/{id}/starred", produces = {"text/plain"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String fetchStarred(@PathVariable int id) throws WiseMappingException {
|
public String fetchStarred(@PathVariable int id) throws WiseMappingException {
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
|
|
||||||
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
|
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
|
||||||
if (!collaboration.isPresent()) {
|
if (collaboration.isEmpty()) {
|
||||||
throw new WiseMappingException("No enough permissions.");
|
throw new WiseMappingException("No enough permissions.");
|
||||||
}
|
}
|
||||||
boolean result = collaboration.get().getCollaborationProperties().getStarred();
|
boolean result = collaboration.get().getCollaborationProperties().getStarred();
|
||||||
return Boolean.toString(result);
|
return Boolean.toString(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/batch")
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.DELETE, value = "/batch")
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void batchDelete(@RequestParam() String ids) throws IOException, WiseMappingException {
|
public void batchDelete(@RequestParam() String ids) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
final String[] mapsIds = ids.split(",");
|
final String[] mapsIds = ids.split(",");
|
||||||
try {
|
try {
|
||||||
for (final String mapId : mapsIds) {
|
for (final String mapId : mapsIds) {
|
||||||
|
@ -494,9 +536,10 @@ public class MindmapController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/maps", consumes = {"application/xml", "application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "", consumes = {"application/xml", "application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.CREATED)
|
@ResponseStatus(value = HttpStatus.CREATED)
|
||||||
public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws IOException, WiseMappingException {
|
public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws WiseMappingException {
|
||||||
|
|
||||||
final Mindmap mindmap = new Mindmap();
|
final Mindmap mindmap = new Mindmap();
|
||||||
if (title != null && !title.isEmpty()) {
|
if (title != null && !title.isEmpty()) {
|
||||||
|
@ -505,8 +548,6 @@ public class MindmapController extends BaseController {
|
||||||
|
|
||||||
if (description != null && !description.isEmpty()) {
|
if (description != null && !description.isEmpty()) {
|
||||||
mindmap.setDescription(description);
|
mindmap.setDescription(description);
|
||||||
} else {
|
|
||||||
mindmap.setDescription("description");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate ...
|
// Validate ...
|
||||||
|
@ -523,17 +564,18 @@ public class MindmapController extends BaseController {
|
||||||
mindmap.setXmlStr(mapXml);
|
mindmap.setXmlStr(mapXml);
|
||||||
|
|
||||||
// Add new mindmap ...
|
// Add new mindmap ...
|
||||||
final User user = Utils.getUser(true);
|
final Account user = Utils.getUser(true);
|
||||||
mindmapService.addMindmap(mindmap, user);
|
mindmapService.addMindmap(mindmap, user);
|
||||||
|
|
||||||
// Return the new created map ...
|
// Return the new created map ...
|
||||||
response.setHeader("Location", "/service/maps/" + mindmap.getId());
|
response.setHeader("Location", "/api/restful/maps/" + mindmap.getId());
|
||||||
response.setHeader("ResourceId", Integer.toString(mindmap.getId()));
|
response.setHeader("ResourceId", Integer.toString(mindmap.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/maps/{id}", consumes = {"application/json"}, produces = {"application/json", "text/plain"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "/{id}", consumes = {"application/json"}, produces = {"application/json", "text/plain"})
|
||||||
@ResponseStatus(value = HttpStatus.CREATED)
|
@ResponseStatus(value = HttpStatus.CREATED)
|
||||||
public void createDuplicate(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws IOException, WiseMappingException {
|
public void createDuplicate(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException {
|
||||||
// Validate ...
|
// Validate ...
|
||||||
final BindingResult result = new BeanPropertyBindingResult(restMindmap, "");
|
final BindingResult result = new BeanPropertyBindingResult(restMindmap, "");
|
||||||
new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result);
|
new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result);
|
||||||
|
@ -542,7 +584,7 @@ public class MindmapController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some basic validations ...
|
// Some basic validations ...
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
|
|
||||||
// Create a shallowCopy of the map ...
|
// Create a shallowCopy of the map ...
|
||||||
final Mindmap mindMap = findMindmapById(id);
|
final Mindmap mindMap = findMindmapById(id);
|
||||||
|
@ -554,29 +596,18 @@ public class MindmapController extends BaseController {
|
||||||
mindmapService.addMindmap(clonedMap, user);
|
mindmapService.addMindmap(clonedMap, user);
|
||||||
|
|
||||||
// Return the new created map ...
|
// Return the new created map ...
|
||||||
response.setHeader("Location", "/service/maps/" + clonedMap.getId());
|
response.setHeader("Location", "/api/restful/maps/" + clonedMap.getId());
|
||||||
response.setHeader("ResourceId", Integer.toString(clonedMap.getId()));
|
response.setHeader("ResourceId", Integer.toString(clonedMap.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveMindmapDocument(boolean minor, @NotNull final Mindmap mindMap, @NotNull final User user) throws WiseMappingException {
|
|
||||||
final Calendar now = Calendar.getInstance();
|
|
||||||
mindMap.setLastModificationTime(now);
|
|
||||||
mindMap.setLastEditor(user);
|
|
||||||
mindmapService.updateMindmap(mindMap, !minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ValidationException buildValidationException(@NotNull String fieldName, @NotNull String message) throws WiseMappingException {
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
final BindingResult result = new BeanPropertyBindingResult(new RestMindmap(), "");
|
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}/labels/{lid}")
|
||||||
result.rejectValue(fieldName, "error.not-specified", null, message);
|
|
||||||
return new ValidationException(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/{id}/labels/{lid}")
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
public void removeLabelFromMap(@PathVariable int id, @PathVariable int lid) throws WiseMappingException {
|
public void removeLabelFromMap(@PathVariable int id, @PathVariable int lid) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
final Label label = labelService.findLabelById(lid, user);
|
final MindmapLabel label = labelService.findLabelById(lid, user);
|
||||||
|
|
||||||
if (label == null) {
|
if (label == null) {
|
||||||
throw new LabelCouldNotFoundException("Label could not be found. Id: " + lid);
|
throw new LabelCouldNotFoundException("Label could not be found. Id: " + lid);
|
||||||
|
@ -586,11 +617,12 @@ public class MindmapController extends BaseController {
|
||||||
mindmapService.updateMindmap(mindmap, false);
|
mindmapService.updateMindmap(mindmap, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/maps/{id}/labels", consumes = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "/{id}/labels", consumes = {"application/json"})
|
||||||
@ResponseStatus(value = HttpStatus.OK)
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
public void updateLabel(@PathVariable int id, @RequestBody int lid) throws WiseMappingException {
|
public void updateLabel(@PathVariable int id, @RequestBody int lid) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
final Label label = labelService.findLabelById(lid, user);
|
final MindmapLabel label = labelService.findLabelById(lid, user);
|
||||||
if (label == null) {
|
if (label == null) {
|
||||||
throw new LabelCouldNotFoundException("Label could not be found. Id: " + lid);
|
throw new LabelCouldNotFoundException("Label could not be found. Id: " + lid);
|
||||||
}
|
}
|
||||||
|
@ -600,9 +632,10 @@ public class MindmapController extends BaseController {
|
||||||
mindmapService.updateMindmap(mindmap, false);
|
mindmapService.updateMindmap(mindmap, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/lock", consumes = {"text/plain"}, produces = {"application/json"})
|
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/{id}/lock", consumes = {"text/plain"}, produces = {"application/json"})
|
||||||
public ResponseEntity<RestLockInfo> lockMindmap(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
|
public ResponseEntity<RestLockInfo> lockMindmap(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
final LockManager lockManager = mindmapService.getLockManager();
|
final LockManager lockManager = mindmapService.getLockManager();
|
||||||
final Mindmap mindmap = findMindmapById(id);
|
final Mindmap mindmap = findMindmapById(id);
|
||||||
|
|
||||||
|
@ -617,7 +650,21 @@ public class MindmapController extends BaseController {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyActiveCollabs(@NotNull RestCollaborationList restCollabs, User user) throws TooManyInactiveAccountsExceptions {
|
|
||||||
|
private void saveMindmapDocument(boolean minor, @NotNull final Mindmap mindMap, @NotNull final Account user) throws WiseMappingException {
|
||||||
|
final Calendar now = Calendar.getInstance();
|
||||||
|
mindMap.setLastModificationTime(now);
|
||||||
|
mindMap.setLastEditor(user);
|
||||||
|
mindmapService.updateMindmap(mindMap, !minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationException buildValidationException(@NotNull String message) throws WiseMappingException {
|
||||||
|
final BindingResult result = new BeanPropertyBindingResult(new RestMindmap(), "");
|
||||||
|
result.rejectValue("title", "error.not-specified", null, message);
|
||||||
|
return new ValidationException(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyActiveCollabs(@NotNull RestCollaborationList restCollabs, Account user) throws TooManyInactiveAccountsExceptions {
|
||||||
// Do not allow more than 20 new accounts per mindmap...
|
// Do not allow more than 20 new accounts per mindmap...
|
||||||
final List<Mindmap> userMindmaps = mindmapService.findMindmapsByUser(user);
|
final List<Mindmap> userMindmaps = mindmapService.findMindmapsByUser(user);
|
||||||
final Set<String> allEmails = userMindmaps
|
final Set<String> allEmails = userMindmaps
|
|
@ -21,7 +21,7 @@
|
||||||
package com.wisemapping.rest;
|
package com.wisemapping.rest;
|
||||||
|
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -29,35 +29,35 @@ public abstract class MindmapFilter {
|
||||||
|
|
||||||
public static final MindmapFilter ALL = new MindmapFilter("all") {
|
public static final MindmapFilter ALL = new MindmapFilter("all") {
|
||||||
@Override
|
@Override
|
||||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
boolean accept(@NotNull Mindmap mindmap, @NotNull Account user) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final MindmapFilter MY_MAPS = new MindmapFilter("my_maps") {
|
public static final MindmapFilter MY_MAPS = new MindmapFilter("my_maps") {
|
||||||
@Override
|
@Override
|
||||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
boolean accept(@NotNull Mindmap mindmap, @NotNull Account user) {
|
||||||
return mindmap.getCreator().identityEquality(user);
|
return mindmap.getCreator().identityEquality(user);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final MindmapFilter STARRED = new MindmapFilter("starred") {
|
public static final MindmapFilter STARRED = new MindmapFilter("starred") {
|
||||||
@Override
|
@Override
|
||||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
boolean accept(@NotNull Mindmap mindmap, @NotNull Account user) {
|
||||||
return mindmap.isStarred(user);
|
return mindmap.isStarred(user);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final MindmapFilter SHARED_WITH_ME = new MindmapFilter("shared_with_me") {
|
public static final MindmapFilter SHARED_WITH_ME = new MindmapFilter("shared_with_me") {
|
||||||
@Override
|
@Override
|
||||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
boolean accept(@NotNull Mindmap mindmap, @NotNull Account user) {
|
||||||
return !MY_MAPS.accept(mindmap, user);
|
return !MY_MAPS.accept(mindmap, user);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final MindmapFilter PUBLIC = new MindmapFilter("public") {
|
public static final MindmapFilter PUBLIC = new MindmapFilter("public") {
|
||||||
@Override
|
@Override
|
||||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
boolean accept(@NotNull Mindmap mindmap, @NotNull Account user) {
|
||||||
return mindmap.isPublic();
|
return mindmap.isPublic();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ public abstract class MindmapFilter {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract boolean accept(@NotNull Mindmap mindmap, @NotNull User user);
|
abstract boolean accept(@NotNull Mindmap mindmap, @NotNull Account user);
|
||||||
|
|
||||||
private static final class LabelFilter extends MindmapFilter {
|
private static final class LabelFilter extends MindmapFilter {
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public abstract class MindmapFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
boolean accept(@NotNull Mindmap mindmap, @NotNull Account user) {
|
||||||
return mindmap.hasLabel(this.id);
|
return mindmap.hasLabel(this.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
|
import com.wisemapping.model.Account;
|
||||||
|
import com.wisemapping.rest.model.RestOath2CallbackResponse;
|
||||||
|
import com.wisemapping.security.JwtTokenUtil;
|
||||||
|
import com.wisemapping.service.UserService;
|
||||||
|
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.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/oauth2/")
|
||||||
|
@CrossOrigin
|
||||||
|
public class OAuth2Controller extends BaseController {
|
||||||
|
final private static Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
|
@Qualifier("userService")
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Qualifier("authenticationManager")
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "googlecallback", produces = {"application/json"})
|
||||||
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletResponse response, @NotNull HttpServletRequest request) throws WiseMappingException {
|
||||||
|
logger.debug("ProcessGoogleCallback:" + code);
|
||||||
|
if (code == null) {
|
||||||
|
throw new WiseMappingException("Illegal argument exception: " + code);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Account user = userService.createAndAuthUserFromGoogle(code);
|
||||||
|
String jwtToken = null;
|
||||||
|
if (user.getGoogleSync()) {
|
||||||
|
jwtToken = jwtTokenUtil.doLogin(response, user.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response ...
|
||||||
|
return new RestOath2CallbackResponse(user, jwtToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "confirmaccountsync", produces = {"application/json"})
|
||||||
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
public RestOath2CallbackResponse confirmAccountSync(@NotNull @RequestParam String email, @NotNull @RequestParam String code, @NotNull HttpServletResponse response) throws WiseMappingException {
|
||||||
|
logger.debug("ConfirmAccountSync:" + email + " - " + code);
|
||||||
|
if (code == null) {
|
||||||
|
throw new WiseMappingException("Illegal argument exception: " + email + " - " + code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update login
|
||||||
|
final Account user = userService.confirmGoogleAccountSync(email, code);
|
||||||
|
|
||||||
|
// Add header ...
|
||||||
|
final String jwtToken = jwtTokenUtil.doLogin(response, email);
|
||||||
|
|
||||||
|
// Response ...
|
||||||
|
return new RestOath2CallbackResponse(user, jwtToken);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* 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.rest;
|
||||||
|
|
||||||
|
import com.wisemapping.exceptions.EmailNotExistsException;
|
||||||
|
import com.wisemapping.exceptions.PasswordTooLongException;
|
||||||
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
|
import com.wisemapping.model.AuthenticationType;
|
||||||
|
import com.wisemapping.model.Account;
|
||||||
|
import com.wisemapping.rest.model.RestResetPasswordResponse;
|
||||||
|
import com.wisemapping.rest.model.RestUserRegistration;
|
||||||
|
import com.wisemapping.service.*;
|
||||||
|
import com.wisemapping.validator.Messages;
|
||||||
|
import com.wisemapping.validator.UserValidator;
|
||||||
|
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.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/restful/users")
|
||||||
|
public class UserController extends BaseController {
|
||||||
|
|
||||||
|
@Qualifier("userService")
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RecaptchaService captchaService;
|
||||||
|
|
||||||
|
@Qualifier("authenticationManager")
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authManager;
|
||||||
|
|
||||||
|
@Value("${app.registration.enabled:true}")
|
||||||
|
private Boolean registrationEnabled;
|
||||||
|
|
||||||
|
@Value("${app.registration.captcha.enabled:true}")
|
||||||
|
private Boolean registrationCaptchaEnabled;
|
||||||
|
|
||||||
|
@Value("${app.accounts.exclusion.domain:''}")
|
||||||
|
private String domainBanExclusion;
|
||||||
|
|
||||||
|
private static final Logger logger = LogManager.getLogger();
|
||||||
|
private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP";
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "/", produces = {"application/json"})
|
||||||
|
@ResponseStatus(value = HttpStatus.CREATED)
|
||||||
|
public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request,
|
||||||
|
@NotNull HttpServletResponse response) throws WiseMappingException, BindException {
|
||||||
|
logger.debug("Register new user:" + registration.getEmail());
|
||||||
|
if (!registrationEnabled) {
|
||||||
|
throw new WiseMappingException("Registration is disabled. You can enable it using app.registration.enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registration.getPassword().length() > Account.MAX_PASSWORD_LENGTH_SIZE) {
|
||||||
|
throw new PasswordTooLongException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If tomcat is behind a reverse proxy, ip needs to be found in other header.
|
||||||
|
String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER);
|
||||||
|
if (remoteIp == null || remoteIp.isEmpty()) {
|
||||||
|
remoteIp = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
logger.debug("Remote address" + remoteIp);
|
||||||
|
verify(registration, remoteIp);
|
||||||
|
|
||||||
|
final Account user = new Account();
|
||||||
|
user.setEmail(registration.getEmail().trim());
|
||||||
|
user.setFirstname(registration.getFirstname());
|
||||||
|
user.setLastname(registration.getLastname());
|
||||||
|
user.setPassword(registration.getPassword());
|
||||||
|
|
||||||
|
user.setAuthenticationType(AuthenticationType.DATABASE);
|
||||||
|
userService.createUser(user, false, true);
|
||||||
|
response.setHeader("Location", "/api/restful/users/" + user.getId());
|
||||||
|
response.setHeader("ResourceId", Integer.toString(user.getId()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = {"application/json"})
|
||||||
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
public RestResetPasswordResponse resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException {
|
||||||
|
try {
|
||||||
|
return userService.resetPassword(email);
|
||||||
|
} catch (InvalidUserEmailException e) {
|
||||||
|
throw new EmailNotExistsException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress)
|
||||||
|
throws BindException {
|
||||||
|
|
||||||
|
final BindException errors = new RegistrationException(registration, "registration");
|
||||||
|
final UserValidator validator = new UserValidator();
|
||||||
|
validator.setUserService(userService);
|
||||||
|
validator.validate(registration, errors);
|
||||||
|
|
||||||
|
// If captcha is enabled, generate it ...
|
||||||
|
if (registrationCaptchaEnabled) {
|
||||||
|
final String recaptcha = registration.getRecaptcha();
|
||||||
|
if (recaptcha != null) {
|
||||||
|
final String reCaptchaResponse = captchaService.verifyRecaptcha(remoteAddress, recaptcha);
|
||||||
|
if (reCaptchaResponse != null && !reCaptchaResponse.isEmpty()) {
|
||||||
|
errors.rejectValue("recaptcha", reCaptchaResponse);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errors.rejectValue("recaptcha", Messages.CAPTCHA_LOADING_ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("captchaEnabled is enabled.Recommend to enable it for production environments.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.hasErrors()) {
|
||||||
|
throw errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is excluded ?.
|
||||||
|
final List<String> excludedDomains = Arrays.asList(domainBanExclusion.split(","));
|
||||||
|
final String emailDomain = registration.getEmail().split("@")[1];
|
||||||
|
if (excludedDomains.contains(emailDomain)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Email is part of ban exclusion list due to abuse. Please, contact site admin if you think this is an error."
|
||||||
|
+ emailDomain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.model;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
@JsonAutoDetect(
|
||||||
|
fieldVisibility = JsonAutoDetect.Visibility.NONE,
|
||||||
|
getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY,
|
||||||
|
isGetterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class RestAppConfig {
|
||||||
|
private String apiBaseUrl;
|
||||||
|
private String uiBaseUrl;
|
||||||
|
private String googleOauth2Url;
|
||||||
|
private boolean registrationEnabled;
|
||||||
|
private boolean recaptcha2Enabled;
|
||||||
|
private String recaptcha2SiteKey;
|
||||||
|
private String analyticsAccount;
|
||||||
|
|
||||||
|
private int jwtExpirationMin = 10080;
|
||||||
|
|
||||||
|
RestAppConfig() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiBaseUrl() {
|
||||||
|
return apiBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiBaseUrl(String apiBaseUrl) {
|
||||||
|
this.apiBaseUrl = apiBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGoogleOauth2Url() {
|
||||||
|
return googleOauth2Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoogleOauth2Url(String googleOauth2Url) {
|
||||||
|
this.googleOauth2Url = googleOauth2Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRegistrationEnabled() {
|
||||||
|
return registrationEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegistrationEnabled(boolean registrationEnabled) {
|
||||||
|
this.registrationEnabled = registrationEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRecaptcha2Enabled() {
|
||||||
|
return recaptcha2Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecaptcha2Enabled(boolean recaptcha2Enabled) {
|
||||||
|
this.recaptcha2Enabled = recaptcha2Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecaptcha2SiteKey() {
|
||||||
|
return recaptcha2SiteKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecaptcha2SiteKey(String recaptcha2SiteKey) {
|
||||||
|
this.recaptcha2SiteKey = recaptcha2SiteKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAnalyticsAccount() {
|
||||||
|
return analyticsAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnalyticsAccount(String analyticsAccount) {
|
||||||
|
this.analyticsAccount = analyticsAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getJwtExpirationMin() {
|
||||||
|
return jwtExpirationMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJwtExpirationMin(int jwtExpirationMin) {
|
||||||
|
this.jwtExpirationMin = jwtExpirationMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUiBaseUrl() {
|
||||||
|
return uiBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUiBaseUrl(String uiBaseUrl) {
|
||||||
|
this.uiBaseUrl = uiBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RestAppConfigBuilder {
|
||||||
|
private String apiBaseUrl;
|
||||||
|
private String uiBaseUrl;
|
||||||
|
private String googleOauth2Url;
|
||||||
|
private boolean registrationEnabled;
|
||||||
|
private boolean isCatchaEnabled = false;
|
||||||
|
private String captchaSiteKey;
|
||||||
|
private String analyticsAccount;
|
||||||
|
|
||||||
|
private int jwtExpirationMin;
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setCaptchaSiteKey(@NotNull String captchaSiteKey) {
|
||||||
|
this.captchaSiteKey = captchaSiteKey;
|
||||||
|
this.isCatchaEnabled = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setApiUrl(@NotNull String url) {
|
||||||
|
this.apiBaseUrl = url;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setUiUrl(@NotNull String url) {
|
||||||
|
this.uiBaseUrl = url;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setJwtExpirationMin(@NotNull int value) {
|
||||||
|
this.jwtExpirationMin = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setGoogleOauth2Url(@NotNull String googleOauth2Url) {
|
||||||
|
this.googleOauth2Url = googleOauth2Url;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setGoogleAnalyticsAccount(@NotNull String analyticsAccount) {
|
||||||
|
this.analyticsAccount = analyticsAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setRegistrationEnabled(@NotNull boolean registrationEnabled) {
|
||||||
|
this.registrationEnabled = registrationEnabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestAppConfigBuilder setAnalyticsAccount(@NotNull String analyticsAccount) {
|
||||||
|
this.analyticsAccount = analyticsAccount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public RestAppConfig build() {
|
||||||
|
final RestAppConfig result = new RestAppConfig();
|
||||||
|
result.googleOauth2Url = googleOauth2Url;
|
||||||
|
result.recaptcha2SiteKey = captchaSiteKey;
|
||||||
|
result.recaptcha2Enabled = isCatchaEnabled;
|
||||||
|
result.uiBaseUrl = uiBaseUrl;
|
||||||
|
result.apiBaseUrl = apiBaseUrl;
|
||||||
|
result.registrationEnabled = registrationEnabled;
|
||||||
|
result.analyticsAccount = analyticsAccount;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,9 +24,9 @@ import com.wisemapping.model.Collaborator;
|
||||||
import com.wisemapping.util.TimeUtils;
|
import com.wisemapping.util.TimeUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
@JsonAutoDetect(
|
@JsonAutoDetect(
|
|
@ -30,9 +30,6 @@ import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.FieldError;
|
import org.springframework.validation.FieldError;
|
||||||
import org.springframework.validation.ObjectError;
|
import org.springframework.validation.ObjectError;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@JsonAutoDetect(
|
@JsonAutoDetect(
|
||||||
|
@ -47,13 +44,13 @@ public class RestErrors {
|
||||||
private Errors errors;
|
private Errors errors;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private List<String> gErrors;
|
private List<String> globalError;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
MessageSource messageSource;
|
private MessageSource messageSource;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
Severity gSeverity;
|
private Severity globalSeverity;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
@ -67,8 +64,8 @@ public class RestErrors {
|
||||||
|
|
||||||
this.errors = errors;
|
this.errors = errors;
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
this.gErrors = this.processGlobalErrors(errors);
|
this.globalError = this.processGlobalErrors(errors);
|
||||||
this.gSeverity = Severity.WARNING;
|
this.globalSeverity = Severity.WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestErrors(@NotNull String errorMsg, @NotNull Severity severity) {
|
public RestErrors(@NotNull String errorMsg, @NotNull Severity severity) {
|
||||||
|
@ -78,9 +75,9 @@ public class RestErrors {
|
||||||
|
|
||||||
public RestErrors(@NotNull String errorMsg, @NotNull Severity severity, @Nullable String debugInfo) {
|
public RestErrors(@NotNull String errorMsg, @NotNull Severity severity, @Nullable String debugInfo) {
|
||||||
this._debugInfo = debugInfo;
|
this._debugInfo = debugInfo;
|
||||||
this.gErrors = new ArrayList<>();
|
this.globalError = new ArrayList<>();
|
||||||
this.gErrors.add(errorMsg);
|
this.globalError.add(errorMsg);
|
||||||
this.gSeverity = severity;
|
this.globalSeverity = severity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> processGlobalErrors(@NotNull Errors errors) {
|
private List<String> processGlobalErrors(@NotNull Errors errors) {
|
||||||
|
@ -123,7 +120,7 @@ public class RestErrors {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getGlobalSeverity() {
|
public String getGlobalSeverity() {
|
||||||
return this.gSeverity.toString();
|
return this.globalSeverity.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -132,7 +129,17 @@ public class RestErrors {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getGlobalErrors() {
|
public List<String> getGlobalErrors() {
|
||||||
return gErrors;
|
return globalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RestErrors{" +
|
||||||
|
"errors=" + errors +
|
||||||
|
", gErrors=" + globalError +
|
||||||
|
", messageSource=" + messageSource +
|
||||||
|
", gSeverity=" + globalSeverity +
|
||||||
|
", _debugInfo='" + _debugInfo + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.model;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
@JsonAutoDetect(
|
||||||
|
fieldVisibility = JsonAutoDetect.Visibility.NONE,
|
||||||
|
getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY,
|
||||||
|
isGetterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class RestJwtUser {
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public RestJwtUser(@NotNull String email, @NotNull String password) {
|
||||||
|
this.setEmail(email);
|
||||||
|
this.setPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return this.email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return this.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.rest.model;
|
package com.wisemapping.rest.model;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.wisemapping.model.Label;
|
import com.wisemapping.model.MindmapLabel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -20,22 +38,22 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_
|
||||||
public class RestLabel {
|
public class RestLabel {
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private final Label label;
|
private final MindmapLabel label;
|
||||||
|
|
||||||
public RestLabel() {
|
public RestLabel() {
|
||||||
this(new Label());
|
this(new MindmapLabel());
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestLabel(@NotNull final Label label) {
|
public RestLabel(@NotNull final MindmapLabel label) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParent(@NotNull final Label parent) {
|
public void setParent(final MindmapLabel parent) {
|
||||||
this.label.setParent(parent);
|
this.label.setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Label getParent() {
|
public MindmapLabel getParent() {
|
||||||
return this.label.getParent();
|
return this.label.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,24 +74,16 @@ public class RestLabel {
|
||||||
label.setTitle(title);
|
label.setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColor(@NotNull final String color) {
|
public void setColor(final String color) {
|
||||||
label.setColor(color);
|
label.setColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIconName(@NotNull final String iconName) {
|
|
||||||
label.setIconName(iconName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String getColor() {
|
@Nullable public String getColor() {
|
||||||
return label.getColor();
|
return label.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable public String getIconName() {
|
|
||||||
return label.getIconName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public Label getDelegated() {
|
public MindmapLabel getDelegated() {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
package com.wisemapping.rest.model;
|
package com.wisemapping.rest.model;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.wisemapping.model.Label;
|
import com.wisemapping.model.MindmapLabel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ public class RestLabelList {
|
||||||
this.restLabels = new ArrayList<>();
|
this.restLabels = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestLabelList(@NotNull final List<Label> labels) {
|
public RestLabelList(@NotNull final List<MindmapLabel> labels) {
|
||||||
this.restLabels = new ArrayList<>(labels.size());
|
this.restLabels = new ArrayList<>(labels.size());
|
||||||
for (Label label : labels) {
|
for (MindmapLabel label : labels) {
|
||||||
this.restLabels.add(new RestLabel(label));
|
this.restLabels.add(new RestLabel(label));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@ package com.wisemapping.rest.model;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import com.wisemapping.service.LockInfo;
|
import com.wisemapping.service.LockInfo;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -40,7 +40,7 @@ public class RestLockInfo {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestLockInfo(@Nullable LockInfo lockInfo, @NotNull User user) {
|
public RestLockInfo(@Nullable LockInfo lockInfo, @NotNull Account user) {
|
||||||
this.email = user.getEmail();
|
this.email = user.getEmail();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,6 @@ import com.wisemapping.util.TimeUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -103,7 +100,7 @@ public class RestMindmap {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCreator() {
|
public String getCreator() {
|
||||||
final User creator = mindmap.getCreator();
|
final Account creator = mindmap.getCreator();
|
||||||
return creator != null ? creator.getEmail() : null;
|
return creator != null ? creator.getEmail() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +109,7 @@ public class RestMindmap {
|
||||||
|
|
||||||
|
|
||||||
public RestCollaborator getLastModifierUser() {
|
public RestCollaborator getLastModifierUser() {
|
||||||
final User lastEditor = mindmap.getLastEditor();
|
final Account lastEditor = mindmap.getLastEditor();
|
||||||
|
|
||||||
RestCollaborator result = null;
|
RestCollaborator result = null;
|
||||||
if (lastEditor != null && mindmap.hasPermissions(collaborator, CollaborationRole.EDITOR)) {
|
if (lastEditor != null && mindmap.hasPermissions(collaborator, CollaborationRole.EDITOR)) {
|
||||||
|
@ -155,7 +152,7 @@ public class RestMindmap {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOwner() {
|
public String getOwner() {
|
||||||
final User owner = mindmap.getCreator();
|
final Account owner = mindmap.getCreator();
|
||||||
return owner != null ? owner.getEmail() : null;
|
return owner != null ? owner.getEmail() : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ package com.wisemapping.rest.model;
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.wisemapping.model.MindMapHistory;
|
import com.wisemapping.model.MindMapHistory;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.Account;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
@ -55,7 +55,7 @@ public class RestMindmapHistory {
|
||||||
public RestMindmapHistory(@NotNull MindMapHistory history) {
|
public RestMindmapHistory(@NotNull MindMapHistory history) {
|
||||||
this.id = history.getId();
|
this.id = history.getId();
|
||||||
this.creation = history.getCreationTime();
|
this.creation = history.getCreationTime();
|
||||||
final User editor = history.getEditor();
|
final Account editor = history.getEditor();
|
||||||
this.creator = editor != null ? editor.getFullName() : "";
|
this.creator = editor != null ? editor.getFullName() : "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class RestMindmapInfo {
|
||||||
// Support test deserialization...
|
// Support test deserialization...
|
||||||
Set<RestLabel> result = this.restLabels;
|
Set<RestLabel> result = this.restLabels;
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
final User me = Utils.getUser();
|
final Account me = Utils.getUser();
|
||||||
result = mindmap.getLabels().
|
result = mindmap.getLabels().
|
||||||
stream()
|
stream()
|
||||||
.filter(l -> l.getCreator().equals(me))
|
.filter(l -> l.getCreator().equals(me))
|
||||||
|
@ -119,7 +119,7 @@ public class RestMindmapInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCreator() {
|
public String getCreator() {
|
||||||
final User creator = mindmap.getCreator();
|
final Account creator = mindmap.getCreator();
|
||||||
return creator != null ? creator.getFullName() : null;
|
return creator != null ? creator.getFullName() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ public class RestMindmapInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRole() {
|
public String getRole() {
|
||||||
final User user = Utils.getUser();
|
final Account user = Utils.getUser();
|
||||||
String result;
|
String result;
|
||||||
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
|
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);
|
||||||
return collaboration.map(value -> value.getRole().getLabel()).orElse(ROLE_NONE);
|
return collaboration.map(value -> value.getRole().getLabel()).orElse(ROLE_NONE);
|
||||||
|
@ -143,7 +143,7 @@ public class RestMindmapInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLastModifierUser() {
|
public String getLastModifierUser() {
|
||||||
final User user = mindmap.getLastEditor();
|
final Account user = mindmap.getLastEditor();
|
||||||
return user != null ? user.getFullName() : "unknown";
|
return user != null ? user.getFullName() : "unknown";
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import com.wisemapping.model.Collaborator;
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue