mirror of
https://bitbucket.org/wisemapping/wisemapping-open-source.git
synced 2024-11-15 03:07:55 +01:00
Merge branch 'develop'
This commit is contained in:
commit
41ea26e0a3
23
README.md
23
README.md
@ -58,6 +58,29 @@ Check out the [docker section](./docker/README.)
|
|||||||
Individual test result reports can be found in wisemapping-open-source/wise-webapp/target/failsafe-reports/index.html
|
Individual test result reports can be found in wisemapping-open-source/wise-webapp/target/failsafe-reports/index.html
|
||||||
Test coverage report of unit and integration test can be found in wisemapping-open-source/wise-webapp/target/site/jacoco and wisemapping-open-source/wise-webapp/target/site/jacoco-it folders. Coverage report is generated in the verify phase of [lifecicle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#introduction-to-the-build-lifecyclea) using [jacoco](https://www.jacoco.org/jacoco/trunk/doc/maven.html)
|
Test coverage report of unit and integration test can be found in wisemapping-open-source/wise-webapp/target/site/jacoco and wisemapping-open-source/wise-webapp/target/site/jacoco-it folders. Coverage report is generated in the verify phase of [lifecicle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#introduction-to-the-build-lifecyclea) using [jacoco](https://www.jacoco.org/jacoco/trunk/doc/maven.html)
|
||||||
|
|
||||||
|
|
||||||
|
## Google authorization
|
||||||
|
|
||||||
|
You must configure the following wisemapping properties (app.properties) in order to get google authorization working
|
||||||
|
* `security.oauth2.google.callbackUrl`: url where google will redirect after user authentication, tipically {frontendBaseUrl}/c/registration-google. Also, this url must be defined in google app configuration
|
||||||
|
* `security.oauth2.google.clientId`: client id from google app
|
||||||
|
* `security.oauth2.google.clientSecret`: client secret from google app
|
||||||
|
|
||||||
|
You must create a Google Application in [Google Cloud](https://console.cloud.google.com) and complete all the information required by Google. Here are the most important properties.
|
||||||
|
|
||||||
|
Oauth consent screen
|
||||||
|
* Authorized domains: wisemapping domain (ex: wisemapping.com), and you can add domains of other environments if needed
|
||||||
|
* Permissions
|
||||||
|
* `https://www.googleapis.com/auth/userinfo.profile`
|
||||||
|
* `https://www.googleapis.com/auth/userinfo.email`
|
||||||
|
* Test users: emails for testing, those can be used before the application is validated by Google
|
||||||
|
|
||||||
|
After that, in Credentials, you must create an `Oauth Client Id` credential
|
||||||
|
* Authorized JavaScript origins: list of authorized domains from which to redirect to Google. Ex: `https://wisemaping.com`, `https://wisemapping-testing.com:8080`
|
||||||
|
* Authorized redirect URIs: list of allowed urls to which google will redirect after authenticating . Ex: `https://wisemaping.com/c/registration-google`, `https://wisemapping-testing.com:8080/c/registration-google`
|
||||||
|
|
||||||
|
After credential was created, Google will show you the clientId and clientSecret to configure your application. For productive applications, you must **publish** your application, this is a validation process with Google.
|
||||||
|
|
||||||
## Members
|
## Members
|
||||||
|
|
||||||
### Founders
|
### Founders
|
||||||
|
@ -15,6 +15,9 @@ CREATE TABLE USER (
|
|||||||
activation_date DATE,
|
activation_date DATE,
|
||||||
allow_send_email CHAR(1) NOT NULL,
|
allow_send_email CHAR(1) NOT NULL,
|
||||||
locale VARCHAR(5),
|
locale VARCHAR(5),
|
||||||
|
google_sync BOOLEAN,
|
||||||
|
sync_code VARCHAR(255),
|
||||||
|
google_token VARCHAR(255),
|
||||||
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -25,6 +25,9 @@ CREATE TABLE USER (
|
|||||||
activation_date DATE,
|
activation_date DATE,
|
||||||
allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0,
|
allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0,
|
||||||
locale VARCHAR(5),
|
locale VARCHAR(5),
|
||||||
|
google_sync BOOL,
|
||||||
|
sync_code VARCHAR(255),
|
||||||
|
google_token VARCHAR(255),
|
||||||
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
ON UPDATE NO ACTION
|
ON UPDATE NO ACTION
|
||||||
|
@ -15,6 +15,9 @@ CREATE TABLE "user" (
|
|||||||
activation_date DATE,
|
activation_date DATE,
|
||||||
allow_send_email TEXT NOT NULL DEFAULT 0,
|
allow_send_email TEXT NOT NULL DEFAULT 0,
|
||||||
locale VARCHAR(5),
|
locale VARCHAR(5),
|
||||||
|
google_sync BOOLEAN,
|
||||||
|
sync_code VARCHAR(255),
|
||||||
|
google_token VARCHAR(255),
|
||||||
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) ON DELETE CASCADE ON UPDATE NO ACTION
|
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -27,14 +30,6 @@ CREATE TABLE LABEL (
|
|||||||
--FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id)
|
--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 (
|
CREATE TABLE MINDMAP (
|
||||||
id SERIAL NOT NULL PRIMARY KEY,
|
id SERIAL NOT NULL PRIMARY KEY,
|
||||||
title VARCHAR(255) NOT NULL,
|
title VARCHAR(255) NOT NULL,
|
||||||
@ -44,11 +39,17 @@ CREATE TABLE MINDMAP (
|
|||||||
creation_date TIMESTAMP,
|
creation_date TIMESTAMP,
|
||||||
edition_date TIMESTAMP,
|
edition_date TIMESTAMP,
|
||||||
creator_id INTEGER NOT NULL,
|
creator_id INTEGER NOT NULL,
|
||||||
tags VARCHAR(1014),
|
|
||||||
last_editor_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
|
--FOREIGN KEY(creator_id) REFERENCES "USER"(colaborator_id) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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
|
CREATE TABLE MINDMAP_HISTORY
|
||||||
(id SERIAL NOT NULL PRIMARY KEY,
|
(id SERIAL NOT NULL PRIMARY KEY,
|
||||||
@ -77,14 +78,6 @@ CREATE TABLE COLLABORATION (
|
|||||||
FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id) ON DELETE CASCADE ON UPDATE NO ACTION
|
FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE TAG (
|
|
||||||
id SERIAL NOT NULL PRIMARY KEY,
|
|
||||||
name VARCHAR(255) NOT NULL,
|
|
||||||
user_id INTEGER NOT NULL --,
|
|
||||||
--FOREIGN KEY(user_id) REFERENCES "USER"(colaborator_id) ON DELETE CASCADE ON UPDATE NO ACTION
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE ACCESS_AUDITORY (
|
CREATE TABLE ACCESS_AUDITORY (
|
||||||
id SERIAL NOT NULL PRIMARY KEY,
|
id SERIAL NOT NULL PRIMARY KEY,
|
||||||
login_date DATE,
|
login_date DATE,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# 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:9.0-jdk17-openjdk
|
FROM tomcat:jdk17
|
||||||
LABEL maintainer="Paulo Gustavo Veiga <pveiga@wisemapping.com>"
|
LABEL maintainer="Paulo Gustavo Veiga <pveiga@wisemapping.com>"
|
||||||
|
|
||||||
# Build variables ...
|
# Build variables ...
|
||||||
@ -31,6 +31,9 @@ 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
|
||||||
|
@ -42,7 +42,7 @@ Depending on the database your want to configure, you can create initialization
|
|||||||
The next step is configure the WiseMapping for the database and credentials.
|
The next step is configure the WiseMapping for the database and credentials.
|
||||||
Download `app.properties` configuration file and configure the required sections:
|
Download `app.properties` configuration file and configure the required sections:
|
||||||
|
|
||||||
> $ curl https://bitbucket.org/wisemapping/wisemapping-open-source/raw/644b7078d790220c7844b732a83d45495f11d64e/wise-webapp/src/main/webapp/WEB-INF/app.properties
|
> $ curl https://bitbucket.org/wisemapping/wisemapping-open-source/src/master/wise-webapp/src/main/webapp/WEB-INF/app.properties
|
||||||
|
|
||||||
### Starting the application
|
### Starting the application
|
||||||
|
|
||||||
|
@ -25,6 +25,9 @@ CREATE TABLE USER (
|
|||||||
activation_date DATE,
|
activation_date DATE,
|
||||||
allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0,
|
allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0,
|
||||||
locale VARCHAR(5),
|
locale VARCHAR(5),
|
||||||
|
google_sync BOOL,
|
||||||
|
sync_code VARCHAR(255),
|
||||||
|
google_token VARCHAR(255),
|
||||||
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
ON UPDATE NO ACTION
|
ON UPDATE NO ACTION
|
||||||
@ -113,17 +116,6 @@ CREATE TABLE COLLABORATION (
|
|||||||
)
|
)
|
||||||
CHARACTER SET utf8;
|
CHARACTER SET utf8;
|
||||||
|
|
||||||
CREATE TABLE TAG (
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
|
||||||
name VARCHAR(255)
|
|
||||||
CHARACTER SET utf8 NOT NULL,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (user_id) REFERENCES USER (colaborator_id)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION
|
|
||||||
)
|
|
||||||
CHARACTER SET utf8;
|
|
||||||
|
|
||||||
CREATE TABLE ACCESS_AUDITORY (
|
CREATE TABLE ACCESS_AUDITORY (
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
login_date DATE,
|
login_date DATE,
|
||||||
|
4
distribution/registration-google/update-db-mysql.sql
Normal file
4
distribution/registration-google/update-db-mysql.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE USER
|
||||||
|
ADD COLUMN `google_sync` TINYINT(1) NULL,
|
||||||
|
ADD COLUMN `sync_code` VARCHAR(255) NULL,
|
||||||
|
ADD COLUMN `google_token` VARCHAR(255) NULL;
|
4
distribution/registration-google/update-db-postgres.sql
Normal file
4
distribution/registration-google/update-db-postgres.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE "user"
|
||||||
|
ADD COLUMN `google_sync` BOOLEAN NULL,
|
||||||
|
ADD COLUMN `sync_code` VARCHAR(255) NULL,
|
||||||
|
ADD COLUMN `google_token` VARCHAR(255) NULL;
|
4
pom.xml
4
pom.xml
@ -4,7 +4,7 @@
|
|||||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<com.wisemapping.version>5.0.14</com.wisemapping.version>
|
<com.wisemapping.version>5.0.19</com.wisemapping.version>
|
||||||
<superpom.dir>${project.basedir}/wise-webapps</superpom.dir>
|
<superpom.dir>${project.basedir}/wise-webapps</superpom.dir>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<groupId>org.wisemapping</groupId>
|
<groupId>org.wisemapping</groupId>
|
||||||
<artifactId>wisemapping</artifactId>
|
<artifactId>wisemapping</artifactId>
|
||||||
<name>WiseMapping Project</name>
|
<name>WiseMapping Project</name>
|
||||||
<version>5.0.14</version>
|
<version>5.0.19</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<groupId>org.wisemapping</groupId>
|
<groupId>org.wisemapping</groupId>
|
||||||
<artifactId>wisemapping</artifactId>
|
<artifactId>wisemapping</artifactId>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
<version>5.0.14</version>
|
<version>5.0.19</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -29,11 +29,11 @@
|
|||||||
<mkdir dir="target/wisemapping-mindplot"/>
|
<mkdir dir="target/wisemapping-mindplot"/>
|
||||||
<exec executable="npm" dir="target" failonerror="true">
|
<exec executable="npm" dir="target" failonerror="true">
|
||||||
<arg value="pack"/>
|
<arg value="pack"/>
|
||||||
<arg value="@wisemapping/mindplot@5.0.17"/>
|
<arg value="@wisemapping/mindplot@5.0.19"/>
|
||||||
</exec>
|
</exec>
|
||||||
<exec executable="tar" dir="target" failonerror="true">
|
<exec executable="tar" dir="target" failonerror="true">
|
||||||
<arg value="-xvzf"/>
|
<arg value="-xvzf"/>
|
||||||
<arg value="wisemapping-mindplot-5.0.17.tgz"/>
|
<arg value="wisemapping-mindplot-5.0.19.tgz"/>
|
||||||
<arg value="-C"/>
|
<arg value="-C"/>
|
||||||
<arg value="wisemapping-mindplot"/>
|
<arg value="wisemapping-mindplot"/>
|
||||||
</exec>
|
</exec>
|
||||||
@ -42,11 +42,11 @@
|
|||||||
<mkdir dir="target/wisemapping-webapp"/>
|
<mkdir dir="target/wisemapping-webapp"/>
|
||||||
<exec executable="npm" dir="target" failonerror="true">
|
<exec executable="npm" dir="target" failonerror="true">
|
||||||
<arg value="pack"/>
|
<arg value="pack"/>
|
||||||
<arg value="@wisemapping/webapp@5.0.18"/>
|
<arg value="@wisemapping/webapp@5.0.19"/>
|
||||||
</exec>
|
</exec>
|
||||||
<exec executable="tar" dir="target" failonerror="true">
|
<exec executable="tar" dir="target" failonerror="true">
|
||||||
<arg value="-xvzf"/>
|
<arg value="-xvzf"/>
|
||||||
<arg value="wisemapping-webapp-5.0.18.tgz"/>
|
<arg value="wisemapping-webapp-5.0.19.tgz"/>
|
||||||
<arg value="-C"/>
|
<arg value="-C"/>
|
||||||
<arg value="wisemapping-webapp"/>
|
<arg value="wisemapping-webapp"/>
|
||||||
</exec>
|
</exec>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<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">
|
<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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>wise-webapp</artifactId>
|
<artifactId>wise-webapp</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
@ -8,13 +9,13 @@
|
|||||||
<groupId>org.wisemapping</groupId>
|
<groupId>org.wisemapping</groupId>
|
||||||
<artifactId>wisemapping</artifactId>
|
<artifactId>wisemapping</artifactId>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
<version>5.0.14</version>
|
<version>5.0.19</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<org.springframework.version>5.3.22</org.springframework.version>
|
<org.springframework.version>5.3.24</org.springframework.version>
|
||||||
<org.springframework.addons>5.6.2</org.springframework.addons>
|
<org.springframework.addons>5.7.3</org.springframework.addons>
|
||||||
<hibernate.version>5.6.11.Final</hibernate.version>
|
<hibernate.version>5.6.12.Final</hibernate.version>
|
||||||
<hibernate-validator.version>6.0.21.Final</hibernate-validator.version>
|
<hibernate-validator.version>6.0.21.Final</hibernate-validator.version>
|
||||||
<spring-security-taglibs.version>5.6.1</spring-security-taglibs.version>
|
<spring-security-taglibs.version>5.6.1</spring-security-taglibs.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -41,7 +42,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.intellij</groupId>
|
<groupId>com.intellij</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<version>7.0.3</version>
|
<version>12.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -50,6 +51,11 @@
|
|||||||
<version>${org.springframework.version}</version>
|
<version>${org.springframework.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.5.1</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.security</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
<artifactId>spring-security-ldap</artifactId>
|
<artifactId>spring-security-ldap</artifactId>
|
||||||
@ -195,7 +201,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>8.0.28</version>
|
<version>8.0.31</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -219,10 +225,9 @@
|
|||||||
<version>3.9.9</version>
|
<version>3.9.9</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j-core</artifactId>
|
||||||
<version>1.2.17</version>
|
<version>2.19.0</version>
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
|
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -240,7 +245,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.13.1</version>
|
<version>2.13.4.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<!-- This is required in case of Tomcat, do not remove -->
|
<!-- This is required in case of Tomcat, do not remove -->
|
||||||
@ -291,15 +296,10 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>5.1.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hsqldb</groupId>
|
<groupId>org.hsqldb</groupId>
|
||||||
<artifactId>hsqldb</artifactId>
|
<artifactId>hsqldb</artifactId>
|
||||||
<version>2.6.1</version>
|
<version>2.7.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
@ -343,7 +343,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>5.1.5</version>
|
<version>8.0.31</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<executions>
|
<executions>
|
||||||
@ -498,13 +498,13 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<!-- Confirm why there is a NPE -->
|
<!-- Confirm why there is a NPE -->
|
||||||
<!-- <execution>-->
|
<!-- <execution>-->
|
||||||
<!-- <id>default-report-integration</id>-->
|
<!-- <id>default-report-integration</id>-->
|
||||||
<!-- <phase>verify</phase>-->
|
<!-- <phase>verify</phase>-->
|
||||||
<!-- <goals>-->
|
<!-- <goals>-->
|
||||||
<!-- <goal>report-integration</goal>-->
|
<!-- <goal>report-integration</goal>-->
|
||||||
<!-- </goals>-->
|
<!-- </goals>-->
|
||||||
<!-- </execution>-->
|
<!-- </execution>-->
|
||||||
<execution>
|
<execution>
|
||||||
<id>default-report</id>
|
<id>default-report</id>
|
||||||
<phase>verify</phase>
|
<phase>verify</phase>
|
||||||
@ -559,7 +559,9 @@
|
|||||||
<daemon>true</daemon>
|
<daemon>true</daemon>
|
||||||
<waitForChild>false</waitForChild>
|
<waitForChild>false</waitForChild>
|
||||||
<maxStartupLines>200</maxStartupLines>
|
<maxStartupLines>200</maxStartupLines>
|
||||||
<jvmArgs>${integrationTestArgLine} -Ddatabase.base.url=${project.build.directory} -Djetty.port=8080</jvmArgs>
|
<jvmArgs>${integrationTestArgLine} -Ddatabase.base.url=${project.build.directory}
|
||||||
|
-Djetty.port=8080
|
||||||
|
</jvmArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
package com.wisemapping.dao;
|
package com.wisemapping.dao;
|
||||||
|
|
||||||
import com.wisemapping.model.AccessAuditory;
|
import com.wisemapping.model.AccessAuditory;
|
||||||
|
import com.wisemapping.model.AuthenticationType;
|
||||||
import com.wisemapping.model.Collaboration;
|
import com.wisemapping.model.Collaboration;
|
||||||
import com.wisemapping.model.Collaborator;
|
import com.wisemapping.model.Collaborator;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
@ -31,7 +32,6 @@ import org.springframework.orm.hibernate5.HibernateTemplate;
|
|||||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
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;
|
||||||
@ -101,7 +101,11 @@ public class UserManagerImpl
|
|||||||
@Override
|
@Override
|
||||||
public void createUser(User user) {
|
public void createUser(User user) {
|
||||||
assert user != null : "Trying to store a null user";
|
assert user != null : "Trying to store a null user";
|
||||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
if (!AuthenticationType.GOOGLE_OAUTH2.equals(user.getAuthenticationType())) {
|
||||||
|
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||||
|
} else {
|
||||||
|
user.setPassword("");
|
||||||
|
}
|
||||||
getHibernateTemplate().saveOrUpdate(user);
|
getHibernateTemplate().saveOrUpdate(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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.filter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* If your wisemapping customization throws cross domain errores in browser, you can configure this filter in webdefault.xml
|
||||||
|
* By default it will accept all domains, but you can restrict to the domain you need
|
||||||
|
*
|
||||||
|
* <filter>
|
||||||
|
* <filter-name>cross-origin</filter-name>
|
||||||
|
* <filter-class>com.wisemapping.filter.CorsFilter</filter-class>
|
||||||
|
* <init-param>
|
||||||
|
* <param-name>allowedOrigins</param-name>
|
||||||
|
* <param-value>*</param-value>
|
||||||
|
* </init-param>
|
||||||
|
* <init-param>
|
||||||
|
* <param-name>allowedMethods</param-name>
|
||||||
|
* <param-value>GET,POST,HEAD</param-value>
|
||||||
|
* </init-param>
|
||||||
|
* <init-param>
|
||||||
|
* <param-name>allowedHeaders</param-name>
|
||||||
|
* <param-value>X-Requested-With,Content-Type,Accept,Origin</param-value>
|
||||||
|
* </init-param>
|
||||||
|
* </filter>
|
||||||
|
* <filter-mapping>
|
||||||
|
* <filter-name>cross-origin</filter-name>
|
||||||
|
* <url-pattern>/*</url-pattern>
|
||||||
|
* </filter-mapping>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CorsFilter implements Filter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
if (servletResponse != null) {
|
||||||
|
// Authorize (allow) all domains to consume the content
|
||||||
|
((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Methods","GET, OPTIONS, HEAD, PUT, POST");
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.doFilter(servletRequest, servletResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,9 @@ public class RequestPropertiesInterceptor implements HandlerInterceptor {
|
|||||||
@Value("${security.type}")
|
@Value("${security.type}")
|
||||||
private String securityType;
|
private String securityType;
|
||||||
|
|
||||||
|
@Value("${security.oauth2.google.url}")
|
||||||
|
private String googleOauth2Url;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object object) throws Exception {
|
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object object) throws Exception {
|
||||||
|
|
||||||
@ -64,6 +67,8 @@ public class RequestPropertiesInterceptor implements HandlerInterceptor {
|
|||||||
request.setAttribute("google.recaptcha2.enabled", recaptcha2Enabled);
|
request.setAttribute("google.recaptcha2.enabled", recaptcha2Enabled);
|
||||||
request.setAttribute("google.recaptcha2.siteKey", recaptcha2SiteKey);
|
request.setAttribute("google.recaptcha2.siteKey", recaptcha2SiteKey);
|
||||||
|
|
||||||
|
request.setAttribute("security.oauth2.google.url", googleOauth2Url);
|
||||||
|
|
||||||
request.setAttribute("site.homepage", siteHomepage);
|
request.setAttribute("site.homepage", siteHomepage);
|
||||||
request.setAttribute("site.static.js.url", siteStaticUrl);
|
request.setAttribute("site.static.js.url", siteStaticUrl);
|
||||||
|
|
||||||
|
@ -24,8 +24,10 @@ import com.wisemapping.model.User;
|
|||||||
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;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
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;
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ import javax.servlet.http.HttpSessionEvent;
|
|||||||
import javax.servlet.http.HttpSessionListener;
|
import javax.servlet.http.HttpSessionListener;
|
||||||
|
|
||||||
public class UnlockOnExpireListener implements HttpSessionListener {
|
public class UnlockOnExpireListener implements HttpSessionListener {
|
||||||
private static final Logger logger = Logger.getLogger(UnlockOnExpireListener.class);
|
private static final Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sessionCreated(@NotNull HttpSessionEvent event) {
|
public void sessionCreated(@NotNull HttpSessionEvent event) {
|
||||||
|
@ -24,7 +24,8 @@ import com.wisemapping.model.Mindmap;
|
|||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
import com.wisemapping.rest.model.RestLogItem;
|
import com.wisemapping.rest.model.RestLogItem;
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -42,7 +43,7 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
final public class NotificationService {
|
final public class NotificationService {
|
||||||
final private static Logger logger = Logger.getLogger(Mailer.class);
|
final private static Logger logger = LogManager.getLogger();
|
||||||
private ResourceBundleMessageSource messageSource;
|
private ResourceBundleMessageSource messageSource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -23,7 +23,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public enum AuthenticationType {
|
public enum AuthenticationType {
|
||||||
DATABASE('D'),
|
DATABASE('D'),
|
||||||
LDAP('L'),
|
LDAP('L'),
|
||||||
OPENID('O');
|
GOOGLE_OAUTH2('G');
|
||||||
|
|
||||||
private final char schemaCode;
|
private final char schemaCode;
|
||||||
|
|
||||||
AuthenticationType(char schemaCode) {
|
AuthenticationType(char schemaCode) {
|
||||||
|
@ -19,13 +19,12 @@
|
|||||||
package com.wisemapping.model;
|
package com.wisemapping.model;
|
||||||
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Fetch;
|
|
||||||
import org.hibernate.annotations.FetchMode;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "COLLABORATION")
|
@Table(name = "COLLABORATION")
|
||||||
@ -127,16 +126,14 @@ public class Collaboration implements Serializable {
|
|||||||
Collaboration that = (Collaboration) o;
|
Collaboration that = (Collaboration) o;
|
||||||
|
|
||||||
if (id != that.id) return false;
|
if (id != that.id) return false;
|
||||||
if (collaborator != null ? !collaborator.equals(that.collaborator) : that.collaborator != null) return false;
|
if (!Objects.equals(collaborator, that.collaborator)) return false;
|
||||||
if (mindMap != null ? !mindMap.equals(that.mindMap) : that.mindMap != null) return false;
|
if (!Objects.equals(mindMap, that.mindMap)) return false;
|
||||||
return role == that.role;
|
return role == that.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = id ^ (id >>> 32);
|
//https://thorben-janssen.com/ultimate-guide-to-implementing-equals-and-hashcode-with-hibernate/
|
||||||
result = 31 * result + (role != null ? role.hashCode() : 0);
|
return 13;
|
||||||
result = 31 * result + (mindMap != null ? mindMap.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ public class Collaborator implements Serializable {
|
|||||||
int id = this.getId();
|
int id = this.getId();
|
||||||
String email = this.getEmail();
|
String email = this.getEmail();
|
||||||
|
|
||||||
int result = (int) (id ^ (id >>> 32));
|
int result = id ^ (id >>> 32);
|
||||||
result = 31 * result + (email != null ? email.hashCode() : 0);
|
result = 31 * result + (email != null ? email.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "LABEL")
|
@Table(name = "LABEL")
|
||||||
@ -34,17 +35,22 @@ public class Label implements Serializable {
|
|||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
@NotNull private String title;
|
@NotNull
|
||||||
@NotNull private String color;
|
private String title;
|
||||||
@Nullable private String iconName;
|
@NotNull
|
||||||
|
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 private User creator;
|
@NotNull
|
||||||
|
private User creator;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name="parent_label_id",nullable = true)
|
@JoinColumn(name = "parent_label_id", nullable = true)
|
||||||
@Nullable private Label parent;
|
@Nullable
|
||||||
|
private Label parent;
|
||||||
|
|
||||||
public void setParent(@Nullable Label parent) {
|
public void setParent(@Nullable Label parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
@ -104,17 +110,15 @@ public class Label implements Serializable {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (!(o instanceof Label)) return false;
|
if (!(o instanceof Label)) return false;
|
||||||
|
|
||||||
Label label = (Label) o;
|
final Label label = (Label) o;
|
||||||
|
|
||||||
return id == label.id && creator.getId() == label.creator.getId()
|
return id == label.id && creator.getId() == label.creator.getId()
|
||||||
&& !(parent != null ? !parent.equals(label.parent) : label.parent != null);
|
&& Objects.equals(parent, label.parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
long result = id;
|
long result = title.hashCode();
|
||||||
result = 31 * result + title.hashCode();
|
result = 31 * result + (creator != null ? creator.hashCode() : 0);
|
||||||
result = 31 * result + (creator!=null?creator.hashCode():0);
|
|
||||||
result = 31 * result + (parent != null ? parent.hashCode() : 0);
|
result = 31 * result + (parent != null ? parent.hashCode() : 0);
|
||||||
return (int) result;
|
return (int) result;
|
||||||
}
|
}
|
||||||
|
@ -83,13 +83,9 @@ public class Mindmap implements Serializable {
|
|||||||
@Basic(fetch = FetchType.LAZY)
|
@Basic(fetch = FetchType.LAZY)
|
||||||
private byte[] zippedXml;
|
private byte[] zippedXml;
|
||||||
|
|
||||||
//~ Constructors .........................................................................................
|
|
||||||
|
|
||||||
public Mindmap() {
|
public Mindmap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ Methods ..............................................................................................
|
|
||||||
|
|
||||||
public void setUnzipXml(@NotNull byte[] value) {
|
public void setUnzipXml(@NotNull byte[] value) {
|
||||||
try {
|
try {
|
||||||
final byte[] zip = ZipUtils.bytesToZip(value);
|
final byte[] zip = ZipUtils.bytesToZip(value);
|
||||||
@ -146,7 +142,9 @@ public class Mindmap implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removedCollaboration(@NotNull Collaboration collaboration) {
|
public void removedCollaboration(@NotNull Collaboration collaboration) {
|
||||||
collaborations.remove(collaboration);
|
// https://stackoverflow.com/questions/25125210/hibernate-persistentset-remove-operation-not-working
|
||||||
|
this.collaborations.remove(collaboration);
|
||||||
|
collaboration.setMindMap(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removedCollaboration(@NotNull Set<Collaboration> collaborations) {
|
public void removedCollaboration(@NotNull Set<Collaboration> collaborations) {
|
||||||
@ -316,11 +314,20 @@ public class Mindmap implements Serializable {
|
|||||||
final StringBuilder result = new StringBuilder();
|
final StringBuilder result = new StringBuilder();
|
||||||
result.append("<map version=\"tango\">");
|
result.append("<map version=\"tango\">");
|
||||||
result.append("<topic central=\"true\" text=\"");
|
result.append("<topic central=\"true\" text=\"");
|
||||||
result.append(StringEscapeUtils.escapeXml(title));
|
result.append(escapeXmlAttribute(title));
|
||||||
result.append("\"/></map>");
|
result.append("\"/></map>");
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static private String escapeXmlAttribute(String attValue) {
|
||||||
|
// Hack: Find out of the box function.
|
||||||
|
String result = attValue.replace("&", "&");
|
||||||
|
result = result.replace("<", "<");
|
||||||
|
result = result.replace("gt", ">");
|
||||||
|
result = result.replace("\"", """);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public Mindmap shallowClone() {
|
public Mindmap shallowClone() {
|
||||||
final Mindmap result = new Mindmap();
|
final Mindmap result = new Mindmap();
|
||||||
result.setDescription(this.getDescription());
|
result.setDescription(this.getDescription());
|
||||||
@ -351,18 +358,6 @@ public class Mindmap implements Serializable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Label findLabel(int labelId) {
|
|
||||||
Label result = null;
|
|
||||||
for (Label label : this.labels) {
|
|
||||||
if (label.getId() == labelId) {
|
|
||||||
result = label;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeLabel(@NotNull final Label label) {
|
public void removeLabel(@NotNull final Label label) {
|
||||||
this.labels.remove(label);
|
this.labels.remove(label);
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,12 @@
|
|||||||
|
|
||||||
package com.wisemapping.model;
|
package com.wisemapping.model;
|
||||||
|
|
||||||
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 javax.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "USER")
|
@Table(name = "USER")
|
||||||
@ -39,21 +36,30 @@ public class User
|
|||||||
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")
|
||||||
|
private Boolean googleSync;
|
||||||
|
|
||||||
|
@Column(name = "sync_code")
|
||||||
|
private String syncCode;
|
||||||
|
|
||||||
|
@Column(name = "google_token")
|
||||||
|
private String googleToken;
|
||||||
|
|
||||||
public User() {
|
public User() {
|
||||||
}
|
}
|
||||||
@ -151,7 +157,35 @@ public class User
|
|||||||
this.authenticatorUri = authenticatorUri;
|
this.authenticatorUri = authenticatorUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setAuthenticationTypeCode(Character authenticationTypeCode) {
|
||||||
|
this.authenticationTypeCode = authenticationTypeCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getGoogleSync() {
|
||||||
|
return googleSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoogleSync(Boolean googleSync) {
|
||||||
|
this.googleSync = googleSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSyncCode() {
|
||||||
|
return syncCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncCode(String syncCode) {
|
||||||
|
this.syncCode = syncCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGoogleToken() {
|
||||||
|
return googleToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoogleToken(String googleToken) {
|
||||||
|
this.googleToken = googleToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "User{" +
|
return "User{" +
|
||||||
"firstname='" + firstname + '\'' +
|
"firstname='" + firstname + '\'' +
|
||||||
|
@ -19,19 +19,15 @@
|
|||||||
package com.wisemapping.rest;
|
package com.wisemapping.rest;
|
||||||
|
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.mail.NotificationService;
|
|
||||||
import com.wisemapping.model.Collaboration;
|
import com.wisemapping.model.Collaboration;
|
||||||
import com.wisemapping.model.Label;
|
import com.wisemapping.model.Label;
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
import com.wisemapping.rest.model.RestLogItem;
|
|
||||||
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;
|
||||||
import com.wisemapping.service.MindmapService;
|
import com.wisemapping.service.MindmapService;
|
||||||
import com.wisemapping.service.UserService;
|
import com.wisemapping.service.UserService;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
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;
|
||||||
@ -41,7 +37,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -58,10 +53,6 @@ public class AccountController extends BaseController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private LabelService labelService;
|
private LabelService labelService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NotificationService notificationService;
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "account/password", consumes = {"text/plain"})
|
@RequestMapping(method = RequestMethod.PUT, value = "account/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) {
|
||||||
|
@ -24,7 +24,8 @@ 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.RegistrationException;
|
import com.wisemapping.service.RegistrationException;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
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;
|
||||||
@ -42,7 +43,7 @@ import java.util.Locale;
|
|||||||
|
|
||||||
public class BaseController {
|
public class BaseController {
|
||||||
|
|
||||||
final private Logger logger = Logger.getLogger(BaseController.class);
|
final private Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
@Qualifier("messageSource")
|
@Qualifier("messageSource")
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -25,7 +25,8 @@ import com.wisemapping.security.Utils;
|
|||||||
import com.wisemapping.service.*;
|
import com.wisemapping.service.*;
|
||||||
import com.wisemapping.validator.MapInfoValidator;
|
import com.wisemapping.validator.MapInfoValidator;
|
||||||
import org.apache.commons.validator.routines.EmailValidator;
|
import org.apache.commons.validator.routines.EmailValidator;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
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;
|
||||||
@ -46,7 +47,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class MindmapController extends BaseController {
|
public class MindmapController extends BaseController {
|
||||||
final Logger logger = Logger.getLogger(MindmapController.class);
|
final Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
private static final String LATEST_HISTORY_REVISION = "latest";
|
private static final String LATEST_HISTORY_REVISION = "latest";
|
||||||
|
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.User;
|
||||||
|
import com.wisemapping.rest.model.RestOath2CallbackResponse;
|
||||||
|
import com.wisemapping.service.*;
|
||||||
|
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.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@CrossOrigin
|
||||||
|
public class Oauth2Controller extends BaseController {
|
||||||
|
@Qualifier("userService")
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Qualifier("authenticationManager")
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authManager;
|
||||||
|
|
||||||
|
@Value("${google.recaptcha2.enabled}")
|
||||||
|
private Boolean recatchaEnabled;
|
||||||
|
|
||||||
|
@Value("${accounts.exclusion.domain:''}")
|
||||||
|
private String domainBanExclusion;
|
||||||
|
|
||||||
|
private void doLogin(HttpServletRequest request, String email) {
|
||||||
|
PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(email,null);
|
||||||
|
Authentication auth = authManager.authenticate(token);
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
|
// update spring mvc session
|
||||||
|
HttpSession session = request.getSession(true);
|
||||||
|
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = "/oauth2/googlecallback", produces = { "application/json" })
|
||||||
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException {
|
||||||
|
User user = userService.createUserFromGoogle(code);
|
||||||
|
if (user.getGoogleSync() != null && user.getGoogleSync().booleanValue()) {
|
||||||
|
doLogin(request, user.getEmail());
|
||||||
|
}
|
||||||
|
RestOath2CallbackResponse response = new RestOath2CallbackResponse();
|
||||||
|
response.setEmail(user.getEmail());
|
||||||
|
response.setGoogleSync(user.getGoogleSync());
|
||||||
|
response.setSyncCode(user.getSyncCode());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/oauth2/confirmaccountsync", produces = { "application/json" })
|
||||||
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
public void confirmAccountSync(@NotNull @RequestParam String email, @NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException {
|
||||||
|
userService.confirmAccountSync(email, code);
|
||||||
|
doLogin(request, email);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,110 +22,122 @@ import com.wisemapping.exceptions.EmailNotExistsException;
|
|||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.model.AuthenticationType;
|
import com.wisemapping.model.AuthenticationType;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
|
import com.wisemapping.rest.model.RestResetPasswordResponse;
|
||||||
import com.wisemapping.rest.model.RestUserRegistration;
|
import com.wisemapping.rest.model.RestUserRegistration;
|
||||||
import com.wisemapping.service.*;
|
import com.wisemapping.service.*;
|
||||||
import com.wisemapping.validator.Messages;
|
import com.wisemapping.validator.Messages;
|
||||||
import com.wisemapping.validator.UserValidator;
|
import com.wisemapping.validator.UserValidator;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
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.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.validation.BindException;
|
import org.springframework.validation.BindException;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
public class UserController extends BaseController {
|
public class UserController extends BaseController {
|
||||||
@Qualifier("userService")
|
@Qualifier("userService")
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RecaptchaService captchaService;
|
private RecaptchaService captchaService;
|
||||||
|
|
||||||
@Value("${google.recaptcha2.enabled}")
|
@Qualifier("authenticationManager")
|
||||||
private Boolean recatchaEnabled;
|
@Autowired
|
||||||
|
private AuthenticationManager authManager;
|
||||||
|
|
||||||
@Value("${accounts.exclusion.domain:''}")
|
@Value("${google.recaptcha2.enabled}")
|
||||||
private String domainBanExclusion;
|
private Boolean recatchaEnabled;
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(UserController.class);
|
@Value("${accounts.exclusion.domain:''}")
|
||||||
private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP";
|
private String domainBanExclusion;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/users", produces = {"application/json"})
|
private static final Logger logger = LogManager.getLogger();
|
||||||
@ResponseStatus(value = HttpStatus.CREATED)
|
private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP";
|
||||||
public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws WiseMappingException, BindException {
|
|
||||||
logger.debug("Register new user:" + registration.getEmail());
|
|
||||||
|
|
||||||
// If tomcat is behind a reverse proxy, ip needs to be found in other header.
|
@RequestMapping(method = RequestMethod.POST, value = "/users", produces = { "application/json" })
|
||||||
String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER);
|
@ResponseStatus(value = HttpStatus.CREATED)
|
||||||
if (remoteIp == null || remoteIp.isEmpty()) {
|
public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request,
|
||||||
remoteIp = request.getRemoteAddr();
|
@NotNull HttpServletResponse response) throws WiseMappingException, BindException {
|
||||||
}
|
logger.debug("Register new user:" + registration.getEmail());
|
||||||
logger.debug("Remote address" + remoteIp);
|
|
||||||
|
|
||||||
verify(registration, remoteIp);
|
// 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);
|
||||||
|
|
||||||
final User user = new User();
|
verify(registration, remoteIp);
|
||||||
user.setEmail(registration.getEmail().trim());
|
|
||||||
user.setFirstname(registration.getFirstname());
|
|
||||||
user.setLastname(registration.getLastname());
|
|
||||||
user.setPassword(registration.getPassword());
|
|
||||||
|
|
||||||
user.setAuthenticationType(AuthenticationType.DATABASE);
|
final User user = new User();
|
||||||
userService.createUser(user, false, true);
|
user.setEmail(registration.getEmail().trim());
|
||||||
response.setHeader("Location", "/service/users/" + user.getId());
|
user.setFirstname(registration.getFirstname());
|
||||||
}
|
user.setLastname(registration.getLastname());
|
||||||
|
user.setPassword(registration.getPassword());
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.PUT, value = "/users/resetPassword", produces = {"application/json"})
|
user.setAuthenticationType(AuthenticationType.DATABASE);
|
||||||
@ResponseStatus(value = HttpStatus.OK)
|
userService.createUser(user, false, true);
|
||||||
public void resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException {
|
response.setHeader("Location", "/service/users/" + user.getId());
|
||||||
try {
|
}
|
||||||
userService.resetPassword(email);
|
|
||||||
} catch (InvalidUserEmailException e) {
|
|
||||||
throw new EmailNotExistsException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress) throws BindException {
|
@RequestMapping(method = RequestMethod.PUT, value = "/users/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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final BindException errors = new RegistrationException(registration, "registration");
|
private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress)
|
||||||
final UserValidator validator = new UserValidator();
|
throws BindException {
|
||||||
validator.setUserService(userService);
|
|
||||||
validator.validate(registration, errors);
|
|
||||||
|
|
||||||
// If captcha is enabled, generate it ...
|
final BindException errors = new RegistrationException(registration, "registration");
|
||||||
if (recatchaEnabled) {
|
final UserValidator validator = new UserValidator();
|
||||||
final String recaptcha = registration.getRecaptcha();
|
validator.setUserService(userService);
|
||||||
if (recaptcha != null) {
|
validator.validate(registration, errors);
|
||||||
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()) {
|
// If captcha is enabled, generate it ...
|
||||||
throw errors;
|
if (recatchaEnabled) {
|
||||||
}
|
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.");
|
||||||
|
}
|
||||||
|
|
||||||
// Is excluded ?.
|
if (errors.hasErrors()) {
|
||||||
final List<String> excludedDomains = Arrays.asList(domainBanExclusion.split(","));
|
throw errors;
|
||||||
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);
|
// 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,33 @@
|
|||||||
|
package com.wisemapping.rest.model;
|
||||||
|
|
||||||
|
public class RestOath2CallbackResponse {
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
private Boolean googleSync;
|
||||||
|
private String syncCode;
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getGoogleSync() {
|
||||||
|
return googleSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoogleSync(Boolean googleSync) {
|
||||||
|
this.googleSync = googleSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSyncCode() {
|
||||||
|
return syncCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncCode(String syncCode) {
|
||||||
|
this.syncCode = syncCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.wisemapping.rest.model;
|
||||||
|
|
||||||
|
public enum RestResetPasswordAction {
|
||||||
|
|
||||||
|
EMAIL_SENT, OAUTH2_USER
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.wisemapping.rest.model;
|
||||||
|
|
||||||
|
public class RestResetPasswordResponse {
|
||||||
|
|
||||||
|
RestResetPasswordAction action;
|
||||||
|
|
||||||
|
public RestResetPasswordAction getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAction(RestResetPasswordAction action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,6 +23,7 @@ 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.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.wisemapping.model.AuthenticationType;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -102,6 +103,10 @@ public class RestUser {
|
|||||||
return this.user;
|
return this.user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AuthenticationType getAuthenticationType() {
|
||||||
|
return user.getAuthenticationType();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (!(o instanceof RestUser)) {
|
if (!(o instanceof RestUser)) {
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.wisemapping.security;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||||
|
|
||||||
|
import com.wisemapping.model.User;
|
||||||
|
|
||||||
|
public class GoogleAuthenticationProvider implements org.springframework.security.authentication.AuthenticationProvider {
|
||||||
|
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
public UserDetailsService getUserDetailsService() {
|
||||||
|
return userDetailsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||||
|
this.userDetailsService = userDetailsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate the given PreAuthenticatedAuthenticationToken.
|
||||||
|
*
|
||||||
|
* If the principal contained in the authentication object is null, the request will
|
||||||
|
* be ignored to allow other providers to authenticate it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Authentication authenticate(Authentication inputToken) throws AuthenticationException {
|
||||||
|
if (!supports(inputToken.getClass())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (inputToken.getPrincipal() == null) {
|
||||||
|
throw new BadCredentialsException("No pre-authenticated principal found in request.");
|
||||||
|
}
|
||||||
|
UserDetails userDetails = userDetailsService.loadUserByUsername(inputToken.getName());
|
||||||
|
final User user = userDetails.getUser();
|
||||||
|
|
||||||
|
if (!user.isActive()) {
|
||||||
|
throw new BadCredentialsException("User has been disabled for login " + inputToken.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
PreAuthenticatedAuthenticationToken resultToken = new PreAuthenticatedAuthenticationToken(userDetails,
|
||||||
|
inputToken.getCredentials(), userDetails.getAuthorities());
|
||||||
|
resultToken.setDetails(userDetails);
|
||||||
|
|
||||||
|
userDetailsService.getUserService().auditLogin(user);
|
||||||
|
|
||||||
|
return resultToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that this provider only supports PreAuthenticatedAuthenticationToken
|
||||||
|
* (sub)classes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean supports(Class<?> authentication) {
|
||||||
|
return PreAuthenticatedAuthenticationToken.class.isAssignableFrom(authentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
package com.wisemapping.security;
|
package com.wisemapping.security;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import org.springframework.security.crypto.codec.Base64;
|
import org.springframework.security.crypto.codec.Base64;
|
||||||
import org.springframework.security.crypto.codec.Hex;
|
import org.springframework.security.crypto.codec.Hex;
|
||||||
import org.springframework.security.crypto.codec.Utf8;
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
@ -29,7 +31,7 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
|
|
||||||
|
|
||||||
public class LegacyPasswordEncoder implements PasswordEncoder {
|
public class LegacyPasswordEncoder implements PasswordEncoder {
|
||||||
final private static Logger logger = Logger.getLogger(LegacyPasswordEncoder.class);
|
final private static Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
public static final String ENC_PREFIX = "ENC:";
|
public static final String ENC_PREFIX = "ENC:";
|
||||||
private final ShaPasswordEncoder sha1Encoder = new ShaPasswordEncoder();
|
private final ShaPasswordEncoder sha1Encoder = new ShaPasswordEncoder();
|
||||||
|
@ -23,7 +23,6 @@ import com.wisemapping.model.User;
|
|||||||
import com.wisemapping.service.UserService;
|
import com.wisemapping.service.UserService;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ public class ViewBaseSecurityAdvise
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isAllowed(@Nullable User user, Mindmap map) {
|
protected boolean isAllowed(@Nullable User user, Mindmap map) {
|
||||||
System.out.println("VIEWWWWWWWWWWWWW");
|
|
||||||
return getMindmapService().hasPermissions(user, map, CollaborationRole.VIEWER);
|
return getMindmapService().hasPermissions(user, map, CollaborationRole.VIEWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,18 +23,21 @@ import com.wisemapping.exceptions.LockException;
|
|||||||
import com.wisemapping.model.CollaborationRole;
|
import com.wisemapping.model.CollaborationRole;
|
||||||
import com.wisemapping.model.Mindmap;
|
import com.wisemapping.model.Mindmap;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
class LockManagerImpl implements LockManager {
|
class LockManagerImpl implements LockManager {
|
||||||
private static final int ONE_MINUTE_MILLISECONDS = 1000 * 60;
|
private static final int ONE_MINUTE_MILLISECONDS = 1000 * 60;
|
||||||
private final Map<Integer, LockInfo> lockInfoByMapId;
|
private final Map<Integer, LockInfo> lockInfoByMapId;
|
||||||
private final static Timer expirationTimer = new Timer();
|
private final static Timer expirationTimer = new Timer();
|
||||||
final private static Logger logger = Logger.getLogger(LockManagerImpl.class);
|
final private static Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLocked(@NotNull Mindmap mindmap) {
|
public boolean isLocked(@NotNull Mindmap mindmap) {
|
||||||
|
@ -143,15 +143,13 @@ public class MindmapServiceImpl
|
|||||||
public void removeCollaboration(@NotNull Mindmap mindmap, @NotNull Collaboration collaboration) throws CollaborationException {
|
public void removeCollaboration(@NotNull Mindmap mindmap, @NotNull Collaboration collaboration) throws CollaborationException {
|
||||||
// remove collaborator association
|
// remove collaborator association
|
||||||
final Mindmap mindMap = collaboration.getMindMap();
|
final Mindmap mindMap = collaboration.getMindMap();
|
||||||
final Set<Collaboration> collaborations = mindMap.getCollaborations();
|
|
||||||
|
|
||||||
final User creator = mindMap.getCreator();
|
final User creator = mindMap.getCreator();
|
||||||
if (creator.identityEquality(collaboration.getCollaborator())) {
|
if (creator.identityEquality(collaboration.getCollaborator())) {
|
||||||
throw new CollaborationException("User is the creator and must have ownership permissions.Creator Email:" + mindMap.getCreator().getEmail() + ",Collaborator:" + collaboration.getCollaborator().getEmail());
|
throw new CollaborationException("User is the creator and must have ownership permissions.Creator Email:" + mindMap.getCreator().getEmail() + ",Collaborator:" + collaboration.getCollaborator().getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
// When you delete an object from hibernate you have to delete it from *all* collections it exists in...
|
// When you delete an object from hibernate you have to delete it from *all* collections it exists in...
|
||||||
collaborations.remove(collaboration);
|
mindMap.removedCollaboration(collaboration);
|
||||||
mindmapManager.removeCollaboration(collaboration);
|
mindmapManager.removeCollaboration(collaboration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +247,7 @@ public class MindmapServiceImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void revertChange(@NotNull Mindmap mindmap, int historyId)
|
public void revertChange(@NotNull Mindmap mindmap, int historyId)
|
||||||
throws WiseMappingException, IOException {
|
throws WiseMappingException {
|
||||||
final MindMapHistory history = mindmapManager.getHistory(historyId);
|
final MindMapHistory history = mindmapManager.getHistory(historyId);
|
||||||
mindmap.setZippedXml(history.getZippedXml());
|
mindmap.setZippedXml(history.getZippedXml());
|
||||||
updateMindmap(mindmap, true);
|
updateMindmap(mindmap, true);
|
||||||
|
@ -17,13 +17,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.wisemapping.service;
|
package com.wisemapping.service;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.wisemapping.validator.Messages;
|
import com.wisemapping.validator.Messages;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.fluent.Form;
|
import org.apache.http.client.fluent.Form;
|
||||||
import org.apache.http.client.fluent.Request;
|
import org.apache.http.client.fluent.Request;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
@ -35,7 +37,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class RecaptchaService {
|
public class RecaptchaService {
|
||||||
|
|
||||||
final private static Logger logger = Logger.getLogger(RecaptchaService.class);
|
final private static Logger logger = LogManager.getLogger();
|
||||||
final private static String GOOGLE_RECAPTCHA_VERIFY_URL =
|
final private static String GOOGLE_RECAPTCHA_VERIFY_URL =
|
||||||
"https://www.google.com/recaptcha/api/siteverify";
|
"https://www.google.com/recaptcha/api/siteverify";
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ package com.wisemapping.service;
|
|||||||
|
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.model.User;
|
import com.wisemapping.model.User;
|
||||||
|
import com.wisemapping.rest.model.RestResetPasswordResponse;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public interface UserService {
|
public interface UserService {
|
||||||
@ -28,6 +30,10 @@ public interface UserService {
|
|||||||
|
|
||||||
User createUser(@NotNull User user, boolean emailConfirmEnabled, boolean welcomeEmail) throws WiseMappingException;
|
User createUser(@NotNull User user, boolean emailConfirmEnabled, boolean welcomeEmail) throws WiseMappingException;
|
||||||
|
|
||||||
|
User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException;
|
||||||
|
|
||||||
|
User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException;
|
||||||
|
|
||||||
void changePassword(@NotNull User user);
|
void changePassword(@NotNull User user);
|
||||||
|
|
||||||
User getUserBy(String email);
|
User getUserBy(String email);
|
||||||
@ -36,7 +42,7 @@ public interface UserService {
|
|||||||
|
|
||||||
void updateUser(User user);
|
void updateUser(User user);
|
||||||
|
|
||||||
void resetPassword(@NotNull String email) throws InvalidUserEmailException, InvalidAuthSchemaException;
|
RestResetPasswordResponse resetPassword(@NotNull String email) throws InvalidUserEmailException, InvalidAuthSchemaException;
|
||||||
|
|
||||||
void removeUser(@NotNull User user);
|
void removeUser(@NotNull User user);
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@ import com.wisemapping.exceptions.InvalidMindmapException;
|
|||||||
import com.wisemapping.exceptions.WiseMappingException;
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
import com.wisemapping.mail.NotificationService;
|
import com.wisemapping.mail.NotificationService;
|
||||||
import com.wisemapping.model.*;
|
import com.wisemapping.model.*;
|
||||||
|
import com.wisemapping.rest.model.RestResetPasswordAction;
|
||||||
|
import com.wisemapping.rest.model.RestResetPasswordResponse;
|
||||||
|
import com.wisemapping.service.google.GoogleAccountBasicData;
|
||||||
|
import com.wisemapping.service.google.GoogleService;
|
||||||
import com.wisemapping.util.VelocityEngineUtils;
|
import com.wisemapping.util.VelocityEngineUtils;
|
||||||
import com.wisemapping.util.VelocityEngineWrapper;
|
import com.wisemapping.util.VelocityEngineWrapper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -39,7 +43,7 @@ public class UserServiceImpl
|
|||||||
private NotificationService notificationService;
|
private NotificationService notificationService;
|
||||||
private MessageSource messageSource;
|
private MessageSource messageSource;
|
||||||
private VelocityEngineWrapper velocityEngineWrapper;
|
private VelocityEngineWrapper velocityEngineWrapper;
|
||||||
|
private GoogleService googleService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void activateAccount(long code)
|
public void activateAccount(long code)
|
||||||
@ -56,10 +60,15 @@ public class UserServiceImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetPassword(@NotNull String email)
|
public RestResetPasswordResponse resetPassword(@NotNull String email)
|
||||||
throws InvalidUserEmailException, InvalidAuthSchemaException {
|
throws InvalidUserEmailException, InvalidAuthSchemaException {
|
||||||
final User user = userManager.getUserBy(email);
|
final User user = userManager.getUserBy(email);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
|
RestResetPasswordResponse response = new RestResetPasswordResponse();
|
||||||
|
if (user.getAuthenticationType().equals(AuthenticationType.GOOGLE_OAUTH2)) {
|
||||||
|
response.setAction(RestResetPasswordAction.OAUTH2_USER);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
if (user.getAuthenticationType() != AuthenticationType.DATABASE) {
|
if (user.getAuthenticationType() != AuthenticationType.DATABASE) {
|
||||||
throw new InvalidAuthSchemaException("Could not change password for " + user.getAuthenticationType().getCode());
|
throw new InvalidAuthSchemaException("Could not change password for " + user.getAuthenticationType().getCode());
|
||||||
@ -72,6 +81,9 @@ public class UserServiceImpl
|
|||||||
|
|
||||||
// Send an email with the new temporal password ...
|
// Send an email with the new temporal password ...
|
||||||
notificationService.resetPassword(user, password);
|
notificationService.resetPassword(user, password);
|
||||||
|
|
||||||
|
response.setAction(RestResetPasswordAction.EMAIL_SENT);
|
||||||
|
return response;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidUserEmailException("The email '" + email + "' does not exists.");
|
throw new InvalidUserEmailException("The email '" + email + "' does not exists.");
|
||||||
}
|
}
|
||||||
@ -147,6 +159,55 @@ public class UserServiceImpl
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException {
|
||||||
|
try {
|
||||||
|
GoogleAccountBasicData data = googleService.processCallback(callbackCode);
|
||||||
|
User existingUser = userManager.getUserBy(data.getEmail());
|
||||||
|
if (existingUser == null) {
|
||||||
|
User newUser = new User();
|
||||||
|
// new registrations from google starts synched
|
||||||
|
newUser.setGoogleSync(true);
|
||||||
|
newUser.setEmail(data.getEmail());
|
||||||
|
newUser.setFirstname(data.getName());
|
||||||
|
newUser.setLastname(data.getLastName());
|
||||||
|
newUser.setAuthenticationType(AuthenticationType.GOOGLE_OAUTH2);
|
||||||
|
newUser.setGoogleToken(data.getAccessToken());
|
||||||
|
existingUser = this.createUser(newUser, false, true);
|
||||||
|
} else {
|
||||||
|
// user exists and doesnt have confirmed account linking, I must wait for confirmation
|
||||||
|
if (existingUser.getGoogleSync() == null) {
|
||||||
|
existingUser.setGoogleSync(false);
|
||||||
|
existingUser.setSyncCode(callbackCode);
|
||||||
|
existingUser.setGoogleToken(data.getAccessToken());
|
||||||
|
userManager.updateUser(existingUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return existingUser;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new WiseMappingException("Cant create user", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException {
|
||||||
|
User existingUser = userManager.getUserBy(email);
|
||||||
|
// additional security check
|
||||||
|
if (existingUser == null || !existingUser.getSyncCode().equals(code)) {
|
||||||
|
throw new WiseMappingException("User not found / incorrect code");
|
||||||
|
}
|
||||||
|
existingUser.setGoogleSync(true);
|
||||||
|
existingUser.setSyncCode(null);
|
||||||
|
// user will not be able to login again with usr/pwd schema
|
||||||
|
existingUser.setAuthenticationType(AuthenticationType.GOOGLE_OAUTH2);
|
||||||
|
existingUser.setPassword("");
|
||||||
|
userManager.updateUser(existingUser);
|
||||||
|
|
||||||
|
return existingUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Mindmap buildTutorialMindmap(@NotNull String firstName) throws InvalidMindmapException {
|
public Mindmap buildTutorialMindmap(@NotNull String firstName) throws InvalidMindmapException {
|
||||||
//To change body of created methods use File | Settings | File Templates.
|
//To change body of created methods use File | Settings | File Templates.
|
||||||
final Locale locale = LocaleContextHolder.getLocale();
|
final Locale locale = LocaleContextHolder.getLocale();
|
||||||
@ -209,7 +270,11 @@ public class UserServiceImpl
|
|||||||
this.velocityEngineWrapper = velocityEngineWrapper;
|
this.velocityEngineWrapper = velocityEngineWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setGoogleService(GoogleService googleService) {
|
||||||
|
this.googleService = googleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public User getCasUserBy(String uid) {
|
public User getCasUserBy(String uid) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.wisemapping.service.google;
|
||||||
|
|
||||||
|
public class GoogleAccountBasicData {
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
private String accountId;
|
||||||
|
private String name;
|
||||||
|
private String lastName;
|
||||||
|
private String accessToken;
|
||||||
|
private String refreshToken;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountId(String accountId) {
|
||||||
|
this.accountId = accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessToken(String accessToken) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRefreshToken() {
|
||||||
|
return refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRefreshToken(String refreshToken) {
|
||||||
|
this.refreshToken = refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GoogleAccountBasicData [email=" + email + ", accountId=" + accountId + ", name=" + name + ", lastName="
|
||||||
|
+ lastName + ", accessToken=" + accessToken + ", refreshToken=" + refreshToken + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package com.wisemapping.service.google;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.wisemapping.service.http.HttpInvoker;
|
||||||
|
import com.wisemapping.service.http.HttpInvokerContentType;
|
||||||
|
import com.wisemapping.service.http.HttpInvokerException;
|
||||||
|
import com.wisemapping.service.http.HttpMethod;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GoogleService {
|
||||||
|
private HttpInvoker httpInvoker;
|
||||||
|
private String optinConfirmUrl;
|
||||||
|
private String accountBasicDataUrl;
|
||||||
|
private String clientId;
|
||||||
|
private String clientSecret;
|
||||||
|
private String callbackUrl;
|
||||||
|
|
||||||
|
public void setHttpInvoker(HttpInvoker httpInvoker) {
|
||||||
|
this.httpInvoker = httpInvoker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptinConfirmUrl(String optinConfirmUrl) {
|
||||||
|
this.optinConfirmUrl = optinConfirmUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountBasicDataUrl(String accountBasicDataUrl) {
|
||||||
|
this.accountBasicDataUrl = accountBasicDataUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientSecret(String clientSecret) {
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCallbackUrl(String callbackUrl) {
|
||||||
|
this.callbackUrl = callbackUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNodeAsString(JsonNode node, String fieldName) {
|
||||||
|
return getNodeAsString(node, fieldName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNodeAsString(JsonNode node, String fieldName, String defaultValue) {
|
||||||
|
JsonNode subNode = node.get(fieldName);
|
||||||
|
return subNode != null ? subNode.asText() : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getHeaders(String token) {
|
||||||
|
Map<String, String> headers = new HashMap<String, String>();
|
||||||
|
headers.put("Content-type", "application/json");
|
||||||
|
headers.put("Authorization", "Bearer " + token);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GoogleAccountBasicData getAccountBasicData(String token) throws HttpInvokerException {
|
||||||
|
JsonNode response = httpInvoker.invoke(accountBasicDataUrl, null, HttpMethod.GET, this.getHeaders(token), null,
|
||||||
|
null);
|
||||||
|
GoogleAccountBasicData data = new GoogleAccountBasicData();
|
||||||
|
data.setEmail(getNodeAsString(response, "email"));
|
||||||
|
data.setAccountId(getNodeAsString(response, "id"));
|
||||||
|
data.setName(getNodeAsString(response, "given_name", data.getEmail()));
|
||||||
|
data.setLastName(getNodeAsString(response, "family_name"));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getOptinConfirmBody(String code) {
|
||||||
|
Map<String, String> result = new HashMap<String, String>();
|
||||||
|
result.put("client_id", clientId);
|
||||||
|
result.put("client_secret", clientSecret);
|
||||||
|
result.put("code", code);
|
||||||
|
result.put("redirect_uri", callbackUrl);
|
||||||
|
result.put("grant_type", "authorization_code");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GoogleAccountBasicData processCallback(String code)
|
||||||
|
throws HttpInvokerException, JsonMappingException, JsonProcessingException {
|
||||||
|
Map<String, String> body = this.getOptinConfirmBody(code);
|
||||||
|
JsonNode optinConfirmResponse = httpInvoker.invoke(
|
||||||
|
optinConfirmUrl,
|
||||||
|
HttpInvokerContentType.FORM_ENCODED,
|
||||||
|
HttpMethod.POST,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
body);
|
||||||
|
|
||||||
|
String accessToken = getNodeAsString(optinConfirmResponse, "access_token");
|
||||||
|
String refreshToken = getNodeAsString(optinConfirmResponse, "refresh_token");
|
||||||
|
|
||||||
|
GoogleAccountBasicData data = this.getAccountBasicData(accessToken);
|
||||||
|
data.setAccessToken(accessToken);
|
||||||
|
data.setRefreshToken(refreshToken);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
package com.wisemapping.service.http;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class HttpInvoker {
|
||||||
|
|
||||||
|
protected static Logger logger = LogManager.getLogger(HttpInvoker.class);
|
||||||
|
|
||||||
|
private ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
public HttpInvoker() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonNode invoke(
|
||||||
|
String url,
|
||||||
|
HttpInvokerContentType requestContentType,
|
||||||
|
HttpMethod method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
String jsonPayload,
|
||||||
|
Map<String, String> formData)
|
||||||
|
throws HttpInvokerException {
|
||||||
|
String responseBody = null;
|
||||||
|
try {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("finalUrl: " + url);
|
||||||
|
logger.debug("method: " + method);
|
||||||
|
logger.debug("payload: " + jsonPayload);
|
||||||
|
logger.debug("header: " + headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||||
|
HttpRequestBase httpRequst = null;
|
||||||
|
|
||||||
|
// build request
|
||||||
|
if (method.equals(HttpMethod.POST))
|
||||||
|
httpRequst = new HttpPost(url);
|
||||||
|
else if (method.equals(HttpMethod.PUT))
|
||||||
|
httpRequst = new HttpPut(url);
|
||||||
|
else if (method.equals(HttpMethod.GET))
|
||||||
|
httpRequst = new HttpGet(url);
|
||||||
|
else if (method.equals(HttpMethod.DELETE))
|
||||||
|
httpRequst = new HttpDelete(url);
|
||||||
|
else
|
||||||
|
throw new HttpInvokerException("Method " + method + " not suppoprted by http connector");
|
||||||
|
|
||||||
|
if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) {
|
||||||
|
HttpEntity entity = null;
|
||||||
|
if (requestContentType.equals(HttpInvokerContentType.JSON)) {
|
||||||
|
if (jsonPayload == null)
|
||||||
|
throw new HttpInvokerException("Json content is required");
|
||||||
|
entity = new StringEntity(jsonPayload, Charset.forName("UTF-8"));
|
||||||
|
((HttpEntityEnclosingRequestBase) httpRequst).setEntity(entity);
|
||||||
|
}
|
||||||
|
if (requestContentType.equals(HttpInvokerContentType.FORM_ENCODED)) {
|
||||||
|
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
|
||||||
|
Set<String> keys = formData.keySet();
|
||||||
|
for (String key : keys) {
|
||||||
|
nameValuePairs.add(new BasicNameValuePair(key, formData.get(key).toString()));
|
||||||
|
}
|
||||||
|
entity = new UrlEncodedFormEntity(nameValuePairs);
|
||||||
|
((HttpEntityEnclosingRequestBase) httpRequst).setEntity(entity);
|
||||||
|
}
|
||||||
|
if (entity == null)
|
||||||
|
throw new HttpInvokerException("Cant build entity to send");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers != null) {
|
||||||
|
Set<String> keys = headers.keySet();
|
||||||
|
for (String key : keys) {
|
||||||
|
httpRequst.setHeader(key, headers.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestContentType != null)
|
||||||
|
httpRequst.setHeader("Content-Type", requestContentType.getHttpContentType());
|
||||||
|
|
||||||
|
// invoke
|
||||||
|
CloseableHttpResponse response = httpClient.execute(httpRequst);
|
||||||
|
// response process
|
||||||
|
JsonNode root = null;
|
||||||
|
responseBody = response.getEntity() != null && response.getEntity().getContent() != null
|
||||||
|
? IOUtils.toString(response.getEntity().getContent(), (String) null)
|
||||||
|
: null;
|
||||||
|
if (responseBody != null) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("response plain: " + responseBody);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
root = mapper.readTree(responseBody);
|
||||||
|
} catch (Exception e) {
|
||||||
|
int returnCode = response.getStatusLine().getStatusCode();
|
||||||
|
throw new HttpInvokerException("cant transform response to JSON. RQ: " + jsonPayload + ", RS: "
|
||||||
|
+ responseBody + ", status: " + returnCode, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.getStatusLine().getStatusCode() >= 400) {
|
||||||
|
logger.error("error response: " + responseBody);
|
||||||
|
throw new HttpInvokerException("error invoking " + url + ", response: " + responseBody + ", status: "
|
||||||
|
+ response.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRequst.releaseConnection();
|
||||||
|
response.close();
|
||||||
|
httpClient.close();
|
||||||
|
|
||||||
|
return root;
|
||||||
|
} catch (HttpInvokerException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("cant invoke service " + url);
|
||||||
|
logger.error("response: " + responseBody, e);
|
||||||
|
throw new HttpInvokerException("cant invoke service " + url, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.wisemapping.service.http;
|
||||||
|
|
||||||
|
public enum HttpInvokerContentType {
|
||||||
|
|
||||||
|
JSON("application/json"),
|
||||||
|
FORM_ENCODED("application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
private String httpContentType;
|
||||||
|
|
||||||
|
private HttpInvokerContentType(String type) {
|
||||||
|
this.httpContentType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHttpContentType() {
|
||||||
|
return httpContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.wisemapping.service.http;
|
||||||
|
|
||||||
|
public class HttpInvokerException extends Exception {
|
||||||
|
|
||||||
|
public HttpInvokerException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpInvokerException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.wisemapping.service.http;
|
||||||
|
|
||||||
|
public enum HttpMethod {
|
||||||
|
POST, GET, DELETE, PUT
|
||||||
|
}
|
@ -39,6 +39,11 @@ public class UsersController {
|
|||||||
return new ModelAndView("forgot-password");
|
return new ModelAndView("forgot-password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "registration-google", method = RequestMethod.GET)
|
||||||
|
public ModelAndView processGoogleCallback() {
|
||||||
|
return new ModelAndView("registration-google");
|
||||||
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "registration", method = RequestMethod.GET)
|
@RequestMapping(value = "registration", method = RequestMethod.GET)
|
||||||
public ModelAndView showRegistrationPage() {
|
public ModelAndView showRegistrationPage() {
|
||||||
return new ModelAndView("registration");
|
return new ModelAndView("registration");
|
||||||
|
@ -67,4 +67,7 @@ TOO_BIG_MINDMAP=Sie haben das Limit von 5000 Themen in einer Mindmap erreicht.
|
|||||||
SHARE_MAP.EMAIL_SUBJECT={0} hat eine Mindmap mit Ihnen geteilt
|
SHARE_MAP.EMAIL_SUBJECT={0} hat eine Mindmap mit Ihnen geteilt
|
||||||
EMAIL.DO_NOT_REPLAY=Wichtig: Antworten Sie nicht auf diese E-Mail. Wenn Sie weitere Hilfe benötigen oder Bedenken bezüglich Ihres Kontos haben, kontaktieren Sie uns <a href="mailto:{0}">hier</a>.
|
EMAIL.DO_NOT_REPLAY=Wichtig: Antworten Sie nicht auf diese E-Mail. Wenn Sie weitere Hilfe benötigen oder Bedenken bezüglich Ihres Kontos haben, kontaktieren Sie uns <a href="mailto:{0}">hier</a>.
|
||||||
EMAIL.GREETINGS=Hallo
|
EMAIL.GREETINGS=Hallo
|
||||||
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
||||||
|
ZOOM_TO_FIT=Zum Beheben zoomen
|
||||||
|
ZOOM_OUT=Rauszoomen
|
||||||
|
ZOOM_IN=Hineinzoomen
|
@ -69,4 +69,7 @@ SHARE_MAP.EMAIL_SUBJECT={0} has shared a mind map with you
|
|||||||
EMAIL.DO_NOT_REPLAY=Important: Do not reply this email. If you need further help or have any concerns regarding your account, contact us to <a href="mailto:{0}">here</a>.
|
EMAIL.DO_NOT_REPLAY=Important: Do not reply this email. If you need further help or have any concerns regarding your account, contact us to <a href="mailto:{0}">here</a>.
|
||||||
EMAIL.GREETINGS=Hi
|
EMAIL.GREETINGS=Hi
|
||||||
TOO_MANY_INACTIVE_ACCOUNTS=You have shared your mindmaps to more than 20 user that have not registered yet. Please, remove inactive accounts or ask them to register.
|
TOO_MANY_INACTIVE_ACCOUNTS=You have shared your mindmaps to more than 20 user that have not registered yet. Please, remove inactive accounts or ask them to register.
|
||||||
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
||||||
|
ZOOM_TO_FIT=Zoom to fit
|
||||||
|
ZOOM_OUT=Zoom out
|
||||||
|
ZOOM_IN=Zoom in
|
@ -67,4 +67,7 @@ PASSWORD_CHANGED.EMAIL_BODY=<p>Esto es solo una notificación de que su contrase
|
|||||||
SHARE_MAP.EMAIL_SUBJECT={0} te ha compartido un mapa mental
|
SHARE_MAP.EMAIL_SUBJECT={0} te ha compartido un mapa mental
|
||||||
EMAIL.DO_NOT_REPLAY=Importante: No responda este correo electrónico. Si necesita más ayuda o tiene alguna inquietud con respecto a su cuenta, comuníquese con nosotros a <a href="mailto:{0}">aquí</a>.
|
EMAIL.DO_NOT_REPLAY=Importante: No responda este correo electrónico. Si necesita más ayuda o tiene alguna inquietud con respecto a su cuenta, comuníquese con nosotros a <a href="mailto:{0}">aquí</a>.
|
||||||
EMAIL.GREETINGS=Hola
|
EMAIL.GREETINGS=Hola
|
||||||
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
||||||
|
ZOOM_TO_FIT=Centrar
|
||||||
|
ZOOM_OUT=Alejar
|
||||||
|
ZOOM_IN=Acercar
|
@ -67,4 +67,7 @@ TOO_BIG_MINDMAP=Vous avez atteint la limite de 5000 sujets dans une carte mental
|
|||||||
SHARE_MAP.EMAIL_SUBJECT={0} a partagé une carte mentale avec vous
|
SHARE_MAP.EMAIL_SUBJECT={0} a partagé une carte mentale avec vous
|
||||||
EMAIL.DO_NOT_REPLAY=Important : Ne répondez pas à cet e-mail. Si vous avez besoin d'aide supplémentaire ou si vous avez des inquiétudes concernant votre compte, contactez-nous <a href="mailto:{0}">ici</a>.
|
EMAIL.DO_NOT_REPLAY=Important : Ne répondez pas à cet e-mail. Si vous avez besoin d'aide supplémentaire ou si vous avez des inquiétudes concernant votre compte, contactez-nous <a href="mailto:{0}">ici</a>.
|
||||||
EMAIL.GREETINGS=Salut
|
EMAIL.GREETINGS=Salut
|
||||||
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
OWNER_ROLE_CAN_NOT_BE_CHANGED=Owner role can not be change. Please, remove owner from the change list.
|
||||||
|
ZOOM_TO_FIT=Zoomer pour s'adapter
|
||||||
|
ZOOM_OUT=Dézoomer
|
||||||
|
ZOOM_IN=Agrandir
|
@ -134,11 +134,29 @@ security.ldap.auth.attribute=mail
|
|||||||
security.ldap.lastName.attribute=sn
|
security.ldap.lastName.attribute=sn
|
||||||
security.ldap.firstName.attribute=givenName
|
security.ldap.firstName.attribute=givenName
|
||||||
|
|
||||||
|
#######################################################################################
|
||||||
|
# Google OAuth Authentication
|
||||||
|
#######################################################################################
|
||||||
|
# OAuth Client id
|
||||||
|
#security.oauth2.google.clientId=<config settings>
|
||||||
|
# OAuth Client secret
|
||||||
|
#security.oauth2.google.clientSecret=<oauth client>
|
||||||
|
# Redirect to this url, this url must be configured in the google app {baseurl}/c/registration-google
|
||||||
|
#security.oauth2.google.callbackUrl=<oauth callback url>
|
||||||
|
|
||||||
|
# Google service for finish registration process, ie. exchange temporal code for user token
|
||||||
|
security.oauth2.google.confirmUrl=https://oauth2.googleapis.com/token
|
||||||
|
# Google service for get user data (name, email, etc)
|
||||||
|
security.oauth2.google.userinfoUrl=https://www.googleapis.com/oauth2/v3/userinfo
|
||||||
|
# Url for starting auth process with google
|
||||||
|
security.oauth2.google.url=https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${security.oauth2.google.callbackUrl}&prompt=consent&response_type=code&client_id=${security.oauth2.google.clientId}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&state=wisemapping&include_granted_scopes=true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################################
|
||||||
# User Account filtering policies
|
# User Account filtering policies
|
||||||
|
#######################################################################################
|
||||||
|
|
||||||
# Coma separated list of domains and emails ban
|
# Coma separated list of domains and emails ban
|
||||||
#accounts.exclusion.domain=
|
#accounts.exclusion.domain=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<definition name="login" template="/jsp/reactInclude.jsp"/>
|
<definition name="login" template="/jsp/reactInclude.jsp"/>
|
||||||
<definition name="registration" template="/jsp/reactInclude.jsp"/>
|
<definition name="registration" template="/jsp/reactInclude.jsp"/>
|
||||||
|
<definition name="registration-google" template="/jsp/reactInclude.jsp"/>
|
||||||
<definition name="forgot-password" template="/jsp/reactInclude.jsp"/>
|
<definition name="forgot-password" template="/jsp/reactInclude.jsp"/>
|
||||||
<definition name="mindmapList" template="/jsp/reactInclude.jsp"/>
|
<definition name="mindmapList" template="/jsp/reactInclude.jsp"/>
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
<bean id="passwordEncoder" class="com.wisemapping.security.DefaultPasswordEncoderFactories" factory-method="createDelegatingPasswordEncoder"/>
|
<bean id="passwordEncoder" class="com.wisemapping.security.DefaultPasswordEncoderFactories" factory-method="createDelegatingPasswordEncoder"/>
|
||||||
|
|
||||||
<sec:authentication-manager alias="authenticationManager">
|
<sec:authentication-manager alias="authenticationManager">
|
||||||
<sec:authentication-provider ref="dbAuthenticationProvider"/>
|
<sec:authentication-provider ref="dbAuthenticationProvider" />
|
||||||
|
<sec:authentication-provider ref="googleAuthenticationProvider" />
|
||||||
<sec:authentication-provider user-service-ref="userDetailsService"/>
|
<sec:authentication-provider user-service-ref="userDetailsService"/>
|
||||||
</sec:authentication-manager>
|
</sec:authentication-manager>
|
||||||
|
|
||||||
@ -19,4 +20,7 @@
|
|||||||
<property name="userDetailsService" ref="userDetailsService"/>
|
<property name="userDetailsService" ref="userDetailsService"/>
|
||||||
<property name="encoder" ref="passwordEncoder"/>
|
<property name="encoder" ref="passwordEncoder"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
<bean id="googleAuthenticationProvider" class="com.wisemapping.security.GoogleAuthenticationProvider">
|
||||||
|
<property name="userDetailsService" ref="userDetailsService"/>
|
||||||
|
</bean>
|
||||||
</beans>
|
</beans>
|
@ -7,6 +7,7 @@
|
|||||||
http://www.springframework.org/schema/security
|
http://www.springframework.org/schema/security
|
||||||
http://www.springframework.org/schema/security/spring-security.xsd">
|
http://www.springframework.org/schema/security/spring-security.xsd">
|
||||||
|
|
||||||
|
<bean id="passwordEncoder" class="com.wisemapping.security.DefaultPasswordEncoderFactories" factory-method="createDelegatingPasswordEncoder"/>
|
||||||
|
|
||||||
<sec:authentication-manager>
|
<sec:authentication-manager>
|
||||||
<sec:authentication-provider ref="ldapAuthProvider"/>
|
<sec:authentication-provider ref="ldapAuthProvider"/>
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
xmlns:sec="http://www.springframework.org/schema/security"
|
xmlns:sec="http://www.springframework.org/schema/security"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
http://www.springframework.org/schema/security
|
http://www.springframework.org/schema/security
|
||||||
http://www.springframework.org/schema/security/spring-security.xsd">
|
http://www.springframework.org/schema/security/spring-security.xsd">
|
||||||
|
|
||||||
<bean id="custom-firewall" class="org.springframework.security.web.firewall.StrictHttpFirewall">
|
<bean id="custom-firewall" class="org.springframework.security.web.firewall.StrictHttpFirewall">
|
||||||
<property name="allowSemicolon" value="true"/>
|
<property name="allowSemicolon" value="true"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
@ -34,6 +34,9 @@
|
|||||||
|
|
||||||
<sec:intercept-url pattern="/service/users/" method="POST" access="permitAll"/>
|
<sec:intercept-url pattern="/service/users/" method="POST" access="permitAll"/>
|
||||||
<sec:intercept-url pattern="/service/users/resetPassword" method="PUT" access="permitAll"/>
|
<sec:intercept-url pattern="/service/users/resetPassword" method="PUT" access="permitAll"/>
|
||||||
|
|
||||||
|
<sec:intercept-url pattern="/service/oauth2/googlecallback" method="POST" access="permitAll"/>
|
||||||
|
<sec:intercept-url pattern="/service/oauth2/confirmaccountsync" method="PUT" access="permitAll"/>
|
||||||
|
|
||||||
<sec:intercept-url pattern="/service/admin/users/**" access="isAuthenticated() and hasRole('ROLE_ADMIN')"/>
|
<sec:intercept-url pattern="/service/admin/users/**" access="isAuthenticated() and hasRole('ROLE_ADMIN')"/>
|
||||||
<sec:intercept-url pattern="/service/admin/database/**" access="isAuthenticated() and hasRole('ROLE_ADMIN')"/>
|
<sec:intercept-url pattern="/service/admin/database/**" access="isAuthenticated() and hasRole('ROLE_ADMIN')"/>
|
||||||
@ -47,6 +50,7 @@
|
|||||||
<sec:intercept-url pattern="/c/login" access="permitAll"/>
|
<sec:intercept-url pattern="/c/login" access="permitAll"/>
|
||||||
<sec:intercept-url pattern="/c/registration" access="hasRole('ANONYMOUS')"/>
|
<sec:intercept-url pattern="/c/registration" access="hasRole('ANONYMOUS')"/>
|
||||||
<sec:intercept-url pattern="/c/registration-success" access="hasRole('ANONYMOUS')"/>
|
<sec:intercept-url pattern="/c/registration-success" access="hasRole('ANONYMOUS')"/>
|
||||||
|
<sec:intercept-url pattern="/c/registration-google" access="permitAll"/>
|
||||||
<sec:intercept-url pattern="/c/forgot-password" access="hasRole('ANONYMOUS')"/>
|
<sec:intercept-url pattern="/c/forgot-password" access="hasRole('ANONYMOUS')"/>
|
||||||
<sec:intercept-url pattern="/c/forgot-password-success" access="hasRole('ANONYMOUS')"/>
|
<sec:intercept-url pattern="/c/forgot-password-success" access="hasRole('ANONYMOUS')"/>
|
||||||
|
|
||||||
|
@ -18,12 +18,25 @@
|
|||||||
<property name="velocityEngineWrapper" ref="velocityEngineWrapper"/>
|
<property name="velocityEngineWrapper" ref="velocityEngineWrapper"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="httpInvoker" class="com.wisemapping.service.http.HttpInvoker">
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="googleService" class="com.wisemapping.service.google.GoogleService">
|
||||||
|
<property name="httpInvoker" ref="httpInvoker"/>
|
||||||
|
<property name="optinConfirmUrl" value="${security.oauth2.google.confirmUrl}"/>
|
||||||
|
<property name="accountBasicDataUrl" value="${security.oauth2.google.userinfoUrl}"/>
|
||||||
|
<property name="clientId" value="${security.oauth2.google.clientId}"/>
|
||||||
|
<property name="clientSecret" value="${security.oauth2.google.clientSecret}"/>
|
||||||
|
<property name="callbackUrl" value="${security.oauth2.google.callbackUrl}"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="userServiceTarget" class="com.wisemapping.service.UserServiceImpl">
|
<bean id="userServiceTarget" class="com.wisemapping.service.UserServiceImpl">
|
||||||
<property name="userManager" ref="userManager"/>
|
<property name="userManager" ref="userManager"/>
|
||||||
<property name="mindmapService" ref="mindMapServiceTarget"/>
|
<property name="mindmapService" ref="mindMapServiceTarget"/>
|
||||||
<property name="notificationService" ref="notificationService"/>
|
<property name="notificationService" ref="notificationService"/>
|
||||||
<property name="messageSource" ref="messageSource"/>
|
<property name="messageSource" ref="messageSource"/>
|
||||||
<property name="velocityEngineWrapper" ref="velocityEngineWrapper"/>
|
<property name="velocityEngineWrapper" ref="velocityEngineWrapper"/>
|
||||||
|
<property name="googleService" ref="googleService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family:Arial;
|
font-family:Montserrat;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#mindplot {
|
div#mindplot {
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
|
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
|
||||||
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||||
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||||
|
<%@ taglib uri = "http://java.sun.com/jsp/jstl/functions" prefix = "fn" %>
|
||||||
|
|
||||||
<%
|
<%
|
||||||
request.setAttribute("principal", com.wisemapping.security.Utils.getUser());
|
request.setAttribute("principal", com.wisemapping.security.Utils.getUser());
|
||||||
%>
|
%>
|
||||||
|
@ -9,15 +9,13 @@
|
|||||||
<%--@elvariable id="lockInfo" type="com.wisemapping.service.LockInfo"--%>
|
<%--@elvariable id="lockInfo" type="com.wisemapping.service.LockInfo"--%>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="${fn:substring(locale,0,2)}">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<base href="${requestScope['site.baseurl']}/static/webapp/">
|
<base href="${requestScope['site.baseurl']}/static/webapp/">
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
|
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" crossorigin>
|
||||||
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap"/>
|
|
||||||
|
|
||||||
<%@ include file="/jsp/pageHeaders.jsf" %>
|
<%@ include file="/jsp/pageHeaders.jsf" %>
|
||||||
|
|
||||||
<title>Loading ... | WiseMapping</title>
|
<title>Loading ... | WiseMapping</title>
|
||||||
@ -47,8 +45,8 @@
|
|||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root" class="mindplot-root"></div>
|
<div id="root" class="mindplot-root"></div>
|
||||||
|
|
||||||
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/vendors.bundle.js" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/vendors.bundle.js" crossorigin="anonymous" defer></script>
|
||||||
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/app.bundle.js" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/app.bundle.js" crossorigin="anonymous" defer></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -5,17 +5,16 @@
|
|||||||
|
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
|
|
||||||
<html>
|
<html lang="${fn:substring(locale,0,2)}">
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="initial-scale=1">
|
<meta name="viewport" content="initial-scale=1">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<base href="${requestScope['site.baseurl']}/static/mindplot/">
|
<base href="${requestScope['site.baseurl']}/static/mindplot/">
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
|
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" crossorigin>
|
||||||
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap"/>
|
<link rel="preload" href="../../css/viewonly.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
|
|
||||||
<title>${mindmap.title} | <spring:message code="SITE.TITLE"/></title>
|
<title>${mindmap.title} | <spring:message code="SITE.TITLE"/></title>
|
||||||
<link rel="stylesheet" href="../../css/viewonly.css"/>
|
|
||||||
<%@ include file="/jsp/pageHeaders.jsf" %>
|
<%@ include file="/jsp/pageHeaders.jsf" %>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -40,23 +39,6 @@
|
|||||||
</script>
|
</script>
|
||||||
</c:if>
|
</c:if>
|
||||||
|
|
||||||
<c:if test="${requestScope['google.analytics.enabled']}">
|
|
||||||
<!-- Google Ads Sense Config. Lazy loading optimization -->
|
|
||||||
<script type="text/javascript">
|
|
||||||
function downloadJsAtOnload() {
|
|
||||||
setTimeout(function downloadJs() {
|
|
||||||
var element = document.createElement("script");
|
|
||||||
element.setAttribute("data-ad-client", "ca-pub-4996113942657337");
|
|
||||||
element.async = true;
|
|
||||||
element.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
|
|
||||||
document.body.appendChild(element);
|
|
||||||
}, 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener("load", downloadJsAtOnload, false);
|
|
||||||
</script>
|
|
||||||
</c:if>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@ -76,37 +58,36 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" class="mindplot-root">
|
<div id="root" class="mindplot-root">
|
||||||
<mindplot-component id="mindmap-comp"></mindplot-component>
|
<mindplot-component id="mindmap-comp"/>
|
||||||
<div id="mindplot-tooltips" className="wise-editor"></div>
|
</div>
|
||||||
|
<div id="mindplot-tooltips" className="wise-editor"></div>
|
||||||
|
|
||||||
<a href="${requestScope['site.homepage']}" target="new">
|
<a href="${requestScope['site.homepage']}" target="new" aria-label="WiseMapping Homepage">
|
||||||
<div id="footerLogo"></div>
|
<div id="footerLogo"></div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div id="mapDetails">
|
<div id="mapDetails">
|
||||||
<span class="title"><spring:message code="CREATOR"/>:</span><span>${mindmap.creator.fullName}</span>
|
<span class="title"><spring:message code="CREATOR"/>:</span><span>${mindmap.creator.fullName}</span>
|
||||||
<span class="title"><spring:message code="DESCRIPTION"/>:</span><span>${mindmap.title}</span>
|
<span class="title"><spring:message code="DESCRIPTION"/>:</span><span>${mindmap.title}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" src="${requestScope['site.static.js.url']}/mindplot/loader.js" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="${requestScope['site.static.js.url']}/mindplot/loader.js" crossorigin="anonymous" defer></script>
|
||||||
|
|
||||||
<div id="floating-panel">
|
<div id="floating-panel">
|
||||||
<div id="zoom-button">
|
<div id="zoom-button">
|
||||||
<button id="zoom-plus" title="Zoom Out">
|
<button id="zoom-plus" title="<spring:message code="ZOOM_IN"/>" alt="<spring:message code="ZOOM_IN"/>">
|
||||||
<img src="../../images/add.svg" width="24" height="24"/>
|
<img src="../../images/add.svg" width="24" height="24" alt="<spring:message code="ZOOM_IN"/>"/>
|
||||||
</button>
|
</button>
|
||||||
<button id="zoom-minus" title="Zoom In">
|
<button id="zoom-minus" title="<spring:message code="ZOOM_OUT"/>" alt="<spring:message code="ZOOM_OUT"/>">
|
||||||
<img src="../../images/minus.svg" width="24" height="24"/>
|
<img src="../../images/minus.svg" width="24" height="24" alt="<spring:message code="ZOOM_OUT"/>"/>
|
||||||
</button>
|
</button>
|
||||||
<div id="position">
|
<div id="position">
|
||||||
<button id="position-button" title="Center">
|
<button id="position-button" title="<spring:message code="ZOOM_TO_FIT"/>" alt="<spring:message code="ZOOM_TO_FIT"/>">
|
||||||
<img src="../../images/center_focus.svg" width="24" height="24"/>
|
<img src="../../images/center_focus.svg" width="24" height="24" alt="<spring:message code="ZOOM_TO_FIT"/>"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Hook zoom events ...
|
// Hook zoom events ...
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
|
<%@ taglib uri = "http://java.sun.com/jsp/jstl/functions" prefix = "fn" %>
|
||||||
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
|
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="${fn:substring(locale,0,2)}">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<base href="${requestScope['site.baseurl']}/static/webapp/">
|
<base href="${requestScope['site.baseurl']}/static/webapp/">
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
|
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" crossorigin>
|
||||||
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap"/>
|
|
||||||
|
|
||||||
<%@ include file="/jsp/pageHeaders.jsf" %>
|
<%@ include file="/jsp/pageHeaders.jsf" %>
|
||||||
|
|
||||||
<title>Loading | WiseMapping</title>
|
<title>WiseMapping</title>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.serverconfig = {
|
window.serverconfig = {
|
||||||
@ -20,7 +19,8 @@
|
|||||||
analyticsAccount: '${requestScope['google.analytics.account']}',
|
analyticsAccount: '${requestScope['google.analytics.account']}',
|
||||||
clientType: 'rest',
|
clientType: 'rest',
|
||||||
recaptcha2Enabled: ${requestScope['google.recaptcha2.enabled']},
|
recaptcha2Enabled: ${requestScope['google.recaptcha2.enabled']},
|
||||||
recaptcha2SiteKey: '${requestScope['google.recaptcha2.siteKey']}'
|
recaptcha2SiteKey: '${requestScope['google.recaptcha2.siteKey']}',
|
||||||
|
googleOauth2Url: '${requestScope['security.oauth2.google.url']}'
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -34,7 +34,7 @@
|
|||||||
element.async = true;
|
element.async = true;
|
||||||
element.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
|
element.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
|
||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
}, 2000);
|
}, 50);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("load", downloadJsAtOnload, false);
|
window.addEventListener("load", downloadJsAtOnload, false);
|
||||||
@ -46,8 +46,8 @@
|
|||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|
||||||
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/vendors.bundle.js" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/vendors.bundle.js" crossorigin="anonymous" async></script>
|
||||||
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/app.bundle.js" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="${requestScope['site.static.js.url']}/webapp/app.bundle.js" crossorigin="anonymous" async></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user