Compare commits
70 Commits
55c5126d95
...
1c73a8d79d
Author | SHA1 | Date |
---|---|---|
Paulo Gustavo Veiga | 1c73a8d79d | |
Paulo Gustavo Veiga | 68c8f5c6b8 | |
Paulo Gustavo Veiga | d26b516eb9 | |
Paulo Gustavo Veiga | 538083ae83 | |
Paulo Gustavo Veiga | 60923e4c8b | |
Paulo Gustavo Veiga | 214e3938c1 | |
Paulo Gustavo Veiga | f49ae37866 | |
Paulo Gustavo Veiga | ad158e4821 | |
Paulo Gustavo Veiga | 769968376b | |
Paulo Gustavo Veiga | 9668823c31 | |
Paulo Gustavo Veiga | 55c104cfbe | |
Paulo Gustavo Veiga | 92edef9bd6 | |
Paulo Gustavo Veiga | 884a93478b | |
Paulo Gustavo Veiga | 63975464ca | |
Paulo Gustavo Veiga | 2b918a0df3 | |
Paulo Gustavo Veiga | 9c1320b63b | |
Paulo Gustavo Veiga | 1589665633 | |
Paulo Gustavo Veiga | 479eb6db2c | |
Paulo Gustavo Veiga | a739bb3e0b | |
Paulo Gustavo Veiga | 50e4a68d28 | |
Paulo Gustavo Veiga | 8ec7c4edea | |
Paulo Gustavo Veiga | 480fd49fd0 | |
Paulo Gustavo Veiga | 61c691fc82 | |
Paulo Gustavo Veiga | 3eaeb8f500 | |
Paulo Gustavo Veiga | 07e8259417 | |
Paulo Gustavo Veiga | ab15fb2d36 | |
Paulo Veiga | 315267e68c | |
Paulo Veiga | 881a16b908 | |
Paulo Veiga | dd8f5ab1ea | |
Paulo Veiga | 0c37ed904a | |
Paulo Gustavo Veiga | 946ef517d3 | |
Paulo Gustavo Veiga | 5116a18952 | |
Paulo Veiga | 3467114a8a | |
Paulo Gustavo Veiga | cda97891ba | |
Paulo Gustavo Veiga | 675802dab7 | |
Paulo Gustavo Veiga | 8b72f75b56 | |
Paulo Gustavo Veiga | e85a670695 | |
Paulo Gustavo Veiga | 28dc77c501 | |
Paulo Gustavo Veiga | c4ae51b50e | |
Paulo Gustavo Veiga | 9912897879 | |
Paulo Gustavo Veiga | 8d3983fd08 | |
Paulo Gustavo Veiga | 169c6e6538 | |
Paulo Gustavo Veiga | 4bb2960716 | |
Paulo Gustavo Veiga | 70c0b0c532 | |
Paulo Gustavo Veiga | 0b96026507 | |
Paulo Gustavo Veiga | 87712b2493 | |
Paulo Gustavo Veiga | c783feef65 | |
Paulo Gustavo Veiga | ea12d0246c | |
Paulo Gustavo Veiga | 4f94d7117a | |
Paulo Gustavo Veiga | abcd0d8515 | |
Paulo Gustavo Veiga | 1742b268a9 | |
Paulo Gustavo Veiga | aaa8d5f0f3 | |
Paulo Gustavo Veiga | 553688b070 | |
Paulo Gustavo Veiga | d2788ae00e | |
Paulo Gustavo Veiga | d4840b9c20 | |
Paulo Gustavo Veiga | b8601d7029 | |
Paulo Gustavo Veiga | 86682ca7d8 | |
Paulo Gustavo Veiga | 762ebabe7e | |
Paulo Gustavo Veiga | 30b2e7e8eb | |
Paulo Gustavo Veiga | 5844663701 | |
Paulo Gustavo Veiga | 734ec3df67 | |
Paulo Gustavo Veiga | 40afd70780 | |
Paulo Gustavo Veiga | 4ebef65728 | |
Paulo Gustavo Veiga | e55e7e8867 | |
Paulo Gustavo Veiga | 1340fff68a | |
Paulo Gustavo Veiga | 68aa7c20eb | |
Paulo Gustavo Veiga | 963ed70d8d | |
Paulo Gustavo Veiga | 0090464d88 | |
Paulo Gustavo Veiga | 53173ec75d | |
Paulo Gustavo Veiga | a66dff8ae4 |
|
@ -0,0 +1,15 @@
|
|||
# WiseMapping Public License Version 1.0 (WPL)
|
||||
|
||||
WiseMapping open source edition is licensed under the WiseMapping Public License Version 1.0. It is basically Apache License Version 2.0 plus the "powered by wisemapping" text requirement on every single page (the "License") unless we authorize you to remove it.
|
||||
The WiseMapping Public License Version 1.0 ("WPL") consists of the [APACHE LICENSE, VERSION 2.0](http://www.apache.org/licenses/LICENSE-2.0), modified to be specific to WiseMapping, with the Additional Terms in Exhibit B.
|
||||
|
||||
Unless Required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
## EXHIBIT B - WiseMapping Public License.
|
||||
Additional Terms applicable to the WiseMapping Public License.
|
||||
I. Effect.
|
||||
These additional terms described in this wiseMapping Public License - Additional Terms shall apply to the Covered Code under this License.
|
||||
II. WiseMapping and "powered by WiseMapping" text.
|
||||
This License does not grant any rights to use the trademarks "WiseMapping" even if such marks are included in the Original Code or Modifications.
|
||||
However, in addition to the other notice obligations, unless wisemapping founders authorize you by email not to do it, (1) all copies of the Original Code in Executable and Source Code form must, as a form of attribution of the original author, include on each user interface screen (i) the "powered by WiseMapping" text; and (2) all derivative works and copies of derivative works of the Covered Code in Executable and Source Code form must include on each user interface screen (i) the "powered by WiseMapping" text. In addition, the "powered by WiseMapping" text, as appropriate, must be visible to all users, must appear in each user interface screen, and must be in the same position. When users click on the "powered by WiseMapping" text it must direct them to http://www.wisemapping.com. This obligation shall also apply to any copies or derivative works which are distributed under the alternative terms of Section 3.6 and this obligation must be included in any such license
|
|
@ -96,5 +96,5 @@ After credential was created, Google will show you the clientId and clientSecret
|
|||
## License
|
||||
|
||||
The source code is Licensed under the WiseMapping Open License, Version 1.0 (the “License”);
|
||||
You may obtain a copy of the License at: [https://wisemapping.atlassian.net/wiki/display/WS/License]
|
||||
You may obtain a copy of the License at: [https://bitbucket.org/wisemapping/wisemapping-open-source/src/develop/license.md](https://bitbucket.org/wisemapping/wisemapping-open-source/src/develop/LICENSE.md)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ pipelines:
|
|||
# Compile sources ...
|
||||
- curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
|
||||
- . $HOME/.nvm/nvm.sh && nvm install node
|
||||
- mvn -B verify --file pom.xml
|
||||
- mvn clean install --file pom.xml -DskipTests
|
||||
# Publish to docker repo ...
|
||||
- docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD
|
||||
- docker build -t wisemapping/wisemapping:latest -f distribution/Dockerfile wise-webapp/target/
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# Database Configuration
|
||||
|
||||
## Overview
|
||||
|
||||
WiseMapping supports a wide variety of databases. However, we run intensively tests over HSQL and MySQL database.
|
||||
|
||||
* HyperSQL: Automatically configured when you compile WiseMapping and It's used primarily for testing. Additionally, the binary distribution already has an instance configured to provide a single click installation.
|
||||
* MySQL: This version is the most tested database we support. MySQL is the database use in http://www.wisemapping.com and it's the suggested version for production environments.
|
||||
* PostgreSQL: Scripts are distributed for the creation and configuration of the it. You will find them within "config/postgres" directory in the binary distribution. Additionally, JDBC driver need to be added to the container.
|
||||
* Others: In spite of the fact that we don't provide yet initialization scripts for others databases, WiseMapping can be deployed in any relational database. Please, contact us if you have any particular question on this area.
|
||||
|
||||
* In the following section, you are going to find a detailed explanation how to configure you WiseMapping using MySQL 5.5.
|
||||
|
||||
## MySQL Installation
|
||||
### Prerequisites
|
||||
* Download and install MySQL. You can download it for free from: http://dev.mysql.com/downloads/
|
||||
Running SQL Scripts
|
||||
Inside the WiseMapping binary distribution, you will find a directory "config/mysql". It contains all the SQL script required to configure a new WiseMapping database instance.
|
||||
|
||||
You will find 4 scripts:
|
||||
* create-database.sql: Create all wisemapping database and wisemapping user.
|
||||
* create-schemas.sql: Create all database tables and index.
|
||||
* apopulate-schemas.sql: Creates a mind map example and an a test user "test@wisemapping.org" with password "test".
|
||||
* drop-schemas.sql: Drop all wisemapping tables in case you want to have a fresh installation.
|
||||
|
||||
There are a lot of good tools you can use to run this scripts (eg: MySQLWorkbench). However, the simples way is to use the command line tool that is distributed as part of the MySQL installation.
|
||||
If you are one brave hearts that is not afraid of the command line tools, open a terminar and execute the following lines:
|
||||
~~~~
|
||||
cd <WISEMAPPING-DIR>/config/database/mysql
|
||||
# Default MySQL installation creates a "root" user with empty password. You can connect to the database with this user if you are # logged in same machine where the database is installed and must be executed logged as "root"
|
||||
#
|
||||
# If you have changed the default database "root" password , you need to specify an additional -p parameter and provide the
|
||||
# new password.
|
||||
mysql -uroot < create-database.sql
|
||||
|
||||
# Create tables and default tests user
|
||||
mysql -uwisemapping -Dwisemapping -ppassword < create-schemas.sql
|
||||
mysql -uwisemapping -Dwisemapping -ppassword < apopulate-schemas.sql
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
Great, you have configured you database !. Let's configure WiseMapping now.
|
||||
|
|
@ -21,7 +21,7 @@ RUN cd ${WEBAPP_TARGET_DIR} && jar -xvf /tmp/wisemapping.war
|
|||
RUN rm /tmp/wisemapping.war
|
||||
|
||||
# Change logger to
|
||||
RUN cp ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j-stdout.xml ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j.xml
|
||||
RUN cp ${WEBAPP_TARGET_DIR}/WEB-INF/log4j2-stdout.xml ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j2.xml
|
||||
|
||||
# Add support for proxy
|
||||
RUN sed -i 's|\
|
||||
|
|
15
license.txt
15
license.txt
|
@ -1,15 +0,0 @@
|
|||
Copyright [2014] [wisemapping]
|
||||
|
||||
Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
"powered by wisemapping" text requirement on every single page;
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the license at
|
||||
|
||||
http://www.wisemapping.org/license
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
5
pom.xml
5
pom.xml
|
@ -46,6 +46,11 @@
|
|||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
<mkdir dir="target/wisemapping-mindplot"/>
|
||||
<exec executable="npm" dir="target" failonerror="true">
|
||||
<arg value="pack"/>
|
||||
<arg value="@wisemapping/mindplot@5.1.1"/>
|
||||
<arg value="@wisemapping/mindplot@5.1.2"/>
|
||||
</exec>
|
||||
<exec executable="tar" dir="target" failonerror="true">
|
||||
<arg value="-xvzf"/>
|
||||
<arg value="wisemapping-mindplot-5.1.1.tgz"/>
|
||||
<arg value="wisemapping-mindplot-5.1.2.tgz"/>
|
||||
<arg value="-C"/>
|
||||
<arg value="wisemapping-mindplot"/>
|
||||
</exec>
|
||||
|
@ -42,11 +42,11 @@
|
|||
<mkdir dir="target/wisemapping-webapp"/>
|
||||
<exec executable="npm" dir="target" failonerror="true">
|
||||
<arg value="pack"/>
|
||||
<arg value="@wisemapping/webapp@5.1.1"/>
|
||||
<arg value="@wisemapping/webapp@5.1.2"/>
|
||||
</exec>
|
||||
<exec executable="tar" dir="target" failonerror="true">
|
||||
<arg value="-xvzf"/>
|
||||
<arg value="wisemapping-webapp-5.1.1.tgz"/>
|
||||
<arg value="wisemapping-webapp-5.1.2.tgz"/>
|
||||
<arg value="-C"/>
|
||||
<arg value="wisemapping-webapp"/>
|
||||
</exec>
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
</parent>
|
||||
|
||||
<properties>
|
||||
<org.springframework.version>6.0.10</org.springframework.version>
|
||||
<org.springframework.addons>6.1.1</org.springframework.addons>
|
||||
<hibernate.version>6.2.6.Final</hibernate.version>
|
||||
<hibernate-validator.version>6.0.21.Final</hibernate-validator.version>
|
||||
<org.springframework.version>6.0.14</org.springframework.version>
|
||||
<org.springframework.addons>6.1.5</org.springframework.addons>
|
||||
<spring-security-taglibs.version>6.0.2</spring-security-taglibs.version>
|
||||
</properties>
|
||||
|
||||
|
@ -51,6 +49,16 @@
|
|||
<version>${org.springframework.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-messaging</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-websocket</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
|
@ -76,8 +84,14 @@
|
|||
<!-- Hibernate -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core-jakarta</artifactId>
|
||||
<version>5.6.15.Final</version>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>6.1.7.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<version>4.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Hibernate Validator -->
|
||||
|
@ -120,12 +134,12 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>5.3.15</version>
|
||||
<version>6.0.6</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -133,7 +147,6 @@
|
|||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
|
@ -165,26 +178,20 @@
|
|||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.32</version>
|
||||
<scope>runtime</scope>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.hibernate</groupId>-->
|
||||
<!-- <artifactId>hibernate-ehcache</artifactId>-->
|
||||
<!-- <version>5.6.15.Final</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>javax.cache</groupId>-->
|
||||
<!-- <artifactId>cache-api</artifactId>-->
|
||||
<!-- <version>1.1.1</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.angus</groupId>
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
|
@ -348,27 +355,6 @@
|
|||
</profiles>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.hibernate.orm.tooling</groupId>-->
|
||||
<!-- <artifactId>hibernate-enhance-maven-plugin</artifactId>-->
|
||||
<!-- <version>${hibernate.version}</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <phase>compile</phase>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <failOnError>true</failOnError>-->
|
||||
<!-- <enableLazyInitialization>true</enableLazyInitialization>-->
|
||||
<!-- <enableDirtyTracking>true</enableDirtyTracking>-->
|
||||
<!-- <enableAssociationManagement>true</enableAssociationManagement>-->
|
||||
<!-- <enableExtendedEnhancement>false</enableExtendedEnhancement>-->
|
||||
<!-- <enableExtendedEnhancement>false</enableExtendedEnhancement>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>enhance</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package com.wisemapping.config;
|
||||
|
||||
import com.wisemapping.exceptions.AccessDeniedSecurityException;
|
||||
import com.wisemapping.exceptions.MapNotPublicSecurityException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.transaction.TransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
@ -11,11 +14,15 @@ import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
|
|||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
public class AppConfig {
|
||||
@EnableTransactionManagement
|
||||
@ComponentScan
|
||||
@ImportResource("classpath:spring/wisemapping-common.xml")
|
||||
public class Application {
|
||||
|
||||
@Autowired
|
||||
TransactionManager txManager;
|
||||
|
||||
@Bean
|
||||
HandlerExceptionResolver errorHandler() {
|
|
@ -0,0 +1,34 @@
|
|||
package com.wisemapping.config;
|
||||
|
||||
import com.wisemapping.security.MapAccessPermissionEvaluation;
|
||||
import com.wisemapping.security.ReadSecurityAdvise;
|
||||
import com.wisemapping.security.UpdateSecurityAdvise;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
|
||||
@Configuration
|
||||
@EnableMethodSecurity(
|
||||
securedEnabled = true,
|
||||
jsr250Enabled = true)
|
||||
public class MethodSecurityConfig {
|
||||
|
||||
@Autowired
|
||||
private ReadSecurityAdvise readAdvice;
|
||||
|
||||
@Autowired
|
||||
private UpdateSecurityAdvise updateAdvice;
|
||||
|
||||
@Bean
|
||||
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
||||
DefaultMethodSecurityExpressionHandler expressionHandler =
|
||||
new DefaultMethodSecurityExpressionHandler();
|
||||
|
||||
final MapAccessPermissionEvaluation permissionEvaluator = new MapAccessPermissionEvaluation(readAdvice, updateAdvice);
|
||||
expressionHandler.setPermissionEvaluator(permissionEvaluator);
|
||||
return expressionHandler;
|
||||
}
|
||||
}
|
|
@ -34,6 +34,22 @@ public class SecurityConfig {
|
|||
firewall.setAllowSemicolon(true);
|
||||
return firewall;
|
||||
}
|
||||
@Bean
|
||||
@Order(1)
|
||||
public SecurityFilterChain embeddedDisabledXOrigin(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception {
|
||||
final MvcRequestMatcher.Builder mvcMatcher = new MvcRequestMatcher.Builder(introspector).servletPath("/c");
|
||||
http
|
||||
.securityMatchers((matchers) ->
|
||||
matchers.requestMatchers(mvcMatcher.pattern(("/maps/*/embed"))))
|
||||
.authorizeHttpRequests(
|
||||
(auth) -> auth.requestMatchers(mvcMatcher.pattern("/maps/*/embed")).permitAll())
|
||||
.headers((header -> header.frameOptions()
|
||||
.disable()
|
||||
))
|
||||
.csrf(AbstractHttpConfigurer::disable);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(2)
|
||||
|
@ -44,13 +60,12 @@ public class SecurityConfig {
|
|||
matchers.requestMatchers(serviceMapper.pattern(("/**"))))
|
||||
.authorizeHttpRequests(auth ->
|
||||
auth
|
||||
.requestMatchers("/users/").permitAll()
|
||||
.requestMatchers("/users/resetPassword").permitAll()
|
||||
.requestMatchers("/oauth2/googlecallback").permitAll()
|
||||
.requestMatchers("/oauth2/confirmaccountsync").permitAll()
|
||||
.requestMatchers("/admin/**").hasAnyRole("ADMIN")
|
||||
.requestMatchers("/**").hasAnyRole("USER", "ADMIN")
|
||||
|
||||
.requestMatchers(serviceMapper.pattern("/users/")).permitAll()
|
||||
.requestMatchers(serviceMapper.pattern("/users/resetPassword")).permitAll()
|
||||
.requestMatchers(serviceMapper.pattern("/oauth2/googlecallback")).permitAll()
|
||||
.requestMatchers(serviceMapper.pattern("/oauth2/confirmaccountsync")).permitAll()
|
||||
.requestMatchers(serviceMapper.pattern("/admin/**")).hasAnyRole("ADMIN")
|
||||
.requestMatchers(serviceMapper.pattern("/**")).hasAnyRole("USER", "ADMIN")
|
||||
)
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.httpBasic(httpBasic -> {
|
||||
|
@ -60,7 +75,7 @@ public class SecurityConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@Order(1)
|
||||
@Order(3)
|
||||
public SecurityFilterChain mvcFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception {
|
||||
final AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler();
|
||||
authenticationSuccessHandler.setAlwaysUseDefaultTargetUrl(false);
|
||||
|
@ -76,12 +91,20 @@ public class SecurityConfig {
|
|||
.authorizeHttpRequests(
|
||||
(auth) ->
|
||||
auth
|
||||
.requestMatchers("/login", "logout").permitAll()
|
||||
.requestMatchers("/registration", "registration-success", "/registration-google").permitAll()
|
||||
.requestMatchers("/forgot-password", "/forgot-password-success").permitAll()
|
||||
.requestMatchers("/maps/*/embed", "/maps/*/try", "/maps/*/public").permitAll()
|
||||
.requestMatchers("/restful/maps/*/document/xml-pub").permitAll()
|
||||
.requestMatchers("/**").hasAnyRole("USER", "ADMIN")
|
||||
.requestMatchers(mvcMatcher.pattern("/login")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/logout")).permitAll()
|
||||
|
||||
.requestMatchers(mvcMatcher.pattern("/registration")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/registration-success")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/registration-google")).permitAll()
|
||||
|
||||
.requestMatchers(mvcMatcher.pattern("/forgot-password")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/forgot-password-success")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/maps/*/try")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/maps/*/public")).permitAll()
|
||||
.requestMatchers(restfullMapper.pattern("/maps/*/document/xml-pub")).permitAll()
|
||||
.requestMatchers(mvcMatcher.pattern("/**")).hasAnyRole("USER", "ADMIN")
|
||||
.requestMatchers(restfullMapper.pattern("/**")).hasAnyRole("USER", "ADMIN")
|
||||
.anyRequest().authenticated())
|
||||
.formLogin((loginForm) ->
|
||||
loginForm.loginPage("/c/login")
|
||||
|
@ -100,22 +123,32 @@ public class SecurityConfig {
|
|||
.tokenValiditySeconds(2419200)
|
||||
.rememberMeParameter("remember-me"
|
||||
).authenticationSuccessHandler(authenticationSuccessHandler)
|
||||
)
|
||||
).headers((header -> header.frameOptions()
|
||||
.disable()
|
||||
))
|
||||
.csrf((csrf) ->
|
||||
csrf.ignoringRequestMatchers("/logout"));
|
||||
csrf.ignoringRequestMatchers(mvcMatcher.pattern("/logout")));
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(3)
|
||||
@Order(4)
|
||||
public SecurityFilterChain shareResourcesFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception {
|
||||
final MvcRequestMatcher.Builder restfullMapper = new MvcRequestMatcher.Builder(introspector);
|
||||
|
||||
return http.authorizeHttpRequests(
|
||||
(auth) ->
|
||||
auth.requestMatchers("/static/**", "/css/**", "/js/**", "/images/**", "/").permitAll()
|
||||
auth.requestMatchers(restfullMapper.pattern("/static/**")).permitAll().
|
||||
requestMatchers(restfullMapper.pattern("/css/**")).permitAll().
|
||||
requestMatchers(restfullMapper.pattern("/js/**")).permitAll().
|
||||
requestMatchers(restfullMapper.pattern("/images/**")).permitAll().
|
||||
requestMatchers(restfullMapper.pattern("/*")).permitAll()
|
||||
).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() {
|
||||
final UserDetailsService result = new UserDetailsService();
|
||||
|
|
|
@ -19,14 +19,21 @@ package com.wisemapping.dao;
|
|||
|
||||
import com.wisemapping.model.Label;
|
||||
import com.wisemapping.model.User;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LabelManagerImpl extends HibernateDaoSupport
|
||||
@Repository("labelManager")
|
||||
public class LabelManagerImpl
|
||||
implements LabelManager {
|
||||
@Resource
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Override
|
||||
public void addLabel(@NotNull final Label label) {
|
||||
|
@ -35,31 +42,37 @@ public class LabelManagerImpl extends HibernateDaoSupport
|
|||
|
||||
@Override
|
||||
public void saveLabel(@NotNull final Label label) {
|
||||
currentSession().save(label);
|
||||
getSession().persist(label);
|
||||
}
|
||||
|
||||
private Session getSession() {
|
||||
return sessionFactory.getCurrentSession();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Label> getAllLabels(@NotNull final User user) {
|
||||
var query = currentSession().createQuery("from com.wisemapping.model.Label wisemapping where creator_id=:creatorId");
|
||||
query.setParameter("creatorId", user.getId());
|
||||
final SelectionQuery<Label> query = getSession().createSelectionQuery("from com.wisemapping.model.Label wisemapping where creator=:creatorId", Label.class);
|
||||
query.setParameter("creatorId", user);
|
||||
return query.list();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Label getLabelById(int id, @NotNull final User user) {
|
||||
var query = currentSession().createQuery("from com.wisemapping.model.Label wisemapping where id=:id and creator=:creator");
|
||||
final Session session = getSession();
|
||||
final SelectionQuery<Label> query = session.createSelectionQuery("from com.wisemapping.model.Label wisemapping where id=:id and creator=:creator", Label.class);
|
||||
query.setParameter("id", id);
|
||||
query.setParameter("creator", user);
|
||||
return getFirst(query.list());
|
||||
|
||||
final List<Label> resultList = query.getResultList();
|
||||
return getFirst(resultList);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Label getLabelByTitle(@NotNull String title, @NotNull final User user) {
|
||||
var query = currentSession().createQuery("from com.wisemapping.model.Label wisemapping where title=:title and creator=:creator");
|
||||
final SelectionQuery<Label> query = getSession().createSelectionQuery("from com.wisemapping.model.Label wisemapping where title=:title and creator=:creator", Label.class);
|
||||
query.setParameter("title", title);
|
||||
query.setParameter("creator", user);
|
||||
return getFirst(query.list());
|
||||
|
@ -67,10 +80,11 @@ public class LabelManagerImpl extends HibernateDaoSupport
|
|||
|
||||
@Override
|
||||
public void removeLabel(@NotNull Label label) {
|
||||
getHibernateTemplate().delete(label);
|
||||
getSession().remove(label);
|
||||
}
|
||||
|
||||
@Nullable private Label getFirst(List<Label> labels) {
|
||||
@Nullable
|
||||
private Label getFirst(final List<Label> labels) {
|
||||
Label result = null;
|
||||
if (labels != null && !labels.isEmpty()) {
|
||||
result = labels.get(0);
|
||||
|
|
|
@ -50,17 +50,11 @@ public interface MindmapManager {
|
|||
|
||||
void removeCollaboration(Collaboration collaboration);
|
||||
|
||||
List<Mindmap> search(MindMapCriteria criteria);
|
||||
|
||||
List<Mindmap> search(MindMapCriteria criteria, int maxResult);
|
||||
|
||||
List<MindMapHistory> getHistoryFrom(int mindmapId);
|
||||
|
||||
MindMapHistory getHistory(int historyId);
|
||||
|
||||
void updateCollaboration(@NotNull Collaboration collaboration);
|
||||
|
||||
void purgeHistory(int mapId) throws IOException;
|
||||
|
||||
List<Mindmap> findMindmapByUser(User user);
|
||||
}
|
||||
|
|
|
@ -19,30 +19,31 @@
|
|||
package com.wisemapping.dao;
|
||||
|
||||
import com.wisemapping.model.*;
|
||||
import com.wisemapping.util.ZipUtils;
|
||||
import jakarta.persistence.Query;
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.criterion.Junction;
|
||||
import org.hibernate.criterion.Order;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.criterion.SimpleExpression;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaDelete;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.orm.hibernate5.HibernateTemplate;
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
@Repository("mindmapManager")
|
||||
public class MindmapManagerImpl
|
||||
extends HibernateDaoSupport
|
||||
implements MindmapManager {
|
||||
@Resource
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Override
|
||||
public Collaborator findCollaborator(@NotNull final String email) {
|
||||
final Collaborator collaborator;
|
||||
Query query = currentSession().createQuery("from com.wisemapping.model.Collaborator collaborator where email=:email");
|
||||
final SelectionQuery<Collaborator> query = getSession().createSelectionQuery("from com.wisemapping.model.Collaborator collaborator where email=:email", Collaborator.class);
|
||||
query.setParameter("email", email);
|
||||
|
||||
final List<Collaborator> collaborators = query.getResultList();
|
||||
|
@ -55,137 +56,87 @@ public class MindmapManagerImpl
|
|||
return collaborator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mindmap> search(MindMapCriteria criteria) {
|
||||
return search(criteria, -1);
|
||||
private Session getSession() {
|
||||
return sessionFactory.getCurrentSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MindMapHistory> getHistoryFrom(int mindmapId) {
|
||||
final Criteria hibernateCriteria = currentSession().createCriteria(MindMapHistory.class);
|
||||
hibernateCriteria.add(Restrictions.eq("mindmapId", mindmapId));
|
||||
hibernateCriteria.addOrder(Order.desc("creationTime"));
|
||||
final Session session = getSession();
|
||||
final CriteriaBuilder cb = session.getCriteriaBuilder();
|
||||
|
||||
// This line throws errors in some environments, so getting all history and taking firsts 10 records
|
||||
hibernateCriteria.setMaxResults(30);
|
||||
return hibernateCriteria.list();
|
||||
final CriteriaQuery<MindMapHistory> cr = cb.createQuery(MindMapHistory.class);
|
||||
final Root<MindMapHistory> root = cr.from(MindMapHistory.class);
|
||||
|
||||
final CriteriaQuery<MindMapHistory> select = cr.select(root)
|
||||
.where(cb.equal(root.get("mindmapId"), mindmapId))
|
||||
.orderBy(cb.desc(root.get("creationTime")));
|
||||
|
||||
return session.
|
||||
createQuery(select)
|
||||
.setMaxResults(30)
|
||||
.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MindMapHistory getHistory(int historyId) {
|
||||
return getHibernateTemplate().get(MindMapHistory.class, historyId);
|
||||
final Session session = getSession();
|
||||
return session.find(MindMapHistory.class, historyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCollaboration(@NotNull Collaboration collaboration) {
|
||||
getHibernateTemplate().save(collaboration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void purgeHistory(int mapId) throws IOException {
|
||||
final Criteria hibernateCriteria = currentSession().createCriteria(MindMapHistory.class);
|
||||
hibernateCriteria.add(Restrictions.eq("mindmapId", mapId));
|
||||
hibernateCriteria.addOrder(Order.desc("creationTime"));
|
||||
|
||||
final List<MindMapHistory> historyList = hibernateCriteria.list();
|
||||
|
||||
final Mindmap mindmap = this.getMindmapById(mapId);
|
||||
if (mindmap != null) {
|
||||
final Calendar yearAgo = Calendar.getInstance();
|
||||
yearAgo.add(Calendar.MONTH, -12);
|
||||
|
||||
// If the map has not been modified in the last months, it means that I don't need to keep all the history ...
|
||||
int max = mindmap.getLastModificationTime().before(yearAgo) ? 10 : 25;
|
||||
|
||||
final HibernateTemplate hibernateTemplate = getHibernateTemplate();
|
||||
for (MindMapHistory history : historyList) {
|
||||
byte[] zippedXml = history.getZippedXml();
|
||||
if (new String(zippedXml).startsWith("<map")) {
|
||||
history.setZippedXml(ZipUtils.bytesToZip(zippedXml));
|
||||
hibernateTemplate.update(history);
|
||||
}
|
||||
}
|
||||
|
||||
if (historyList.size() > max) {
|
||||
for (int i = max; i < historyList.size(); i++) {
|
||||
hibernateTemplate.delete(historyList.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
final Session session = getSession();
|
||||
session.persist(collaboration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mindmap> findMindmapByUser(@NotNull User user) {
|
||||
|
||||
final Mindmap collaborator;
|
||||
final Query query = currentSession()
|
||||
.createQuery("from com.wisemapping.model.Mindmap m where m.id in (select c.mindMap.id from com.wisemapping.model.Collaboration as c where c.collaborator.id=:collabId )");
|
||||
final SelectionQuery<Mindmap> query = getSession()
|
||||
.createSelectionQuery("from com.wisemapping.model.Mindmap m where m.id in (select c.mindMap.id from com.wisemapping.model.Collaboration as c where c.collaborator.id=:collabId )", Mindmap.class);
|
||||
query.setParameter("collabId", user.getId());
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mindmap> search(MindMapCriteria criteria, int maxResult) {
|
||||
final Criteria hibernateCriteria = currentSession().createCriteria(Mindmap.class);
|
||||
//always search public maps
|
||||
hibernateCriteria.add(Restrictions.like("public", Boolean.TRUE));
|
||||
|
||||
if (criteria != null) {
|
||||
final Junction junction;
|
||||
if (criteria.isOrCriteria()) {
|
||||
junction = Restrictions.disjunction();
|
||||
} else {
|
||||
junction = Restrictions.conjunction();
|
||||
}
|
||||
|
||||
if (criteria.getTitle() != null && criteria.getTitle().length() > 0) {
|
||||
final SimpleExpression titleRestriction = Restrictions.like("title", "%" + criteria.getTitle() + "%");
|
||||
junction.add(titleRestriction);
|
||||
}
|
||||
|
||||
if (criteria.getDescription() != null && criteria.getDescription().length() > 0) {
|
||||
final SimpleExpression descriptionRestriction = Restrictions.like("description", "%" + criteria.getDescription() + "%");
|
||||
junction.add(descriptionRestriction);
|
||||
}
|
||||
hibernateCriteria.add(junction);
|
||||
}
|
||||
return hibernateCriteria.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Collaboration> findCollaboration(final int collaboratorId) {
|
||||
Query query = currentSession().createQuery("from com.wisemapping.model.Collaboration c where c.collaborator.id=:collaboratorId");
|
||||
final SelectionQuery<Collaboration> query = getSession().createSelectionQuery("from com.wisemapping.model.Collaboration c where c.collaborator.id=:collaboratorId", Collaboration.class);
|
||||
query.setParameter("collaboratorId", collaboratorId);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCollaborator(@NotNull Collaborator collaborator) {
|
||||
final Session session = getSession();
|
||||
assert collaborator != null : "ADD MINDMAP COLLABORATOR: Collaborator is required!";
|
||||
getHibernateTemplate().save(collaborator);
|
||||
session.persist(collaborator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCollaboration(Collaboration collaboration) {
|
||||
getHibernateTemplate().delete(collaboration);
|
||||
final Session session = getSession();
|
||||
session.remove(collaboration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCollaborator(@NotNull Collaborator collaborator) {
|
||||
getHibernateTemplate().delete(collaborator);
|
||||
final Session session = getSession();
|
||||
session.remove(collaborator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Mindmap getMindmapById(int id) {
|
||||
return getHibernateTemplate().get(Mindmap.class, id);
|
||||
final Session session = getSession();
|
||||
return session.get(Mindmap.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mindmap getMindmapByTitle(final String title, final User user) {
|
||||
final Mindmap result;
|
||||
Query query = currentSession().createQuery("from com.wisemapping.model.Mindmap wisemapping where title=:title and creator=:creator");
|
||||
final SelectionQuery<Mindmap> query = getSession().createSelectionQuery("from com.wisemapping.model.Mindmap wisemapping where title=:title and creator=:creator", Mindmap.class);
|
||||
query.setParameter("title", title);
|
||||
query.setParameter("creator", user);
|
||||
|
||||
|
@ -207,13 +158,13 @@ public class MindmapManagerImpl
|
|||
@Override
|
||||
public void saveMindmap(Mindmap mindMap) {
|
||||
assert mindMap != null : "Save Mindmap: Mindmap is required!";
|
||||
currentSession().save(mindMap);
|
||||
getSession().persist(mindMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMindmap(@NotNull Mindmap mindMap, boolean saveHistory) {
|
||||
assert mindMap != null : "Save Mindmap: Mindmap is required!";
|
||||
getHibernateTemplate().saveOrUpdate(mindMap);
|
||||
getSession().merge(mindMap);
|
||||
if (saveHistory) {
|
||||
saveHistory(mindMap);
|
||||
}
|
||||
|
@ -222,16 +173,20 @@ public class MindmapManagerImpl
|
|||
@Override
|
||||
public void removeMindmap(@NotNull final Mindmap mindmap) {
|
||||
// Delete history first ...
|
||||
final Criteria hibernateCriteria = currentSession().createCriteria(MindMapHistory.class);
|
||||
hibernateCriteria.add(Restrictions.eq("mindmapId", mindmap.getId()));
|
||||
final List list = hibernateCriteria.list();
|
||||
getHibernateTemplate().deleteAll(list);
|
||||
final Session session = getSession();
|
||||
final CriteriaBuilder cb = session.getCriteriaBuilder();
|
||||
|
||||
final CriteriaDelete<MindMapHistory> cr = cb.createCriteriaDelete(MindMapHistory.class);
|
||||
final Root<MindMapHistory> root = cr.from(MindMapHistory.class);
|
||||
|
||||
final CriteriaDelete<MindMapHistory> deleteStatement = cr.where(cb.equal(root.get("mindmapId"), mindmap.getId()));
|
||||
session.createMutationQuery(deleteStatement).executeUpdate();
|
||||
|
||||
// Remove collaborations ...
|
||||
mindmap.removedCollaboration(mindmap.getCollaborations());
|
||||
|
||||
// Delete mindmap ....
|
||||
getHibernateTemplate().delete(mindmap);
|
||||
getSession().remove(mindmap);
|
||||
}
|
||||
|
||||
private void saveHistory(@NotNull final Mindmap mindMap) {
|
||||
|
@ -241,6 +196,6 @@ public class MindmapManagerImpl
|
|||
history.setCreationTime(Calendar.getInstance());
|
||||
history.setEditor(mindMap.getLastEditor());
|
||||
history.setMindmapId(mindMap.getId());
|
||||
getHibernateTemplate().saveOrUpdate(history);
|
||||
getSession().merge(history);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,37 +18,43 @@
|
|||
|
||||
package com.wisemapping.dao;
|
||||
|
||||
import com.wisemapping.model.AccessAuditory;
|
||||
import com.wisemapping.model.AuthenticationType;
|
||||
import com.wisemapping.model.Collaboration;
|
||||
import com.wisemapping.model.Collaborator;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.model.*;
|
||||
import com.wisemapping.security.DefaultPasswordEncoderFactories;
|
||||
import com.wisemapping.security.LegacyPasswordEncoder;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.hibernate.ObjectNotFoundException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.orm.hibernate5.HibernateTemplate;
|
||||
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
@Repository
|
||||
public class UserManagerImpl
|
||||
extends HibernateDaoSupport
|
||||
implements UserManager {
|
||||
@Autowired
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
public void setEncoder(PasswordEncoder passwordEncoder) {
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<User> getAllUsers() {
|
||||
return currentSession().createQuery("from com.wisemapping.model.User user").list();
|
||||
return getSession().createSelectionQuery("from com.wisemapping.model.User user", User.class).getResultList();
|
||||
}
|
||||
|
||||
private Session getSession() {
|
||||
return sessionFactory.getCurrentSession();
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,10 +63,10 @@ public class UserManagerImpl
|
|||
public User getUserBy(@NotNull final String email) {
|
||||
User user = null;
|
||||
|
||||
var query = currentSession().createQuery("from com.wisemapping.model.User colaborator where email=:email");
|
||||
SelectionQuery<User> query = getSession().createSelectionQuery("from com.wisemapping.model.User colaborator where email=:email",User.class);
|
||||
query.setParameter("email", email);
|
||||
|
||||
final List<User> users = query.list();
|
||||
final List<User> users = query.getResultList();
|
||||
if (users != null && !users.isEmpty()) {
|
||||
assert users.size() == 1 : "More than one user with the same email!";
|
||||
user = users.get(0);
|
||||
|
@ -71,19 +77,20 @@ public class UserManagerImpl
|
|||
|
||||
@Override
|
||||
public Collaborator getCollaboratorBy(final String email) {
|
||||
final Collaborator cola;
|
||||
var query = currentSession().createQuery("from com.wisemapping.model.Collaborator colaborator where " +
|
||||
"email=:email");
|
||||
final Collaborator result;
|
||||
Session session = getSession();
|
||||
final SelectionQuery<Collaborator> query = session.createSelectionQuery("from com.wisemapping.model.Collaborator colaborator where " +
|
||||
"email=:email", Collaborator.class);
|
||||
query.setParameter("email", email);
|
||||
|
||||
final List<User> cols = query.list();
|
||||
final List<Collaborator> cols = query.getResultList();
|
||||
if (cols != null && !cols.isEmpty()) {
|
||||
assert cols.size() == 1 : "More than one colaborator with the same email!";
|
||||
cola = cols.get(0);
|
||||
result = cols.get(0);
|
||||
} else {
|
||||
cola = null;
|
||||
result = null;
|
||||
}
|
||||
return cola;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -91,7 +98,7 @@ public class UserManagerImpl
|
|||
public User getUserBy(int id) {
|
||||
User user = null;
|
||||
try {
|
||||
user = getHibernateTemplate().get(User.class, id);
|
||||
user = getSession().get(User.class, id);
|
||||
} catch (ObjectNotFoundException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
|
@ -106,7 +113,7 @@ public class UserManagerImpl
|
|||
} else {
|
||||
user.setPassword("");
|
||||
}
|
||||
getHibernateTemplate().saveOrUpdate(user);
|
||||
getSession().persist(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -114,10 +121,10 @@ public class UserManagerImpl
|
|||
assert user != null : "Trying to store a null user";
|
||||
|
||||
// Migrate from previous temporal collab to new user ...
|
||||
final HibernateTemplate template = getHibernateTemplate();
|
||||
final Session session = getSession();
|
||||
collaborator.setEmail(collaborator.getEmail() + "_toRemove");
|
||||
template.saveOrUpdate(collaborator);
|
||||
template.flush();
|
||||
session.merge(collaborator);
|
||||
session.flush();
|
||||
|
||||
// Save all new...
|
||||
this.createUser(user);
|
||||
|
@ -129,18 +136,18 @@ public class UserManagerImpl
|
|||
}
|
||||
|
||||
// Delete old user ...
|
||||
template.delete(collaborator);
|
||||
session.remove(collaborator);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUser(@NotNull final User user) {
|
||||
getHibernateTemplate().delete(user);
|
||||
getSession().remove(user);
|
||||
}
|
||||
|
||||
public void auditLogin(@NotNull AccessAuditory accessAuditory) {
|
||||
assert accessAuditory != null : "accessAuditory is null";
|
||||
getHibernateTemplate().save(accessAuditory);
|
||||
getSession().persist(accessAuditory);
|
||||
}
|
||||
|
||||
public void updateUser(@NotNull User user) {
|
||||
|
@ -152,21 +159,21 @@ public class UserManagerImpl
|
|||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||
}
|
||||
|
||||
getHibernateTemplate().update(user);
|
||||
getSession().merge(user);
|
||||
}
|
||||
|
||||
public User getUserByActivationCode(long code) {
|
||||
final User user;
|
||||
|
||||
var query = currentSession().createQuery("from com.wisemapping.model.User user where " +
|
||||
"activationCode=:activationCode");
|
||||
final SelectionQuery<User> query = getSession().createSelectionQuery("from com.wisemapping.model.User user where " +
|
||||
"activationCode=:activationCode", User.class);
|
||||
query.setParameter("activationCode", code);
|
||||
final List users = query.list();
|
||||
|
||||
final List<User> users = query.getResultList();
|
||||
if (users != null && !users.isEmpty()) {
|
||||
|
||||
assert users.size() == 1 : "More than one user with the same username!";
|
||||
user = (User) users.get(0);
|
||||
user = users.get(0);
|
||||
} else {
|
||||
user = null;
|
||||
}
|
||||
|
|
|
@ -21,11 +21,14 @@ import com.wisemapping.exceptions.ClientException;
|
|||
import com.wisemapping.exceptions.OAuthAuthenticationException;
|
||||
import com.wisemapping.exceptions.Severity;
|
||||
import com.wisemapping.exceptions.ValidationException;
|
||||
import com.wisemapping.mail.NotificationService;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.rest.model.RestErrors;
|
||||
import com.wisemapping.security.Utils;
|
||||
import com.wisemapping.service.NotificationService;
|
||||
import com.wisemapping.service.RegistrationException;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -38,9 +41,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
|||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -62,25 +62,27 @@ public class BaseController {
|
|||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ResponseBody
|
||||
public RestErrors handleClientErrors(@NotNull IllegalArgumentException ex) {
|
||||
logger.error(ex.getMessage(), ex);
|
||||
return new RestErrors(ex.getMessage(), Severity.WARNING);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ValidationException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public RestErrors handleValidationErrors(@NotNull ValidationException ex) {
|
||||
logger.error(ex.getMessage(), ex);
|
||||
return new RestErrors(ex.getErrors(), messageSource);
|
||||
}
|
||||
|
||||
@ExceptionHandler(JsonHttpMessageNotReadableException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public RestErrors handleJSONErrors(@NotNull JsonHttpMessageNotReadableException ex) {
|
||||
logger.error(ex.getMessage(), ex);
|
||||
return new RestErrors("Communication error", Severity.SEVERE);
|
||||
}
|
||||
|
||||
@ExceptionHandler(java.lang.reflect.UndeclaredThrowableException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public RestErrors handleSecurityErrors(@NotNull UndeclaredThrowableException ex) {
|
||||
logger.error(ex.getMessage(), ex);
|
||||
final Throwable cause = ex.getCause();
|
||||
RestErrors result;
|
||||
if (cause instanceof ClientException) {
|
||||
|
@ -107,6 +109,7 @@ public class BaseController {
|
|||
// "error_description": "Bad Request"
|
||||
//}, status: 400
|
||||
//
|
||||
logger.error(ex.getMessage(), ex);
|
||||
response.setStatus(response.getStatus());
|
||||
return ex;
|
||||
}
|
||||
|
@ -115,17 +118,16 @@ public class BaseController {
|
|||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
@ResponseBody
|
||||
public RestErrors handleServerErrors(@NotNull Exception ex, @NotNull HttpServletRequest request) {
|
||||
logger.error(ex.getMessage(), ex);
|
||||
final User user = Utils.getUser(false);
|
||||
notificationService.reportJavaException(ex, user, request);
|
||||
logger.error(ex);
|
||||
|
||||
return new RestErrors(ex.getMessage(), Severity.SEVERE);
|
||||
}
|
||||
|
||||
@ExceptionHandler(RegistrationException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ResponseBody
|
||||
public RestErrors handleRegistrationErrors(@NotNull RegistrationException exception) {
|
||||
return new RestErrors(exception, messageSource);
|
||||
public RestErrors handleRegistrationErrors(@NotNull RegistrationException ex) {
|
||||
return new RestErrors(ex, messageSource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* 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 org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class DebugMappingJacksonHttpMessageConverter extends MappingJackson2HttpMessageConverter {
|
||||
|
||||
@Override
|
||||
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws JsonHttpMessageNotReadableException {
|
||||
try {
|
||||
final byte[] bytes = IOUtils.toByteArray(inputMessage.getBody());
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
final WrapHttpInputMessage wrap = new WrapHttpInputMessage(bais, inputMessage.getHeaders());
|
||||
|
||||
return super.readInternal(clazz, wrap);
|
||||
|
||||
} catch (HttpMessageNotReadableException | IOException e) {
|
||||
throw new JsonHttpMessageNotReadableException("Request Body could not be read", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WrapHttpInputMessage implements HttpInputMessage {
|
||||
private final InputStream body;
|
||||
private final HttpHeaders headers;
|
||||
|
||||
WrapHttpInputMessage(InputStream is, HttpHeaders headers) {
|
||||
this.body = is;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
}
|
|
@ -35,6 +35,8 @@ import org.springframework.http.HttpStatus;
|
|||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -47,6 +49,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
|
||||
@Controller
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||
public class MindmapController extends BaseController {
|
||||
final Logger logger = LogManager.getLogger();
|
||||
|
@ -84,8 +87,7 @@ public class MindmapController extends BaseController {
|
|||
List<Mindmap> mindmaps = mindmapService.findMindmapsByUser(user);
|
||||
mindmaps = mindmaps
|
||||
.stream()
|
||||
.filter(m -> filter.accept(m, user))
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
.filter(m -> filter.accept(m, user)).toList();
|
||||
|
||||
return new RestMindmapList(mindmaps, user);
|
||||
}
|
||||
|
@ -148,6 +150,7 @@ public class MindmapController extends BaseController {
|
|||
saveMindmapDocument(minor, mindmap, user);
|
||||
}
|
||||
|
||||
@PreAuthorize("permitAll()")
|
||||
@RequestMapping(method = RequestMethod.GET, value = {"/maps/{id}/document/xml", "/maps/{id}/document/xml-pub"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"})
|
||||
@ResponseBody
|
||||
public byte[] retrieveDocument(@PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package com.wisemapping.security;
|
||||
|
||||
public enum MapAccessPermission {
|
||||
READ,
|
||||
WRITE
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package com.wisemapping.security;
|
||||
|
||||
import com.wisemapping.model.Collaborator;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.security.access.PermissionEvaluator;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class MapAccessPermissionEvaluation implements PermissionEvaluator {
|
||||
final private static Logger logger = LogManager.getLogger();
|
||||
|
||||
private MapPermissionsSecurityAdvice readAdvice;
|
||||
|
||||
private MapPermissionsSecurityAdvice updateAdvice;
|
||||
|
||||
public MapAccessPermissionEvaluation(final @NotNull MapPermissionsSecurityAdvice readAdvice, final @NotNull MapPermissionsSecurityAdvice updateAdvice) {
|
||||
this.readAdvice = readAdvice;
|
||||
this.updateAdvice = updateAdvice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(
|
||||
@NotNull Authentication auth, @NotNull Object targetDomainObject, @NotNull Object permission) {
|
||||
|
||||
logger.log(Level.DEBUG, "auth: " + auth + ",targetDomainObject:" + targetDomainObject + ",permission:" + permission);
|
||||
if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)) {
|
||||
logger.debug("Permissions could not be validated, illegal parameters.");
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result;
|
||||
final User user = Utils.getUser();
|
||||
final MapAccessPermission perm = MapAccessPermission.valueOf((permission.toString().toUpperCase()));
|
||||
if (targetDomainObject instanceof Integer) {
|
||||
// Checking permissions by mapId ...
|
||||
final int mapId = (Integer) targetDomainObject;
|
||||
result = hasPrivilege(mapId, perm);
|
||||
} else if (targetDomainObject instanceof Mindmap) {
|
||||
final Mindmap map = (Mindmap) targetDomainObject;
|
||||
result = hasPrivilege(map, perm);
|
||||
} else if (targetDomainObject instanceof Collaborator collab) {
|
||||
// Read only operations checks ...
|
||||
result = user.identityEquality(collab) || readAdvice.getMindmapService().isAdmin(user);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported check control of permissions");
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
logger.debug("User '" + (user != null ? user.getEmail() : "none") + "' not allowed to invoke");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(
|
||||
@NotNull Authentication auth, Serializable targetId, @NotNull String targetType, @NotNull Object
|
||||
permission) {
|
||||
logger.log(Level.FATAL, "Unsupported privilege: auth: " + auth + ",targetId:" + targetType + ",targetType:" + targetType + ", permission:" + permission);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasPrivilege(@NotNull int mapId, @NotNull MapAccessPermission permission) {
|
||||
boolean result;
|
||||
final User user = Utils.getUser();
|
||||
if (MapAccessPermission.READ == permission) {
|
||||
result = readAdvice.isAllowed(user, mapId);
|
||||
} else {
|
||||
result = updateAdvice.isAllowed(user, mapId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean hasPrivilege(@NotNull Mindmap map, @NotNull MapAccessPermission permission) {
|
||||
boolean result;
|
||||
final User user = Utils.getUser();
|
||||
if (MapAccessPermission.READ == permission) {
|
||||
result = readAdvice.isAllowed(user, map);
|
||||
} else {
|
||||
result = updateAdvice.isAllowed(user, map);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,38 +1,37 @@
|
|||
/*
|
||||
* Copyright [2022] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.service;
|
||||
|
||||
import jakarta.servlet.ServletContextEvent;
|
||||
import jakarta.servlet.ServletContextListener;
|
||||
|
||||
public class HibernateAppListener implements ServletContextListener {
|
||||
|
||||
public void contextInitialized(ServletContextEvent ce) {
|
||||
|
||||
try {
|
||||
|
||||
Class.forName("tomcatJndi.HibernateUtil").newInstance();
|
||||
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
/* Application Shutdown Event */
|
||||
public void contextDestroyed(ServletContextEvent ce)
|
||||
{ }
|
||||
}
|
||||
/*
|
||||
* Copyright [2022] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.security;
|
||||
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.service.MindmapService;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public abstract class MapPermissionsSecurityAdvice {
|
||||
@Autowired private MindmapService mindmapService;
|
||||
|
||||
protected abstract boolean isAllowed(@Nullable User user, Mindmap map);
|
||||
|
||||
protected abstract boolean isAllowed(@Nullable User user, int mapId);
|
||||
|
||||
protected MindmapService getMindmapService() {
|
||||
return mindmapService;
|
||||
}
|
||||
}
|
|
@ -16,32 +16,22 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.security.aop;
|
||||
package com.wisemapping.security;
|
||||
|
||||
import com.wisemapping.model.CollaborationRole;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
public class ViewBaseSecurityAdvise
|
||||
extends BaseSecurityAdvice
|
||||
implements MethodInterceptor {
|
||||
@Component
|
||||
public class ReadSecurityAdvise
|
||||
extends MapPermissionsSecurityAdvice {
|
||||
|
||||
@Override
|
||||
public Object invoke(@NotNull MethodInvocation methodInvocation) throws Throwable {
|
||||
checkRole(methodInvocation);
|
||||
return methodInvocation.proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowed(@Nullable User user, Mindmap map) {
|
||||
return getMindmapService().hasPermissions(user, map, CollaborationRole.VIEWER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowed(@Nullable User user, int mapId) {
|
||||
return getMindmapService().hasPermissions(user, mapId, CollaborationRole.VIEWER);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright [2022] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.security;
|
||||
|
||||
import com.wisemapping.model.CollaborationRole;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UpdateSecurityAdvise
|
||||
extends MapPermissionsSecurityAdvice {
|
||||
|
||||
@Override
|
||||
protected boolean isAllowed(@Nullable User user, @NotNull Mindmap map) {
|
||||
boolean result;
|
||||
if (map.getCreator() == null) {
|
||||
// This means that the map is new and is an add operation.
|
||||
result = true;
|
||||
} else {
|
||||
result = getMindmapService().hasPermissions(user, map, CollaborationRole.EDITOR);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowed(@Nullable User user, int mapId) {
|
||||
return getMindmapService().hasPermissions(user, mapId, CollaborationRole.EDITOR);
|
||||
}
|
||||
}
|
|
@ -23,13 +23,16 @@ import com.wisemapping.model.User;
|
|||
import com.wisemapping.service.UserService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service
|
||||
public class UserDetailsService
|
||||
implements org.springframework.security.core.userdetails.UserDetailsService {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
private String adminUser;
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright [2022] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.security.aop;
|
||||
|
||||
import com.wisemapping.exceptions.AccessDeniedSecurityException;
|
||||
import com.wisemapping.model.Collaborator;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.security.Utils;
|
||||
import com.wisemapping.service.MindmapService;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class BaseSecurityAdvice {
|
||||
private MindmapService mindmapService = null;
|
||||
|
||||
public void checkRole(MethodInvocation methodInvocation) throws AccessDeniedSecurityException {
|
||||
final User user = Utils.getUser();
|
||||
final Object argument = methodInvocation.getArguments()[0];
|
||||
boolean isAllowed;
|
||||
|
||||
if (argument instanceof Mindmap) {
|
||||
isAllowed = isAllowed(user, (Mindmap) argument) || mindmapService.isAdmin(user);
|
||||
} else if (argument instanceof Integer) {
|
||||
isAllowed = isAllowed(user, ((Integer) argument)) || mindmapService.isAdmin(user);
|
||||
} else if (argument instanceof Collaborator) {
|
||||
// Read operation find on the user are allowed ...
|
||||
isAllowed = user.identityEquality((Collaborator) argument) || mindmapService.isAdmin(user);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Argument " + argument);
|
||||
}
|
||||
|
||||
if (!isAllowed) {
|
||||
throw new AccessDeniedSecurityException("User '" + (user != null ? user.getEmail() : "none") + "' not allowed to invoke:" + methodInvocation);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isAllowed(@Nullable User user, Mindmap map);
|
||||
|
||||
protected abstract boolean isAllowed(@Nullable User user, int mapId);
|
||||
|
||||
protected MindmapService getMindmapService() {
|
||||
return mindmapService;
|
||||
}
|
||||
|
||||
public void setMindmapService(MindmapService service) {
|
||||
this.mindmapService = service;
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright [2022] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.security.aop;
|
||||
|
||||
import com.wisemapping.model.CollaborationRole;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class UpdateSecurityAdvise
|
||||
extends BaseSecurityAdvice
|
||||
implements MethodInterceptor {
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
||||
checkRole(methodInvocation);
|
||||
return methodInvocation.proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowed(@Nullable User user, @NotNull Mindmap map) {
|
||||
boolean result;
|
||||
if (map.getCreator() == null) {
|
||||
// This means that the map is new and is an add operation.
|
||||
result = true;
|
||||
} else {
|
||||
result = getMindmapService().hasPermissions(user, map, CollaborationRole.EDITOR);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowed(@Nullable User user, int mapId) {
|
||||
return getMindmapService().hasPermissions(user, mapId, CollaborationRole.EDITOR);
|
||||
}
|
||||
}
|
|
@ -23,19 +23,24 @@ import com.wisemapping.model.Label;
|
|||
import com.wisemapping.model.User;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service("labelService")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public class LabelServiceImpl implements LabelService {
|
||||
|
||||
@Autowired
|
||||
private LabelManager labelManager;
|
||||
|
||||
public void setLabelManager(LabelManager labelManager) {
|
||||
this.labelManager = labelManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLabel(@NotNull final Label label, @NotNull final User user) throws WiseMappingException {
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'WRITE')")
|
||||
public void addLabel(@NotNull final Label label, @NotNull final User user) {
|
||||
|
||||
label.setCreator(user);
|
||||
labelManager.addLabel(label);
|
||||
|
@ -43,22 +48,26 @@ public class LabelServiceImpl implements LabelService {
|
|||
|
||||
@NotNull
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'READ')")
|
||||
public List<Label> getAll(@NotNull final User user) {
|
||||
return labelManager.getAllLabels(user);
|
||||
}
|
||||
|
||||
@Override @Nullable
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'READ')")
|
||||
public Label findLabelById(int id, @NotNull final User user) {
|
||||
return labelManager.getLabelById(id, user);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'READ')")
|
||||
public Label getLabelByTitle(@NotNull String title, @NotNull final User user) {
|
||||
return labelManager.getLabelByTitle(title, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'WRITE')")
|
||||
public void removeLabel(@NotNull Label label, @NotNull User user) throws WiseMappingException {
|
||||
if (label.getCreator().equals(user)) {
|
||||
labelManager.removeLabel(label);
|
||||
|
|
|
@ -17,36 +17,44 @@
|
|||
*/
|
||||
|
||||
|
||||
package com.wisemapping.mail;
|
||||
package com.wisemapping.service;
|
||||
|
||||
import com.wisemapping.util.VelocityEngineUtils;
|
||||
import com.wisemapping.util.VelocityEngineWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.mail.javamail.MimeMessagePreparator;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
public final class Mailer {
|
||||
@Service
|
||||
public final class MailerService {
|
||||
|
||||
//~ Instance fields ......................................................................................
|
||||
|
||||
@Autowired
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
@Autowired
|
||||
private VelocityEngineWrapper velocityEngineWrapper;
|
||||
private final String serverFromEmail;
|
||||
private final String supportEmail;
|
||||
private final String errorReporterEmail;
|
||||
|
||||
@Value("${mail.serverSendEmail}")
|
||||
private String serverFromEmail;
|
||||
|
||||
@Value("${mail.supportEmail}")
|
||||
private String supportEmail;
|
||||
|
||||
@Value("${mail.errorReporterEmail}")
|
||||
private String errorReporterEmail;
|
||||
|
||||
//~ Methods ..............................................................................................
|
||||
|
||||
public Mailer(@NotNull String siteEmail, @NotNull String supportEmail, @NotNull String errorReporterEmail) {
|
||||
this.serverFromEmail = siteEmail;
|
||||
this.supportEmail = supportEmail;
|
||||
this.errorReporterEmail = errorReporterEmail;
|
||||
}
|
||||
|
||||
public String getServerSenderEmail() {
|
||||
return serverFromEmail;
|
||||
}
|
|
@ -49,8 +49,6 @@ public interface MindmapService {
|
|||
|
||||
void removeMindmap(@NotNull final Mindmap mindmap, @NotNull final User user) throws WiseMappingException;
|
||||
|
||||
List<Mindmap> search(MindMapCriteria criteria);
|
||||
|
||||
List<MindMapHistory> findMindmapHistory(int mindmapId);
|
||||
|
||||
boolean hasPermissions(@Nullable User user, Mindmap map, CollaborationRole allowedRole);
|
||||
|
|
|
@ -20,23 +20,28 @@ package com.wisemapping.service;
|
|||
|
||||
import com.wisemapping.dao.MindmapManager;
|
||||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.mail.NotificationService;
|
||||
import com.wisemapping.model.*;
|
||||
import com.wisemapping.security.Utils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@Service("mindmapService")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public class MindmapServiceImpl
|
||||
|
||||
implements MindmapService {
|
||||
|
||||
@Autowired
|
||||
|
@ -49,6 +54,8 @@ public class MindmapServiceImpl
|
|||
@Autowired
|
||||
private NotificationService notificationService;
|
||||
|
||||
|
||||
@Value("${admin.user}")
|
||||
private String adminUser;
|
||||
final private LockManager lockManager;
|
||||
|
||||
|
@ -92,37 +99,42 @@ public class MindmapServiceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasPermission(#user, 'READ')")
|
||||
public Mindmap getMindmapByTitle(String title, User user) {
|
||||
return mindmapManager.getMindmapByTitle(title, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Mindmap findMindmapById(int id) {
|
||||
return mindmapManager.getMindmapById(id);
|
||||
@PreAuthorize("hasPermission(#mapId, 'READ')")
|
||||
public Mindmap findMindmapById(int mapId) {
|
||||
return mindmapManager.getMindmapById(mapId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'READ')")
|
||||
public List<Mindmap> findMindmapsByUser(@NotNull User user) {
|
||||
return mindmapManager.findMindmapByUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#user, 'READ')")
|
||||
public List<Collaboration> findCollaborations(@NotNull User user) {
|
||||
return mindmapManager.findCollaboration(user.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMindmap(@NotNull Mindmap mindMap, boolean saveHistory) throws WiseMappingException {
|
||||
if (mindMap.getTitle() == null || mindMap.getTitle().length() == 0) {
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mindmap, 'WRITE')")
|
||||
public void updateMindmap(@NotNull Mindmap mindmap, boolean saveHistory) throws WiseMappingException {
|
||||
if (mindmap.getTitle() == null || mindmap.getTitle().length() == 0) {
|
||||
throw new WiseMappingException("The title can not be empty");
|
||||
}
|
||||
|
||||
// Check that what we received a valid mindmap...
|
||||
final String xml;
|
||||
try {
|
||||
xml = mindMap.getXmlStr().trim();
|
||||
xml = mindmap.getXmlStr().trim();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new WiseMappingException("Could not be decoded.", e);
|
||||
}
|
||||
|
@ -131,15 +143,11 @@ public class MindmapServiceImpl
|
|||
throw new WiseMappingException("Map seems not to be a valid mindmap: '" + xml + "'");
|
||||
}
|
||||
|
||||
mindmapManager.updateMindmap(mindMap, saveHistory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mindmap> search(MindMapCriteria criteria) {
|
||||
return mindmapManager.search(criteria);
|
||||
mindmapManager.updateMindmap(mindmap, saveHistory);
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mindmap, 'WRITE')")
|
||||
public void removeCollaboration(@NotNull Mindmap mindmap, @NotNull Collaboration collaboration) throws CollaborationException {
|
||||
// remove collaborator association
|
||||
final Mindmap mindMap = collaboration.getMindMap();
|
||||
|
@ -154,6 +162,7 @@ public class MindmapServiceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mindmap, 'READ')")
|
||||
public void removeMindmap(@NotNull Mindmap mindmap, @NotNull User user) throws WiseMappingException {
|
||||
if (mindmap.getCreator().identityEquality(user)) {
|
||||
mindmapManager.removeMindmap(mindmap);
|
||||
|
@ -166,9 +175,10 @@ public class MindmapServiceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addMindmap(@NotNull Mindmap map, @NotNull User user) {
|
||||
@PreAuthorize("hasPermission(#mindmap, 'WRITE')")
|
||||
public void addMindmap(@NotNull Mindmap mindmap, @NotNull User user) {
|
||||
|
||||
final String title = map.getTitle();
|
||||
final String title = mindmap.getTitle();
|
||||
|
||||
if (title == null || title.length() == 0) {
|
||||
throw new IllegalArgumentException("The tile can not be empty");
|
||||
|
@ -180,20 +190,21 @@ public class MindmapServiceImpl
|
|||
}
|
||||
|
||||
final Calendar creationTime = Calendar.getInstance();
|
||||
map.setLastEditor(user);
|
||||
map.setCreationTime(creationTime);
|
||||
map.setLastModificationTime(creationTime);
|
||||
map.setCreator(user);
|
||||
mindmap.setLastEditor(user);
|
||||
mindmap.setCreationTime(creationTime);
|
||||
mindmap.setLastModificationTime(creationTime);
|
||||
mindmap.setCreator(user);
|
||||
|
||||
// Add map creator with owner permissions ...
|
||||
final User dbUser = userService.getUserBy(user.getId());
|
||||
final Collaboration collaboration = new Collaboration(CollaborationRole.OWNER, dbUser, map);
|
||||
map.getCollaborations().add(collaboration);
|
||||
final Collaboration collaboration = new Collaboration(CollaborationRole.OWNER, dbUser, mindmap);
|
||||
mindmap.getCollaborations().add(collaboration);
|
||||
|
||||
mindmapManager.addMindmap(dbUser, map);
|
||||
mindmapManager.addMindmap(dbUser, mindmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mindmap, 'WRITE')")
|
||||
public void addCollaboration(@NotNull Mindmap mindmap, @NotNull String email, @NotNull CollaborationRole role, @Nullable String message)
|
||||
throws CollaborationException {
|
||||
|
||||
|
@ -227,7 +238,8 @@ public class MindmapServiceImpl
|
|||
}
|
||||
}
|
||||
|
||||
private Collaborator addCollaborator(String email) {
|
||||
|
||||
private Collaborator addCollaborator(@NotNull String email) {
|
||||
// Add a new collaborator ...
|
||||
Collaborator collaborator = mindmapManager.findCollaborator(email);
|
||||
if (collaborator == null) {
|
||||
|
@ -241,11 +253,13 @@ public class MindmapServiceImpl
|
|||
|
||||
|
||||
@Override
|
||||
public List<MindMapHistory> findMindmapHistory(int mindmapId) {
|
||||
return mindmapManager.getHistoryFrom(mindmapId);
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mapId, 'READ')")
|
||||
public List<MindMapHistory> findMindmapHistory(int mapId) {
|
||||
return mindmapManager.getHistoryFrom(mapId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mindmap, 'WRITE')")
|
||||
public void revertChange(@NotNull Mindmap mindmap, int historyId)
|
||||
throws WiseMappingException {
|
||||
final MindMapHistory history = mindmapManager.getHistory(historyId);
|
||||
|
@ -254,8 +268,9 @@ public class MindmapServiceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public MindMapHistory findMindmapHistory(int id, int hid) throws WiseMappingException {
|
||||
final List<MindMapHistory> mindmapHistory = this.findMindmapHistory(id);
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#mapId, 'READ')")
|
||||
public MindMapHistory findMindmapHistory(int mapId, int hid) throws WiseMappingException {
|
||||
final List<MindMapHistory> mindmapHistory = this.findMindmapHistory(mapId);
|
||||
MindMapHistory result = null;
|
||||
for (MindMapHistory history : mindmapHistory) {
|
||||
if (history.getId() == hid) {
|
||||
|
@ -265,12 +280,13 @@ public class MindmapServiceImpl
|
|||
}
|
||||
|
||||
if (result == null) {
|
||||
throw new WiseMappingException("History could not be found for mapid=" + id + ",hid" + hid);
|
||||
throw new WiseMappingException("History could not be found for mapid=" + mapId + ",hid" + hid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAnyRole('USER', 'ADMIN') && hasPermission(#collaborator, 'WRITE')")
|
||||
public void updateCollaboration(@NotNull Collaborator collaborator, @NotNull Collaboration collaboration) throws WiseMappingException {
|
||||
if (!collaborator.identityEquality(collaboration.getCollaborator())) {
|
||||
throw new WiseMappingException("No enough permissions for this operation.");
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wisemapping.mail;
|
||||
package com.wisemapping.service;
|
||||
|
||||
import com.wisemapping.filter.SupportedUserAgent;
|
||||
import com.wisemapping.model.Collaboration;
|
||||
|
@ -29,10 +29,13 @@ import org.apache.logging.log4j.Logger;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
@ -42,13 +45,16 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
final public class NotificationService {
|
||||
final private static Logger logger = LogManager.getLogger();
|
||||
@Autowired
|
||||
private ResourceBundleMessageSource messageSource;
|
||||
|
||||
@Autowired
|
||||
private Mailer mailer;
|
||||
private MailerService mailerService;
|
||||
|
||||
@Value("${site.baseurl:http://localhost:8080/}")
|
||||
private String baseUrl;
|
||||
|
||||
public void newCollaboration(@NotNull Collaboration collaboration, @NotNull Mindmap mindmap, @NotNull User user, @Nullable String message) {
|
||||
|
@ -56,7 +62,7 @@ final public class NotificationService {
|
|||
|
||||
try {
|
||||
// Sent collaboration email ...
|
||||
final String formMail = mailer.getServerSenderEmail();
|
||||
final String formMail = mailerService.getServerSenderEmail();
|
||||
|
||||
// Is the user already registered user ?.
|
||||
final String collabEmail = collaboration.getCollaborator().getEmail();
|
||||
|
@ -72,14 +78,14 @@ final public class NotificationService {
|
|||
model.put("baseUrl", getBaseUrl());
|
||||
model.put("senderMail", user.getEmail());
|
||||
model.put("message", message);
|
||||
model.put("doNotReplay", messageSource.getMessage("EMAIL.DO_NOT_REPLAY", new Object[]{mailer.getSupportEmail()}, locale));
|
||||
model.put("doNotReplay", messageSource.getMessage("EMAIL.DO_NOT_REPLAY", new Object[]{mailerService.getSupportEmail()}, locale));
|
||||
|
||||
// To resolve resources on templates ...
|
||||
model.put("noArg", new Object[]{});
|
||||
model.put("messages", messageSource);
|
||||
model.put("locale", locale);
|
||||
|
||||
mailer.sendEmail(formMail, collabEmail, subject, model, "newCollaboration.vm");
|
||||
mailerService.sendEmail(formMail, collabEmail, subject, model, "newCollaboration.vm");
|
||||
} catch (Exception e) {
|
||||
handleException(e);
|
||||
}
|
||||
|
@ -125,8 +131,8 @@ final public class NotificationService {
|
|||
model.put("messageTitle", messageTitle);
|
||||
model.put("messageBody", messageBody);
|
||||
model.put("baseUrl", getBaseUrl());
|
||||
model.put("supportEmail", mailer.getSupportEmail());
|
||||
model.put("doNotReplay", messageSource.getMessage("EMAIL.DO_NOT_REPLAY", new Object[]{mailer.getSupportEmail()}, locale));
|
||||
model.put("supportEmail", mailerService.getSupportEmail());
|
||||
model.put("doNotReplay", messageSource.getMessage("EMAIL.DO_NOT_REPLAY", new Object[]{mailerService.getSupportEmail()}, locale));
|
||||
|
||||
// To resolve resources on templates ...
|
||||
model.put("noArg", new Object[]{});
|
||||
|
@ -134,7 +140,7 @@ final public class NotificationService {
|
|||
model.put("locale", locale);
|
||||
|
||||
logger.debug("Email properties->" + model);
|
||||
mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), mailSubject, model, "baseLayout.vm");
|
||||
mailerService.sendEmail(mailerService.getServerSenderEmail(), user.getEmail(), mailSubject, model, "baseLayout.vm");
|
||||
} catch (Exception e) {
|
||||
handleException(e);
|
||||
}
|
||||
|
@ -146,15 +152,15 @@ final public class NotificationService {
|
|||
|
||||
}
|
||||
|
||||
public void setMailer(Mailer mailer) {
|
||||
this.mailer = mailer;
|
||||
public void setMailer(MailerService mailerService) {
|
||||
this.mailerService = mailerService;
|
||||
}
|
||||
|
||||
|
||||
public void activateAccount(@NotNull User user) {
|
||||
final Map<String, Object> model = new HashMap<>();
|
||||
model.put("user", user);
|
||||
mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), "[WiseMapping] Active account", model, "activationAccountMail.vm");
|
||||
mailerService.sendEmail(mailerService.getServerSenderEmail(), user.getEmail(), "[WiseMapping] Active account", model, "activationAccountMail.vm");
|
||||
}
|
||||
|
||||
public void sendRegistrationEmail(@NotNull User user) {
|
|
@ -15,7 +15,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.wisemapping.mail;
|
||||
package com.wisemapping.service;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.util.DigestUtils;
|
|
@ -29,21 +29,27 @@ import org.apache.http.client.fluent.Request;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service
|
||||
public class RecaptchaService {
|
||||
|
||||
final private static Logger logger = LogManager.getLogger();
|
||||
|
||||
final private static String GOOGLE_RECAPTCHA_VERIFY_URL =
|
||||
"https://www.google.com/recaptcha/api/siteverify";
|
||||
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
public static final String CATCH_ERROR_CODE_TIMEOUT_OR_DUPLICATE = "timeout-or-duplicate";
|
||||
public static final String CATCHA_ERROR_CODE_INPUT_RESPONSE = "invalid-input-response";
|
||||
|
||||
@Value("${google.recaptcha2.secretKey}")
|
||||
private String recaptchaSecret;
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.wisemapping.dao.UserManager;
|
|||
import com.wisemapping.exceptions.InvalidMindmapException;
|
||||
import com.wisemapping.exceptions.OAuthAuthenticationException;
|
||||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.mail.NotificationService;
|
||||
import com.wisemapping.model.*;
|
||||
import com.wisemapping.rest.model.RestResetPasswordAction;
|
||||
import com.wisemapping.rest.model.RestResetPasswordResponse;
|
||||
|
@ -33,18 +32,31 @@ import com.wisemapping.util.VelocityEngineUtils;
|
|||
import com.wisemapping.util.VelocityEngineWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service("userService")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public class UserServiceImpl
|
||||
implements UserService {
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
@Autowired
|
||||
private MindmapService mindmapService;
|
||||
@Autowired
|
||||
private NotificationService notificationService;
|
||||
@Autowired
|
||||
private MessageSource messageSource;
|
||||
@Autowired
|
||||
private VelocityEngineWrapper velocityEngineWrapper;
|
||||
@Autowired
|
||||
private GoogleService googleService;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,8 @@ package com.wisemapping.service.google;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -30,11 +32,17 @@ import com.wisemapping.service.google.http.HttpInvokerException;
|
|||
|
||||
@Service
|
||||
public class GoogleService {
|
||||
@Autowired
|
||||
private HttpInvoker httpInvoker;
|
||||
@Value("${security.oauth2.google.confirmUrl}")
|
||||
private String optinConfirmUrl;
|
||||
@Value("${security.oauth2.google.userinfoUrl}")
|
||||
private String accountBasicDataUrl;
|
||||
@Value("${security.oauth2.google.clientId}")
|
||||
private String clientId;
|
||||
@Value("${security.oauth2.google.clientSecret}")
|
||||
private String clientSecret;
|
||||
@Value("${security.oauth2.google.callbackUrl}")
|
||||
private String callbackUrl;
|
||||
|
||||
public void setHttpInvoker(HttpInvoker httpInvoker) {
|
||||
|
|
|
@ -21,7 +21,9 @@ import org.apache.commons.collections.ExtendedProperties;
|
|||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.runtime.RuntimeConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class VelocityEngineWrapper {
|
||||
private final VelocityEngine velocityEngine;
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -46,6 +48,7 @@ import org.springframework.web.servlet.ModelAndView;
|
|||
import java.util.Locale;
|
||||
|
||||
@Controller
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public class MvcMindmapController {
|
||||
|
||||
@Qualifier("mindmapService")
|
||||
|
@ -58,6 +61,7 @@ public class MvcMindmapController {
|
|||
final MindMapBean mindmap = findMindmapBean(id);
|
||||
model.addAttribute("principal", Utils.getUser());
|
||||
model.addAttribute("mindmap", mindmap);
|
||||
model.addAttribute("creatorFullName", mindmap.getCreator().getFullName());
|
||||
final Locale locale = LocaleContextHolder.getLocale();
|
||||
model.addAttribute("locale", locale.toString().toLowerCase());
|
||||
return "mindmapViewonly";
|
||||
|
|
|
@ -53,4 +53,16 @@ public class MvcUsersController {
|
|||
return new ModelAndView("reactInclude");
|
||||
}
|
||||
|
||||
@RequestMapping(value = "registration-success", method = RequestMethod.GET)
|
||||
@PreAuthorize("permitAll()")
|
||||
public ModelAndView showRegistrationSuccess() {
|
||||
return new ModelAndView("reactInclude");
|
||||
}
|
||||
|
||||
@RequestMapping(value = "forgot-password-success", method = RequestMethod.GET)
|
||||
@PreAuthorize("permitAll()")
|
||||
public ModelAndView showResetPasswordSuccess() {
|
||||
return new ModelAndView("reactInclude");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
<Console name="LogToConsole" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||
</Console>
|
||||
<File name="LogToFile" fileName="wisemapping.log">
|
||||
<File name="LogToFile" fileName="/var/log/wisemapping.log">
|
||||
<PatternLayout>
|
||||
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
|
||||
</PatternLayout>
|
||||
</File>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Logger name="com.wisemapping" level="warn">
|
||||
<Logger name="com.wisemapping" level="trace">
|
||||
<AppenderRef ref="LogToConsole"/>
|
||||
</Logger>
|
||||
<Logger name="org.springframework" level="warn">
|
||||
<Logger name="org.springframework" level="trace">
|
||||
<AppenderRef ref="LogToConsole"/>
|
||||
</Logger>
|
||||
<Root level="warn">
|
||||
<Root level="trace">
|
||||
<AppenderRef ref="LogToConsole"/>
|
||||
</Root>
|
||||
</Loggers>
|
|
@ -64,4 +64,7 @@ OWNER_ROLE_CAN_NOT_BE_CHANGED=Роль владельца изменить не
|
|||
ZOOM_TO_FIT=Увеличить, чтобы соответствовать
|
||||
ZOOM_OUT=Уменьшить
|
||||
ZOOM_IN=Приблизить
|
||||
PASSWORD_TOO_LONG=Password must be less than 40 characters.
|
||||
PASSWORD_TOO_LONG=Password must be less than 40 characters.
|
||||
CHANGE_PASSWORD.EMAIL_SUBJECT=Your password has been reset
|
||||
CHANGE_PASSWORD.EMAIL_TITLE=A temporal password has been generated
|
||||
CHANGE_PASSWORD.EMAIL_BODY=<p>Someone, most likely you, requested a new password for your WiseMapping account. </p><p><strong>Here is your new password: {0} </strong></p><p>You can login clicking <a href="{1}/c/login">here</a>. We strongly encourage you to change the password as soon as possible.</p>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<!-- <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">-->
|
||||
<!-- <property name="defaultEncoding" value="UTF-8"/>-->
|
||||
<!-- <property name="basenames">-->
|
||||
<!-- <list>-->
|
||||
<!-- <value>messages</value>-->
|
||||
<!-- </list>-->
|
||||
<!-- </property>-->
|
||||
<!-- </bean>-->
|
||||
|
||||
<import resource="wisemapping-datasource.xml"/>
|
||||
<import resource="wisemapping-dao.xml"/>
|
||||
<import resource="wisemapping-service.xml"/>
|
||||
<import resource="wisemapping-servlet.xml"/>
|
||||
</beans>
|
|
@ -23,7 +23,7 @@
|
|||
<prop key="hibernate.dialect">${database.hibernate.dialect}</prop>
|
||||
<!-- <prop key="hibernate.cache.use_second_level_cache">true</prop>-->
|
||||
<!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>-->
|
||||
<!-- <prop key="hibernate.default_batch_fetch_size">200</prop>-->
|
||||
<prop key="hibernate.default_batch_fetch_size">200</prop>
|
||||
<prop key="hibernate.nestedTransactionAllowed">true</prop>
|
||||
<prop key="hibernate.auto_quote_keyword">true</prop>
|
||||
</props>
|
||||
|
@ -35,23 +35,4 @@
|
|||
<property name="nestedTransactionAllowed" value="true"/>
|
||||
</bean>
|
||||
|
||||
<!-- Hibernate Template Definition -->
|
||||
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
|
||||
<property name="sessionFactory" ref="mindmapSessionFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="txAttributes"
|
||||
class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
|
||||
<property name="properties">
|
||||
<props>
|
||||
<prop key="*">PROPAGATION_REQUIRED</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
<property name="transactionAttributeSource" ref="txAttributes"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -13,11 +13,10 @@
|
|||
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
<context:component-scan base-package="com.wisemapping.rest"/>
|
||||
<context:annotation-config/>
|
||||
|
||||
<mvc:annotation-driven>
|
||||
<mvc:message-converters>
|
||||
<bean class="com.wisemapping.rest.DebugMappingJacksonHttpMessageConverter"/>
|
||||
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
|
||||
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
|
||||
</mvc:message-converters>
|
||||
</mvc:annotation-driven>
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:property-placeholder location="/WEB-INF/app.properties" ignore-unresolvable="true"/>
|
||||
|
||||
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
|
||||
<property name="host" value="${mail.smtp.host}"/>
|
||||
<property name="port" value="${mail.smtp.port}"/>
|
||||
<property name="protocol" value="smtp"/>
|
||||
<property name="username" value="${mail.username}"/>
|
||||
<property name="password" value="${mail.password}"/>
|
||||
<property name="javaMailProperties">
|
||||
<props>
|
||||
<prop key="mail.smtp.auth">${mail.smtp.auth:false}</prop>
|
||||
<prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable:false}</prop>
|
||||
<prop key="mail.smtp.quitwait">${mail.smtp.quitwait:true}</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
|
||||
<property name="defaultEncoding" value="UTF-8"/>
|
||||
<property name="basenames">
|
||||
<list>
|
||||
<value>messages</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<import resource="wisemapping-security-${security.type:db}.xml"/>
|
||||
</beans>
|
|
@ -12,8 +12,6 @@
|
|||
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
<context:component-scan base-package="com.wisemapping"/>
|
||||
<context:annotation-config/>
|
||||
<mvc:annotation-driven/>
|
||||
<context:property-placeholder location="/WEB-INF/app.properties" ignore-unresolvable="true"/>
|
||||
|
||||
<!-- Interceptors Registration -->
|
|
@ -1,18 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="DEBUG">
|
||||
<Configuration status="warn">
|
||||
<Appenders>
|
||||
<Console name="LogToConsole" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Logger name="com.wisemapping" level="debug">
|
||||
<Logger name="com.wisemapping" level="warn">
|
||||
<AppenderRef ref="LogToConsole"/>
|
||||
</Logger>
|
||||
<Logger name="org.springframework" level="trace">
|
||||
<Logger name="org.springframework" level="warn">
|
||||
<AppenderRef ref="LogToConsole"/>
|
||||
</Logger>
|
||||
<Root level="trace">
|
||||
<Root level="warn">
|
||||
<AppenderRef ref="LogToConsole"/>
|
||||
</Root>
|
||||
</Loggers>
|
|
@ -1,6 +1,5 @@
|
|||
<%@ page import="com.wisemapping.security.Utils" %>
|
||||
<%@ page import="com.wisemapping.model.User" %>
|
||||
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
|
||||
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
<%@ include file="init.jsp" %>
|
||||
|
||||
<%--@elvariable id="mindmap" type="com.wisemapping.model.Mindmap"--%>
|
||||
|
@ -8,12 +7,15 @@
|
|||
<%--@elvariable id="editorTryMode" type="java.lang.String"--%>
|
||||
<%--@elvariable id="lockInfo" type="com.wisemapping.service.LockInfo"--%>
|
||||
|
||||
<c:set var="baseUrl" value="${requestScope['site.baseurl']}" scope="request" />
|
||||
<c:set var="baseJsUrl" value="${requestScope['site.static.js.url']}" scope="request" />
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="${fn:substring(locale,0,2)}">
|
||||
<head>
|
||||
<base href="${baseUrl}/static/webapp/" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<base href="${requestScope['site.baseurl']}/static/webapp/">
|
||||
|
||||
<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>
|
||||
<%@ include file="pageHeaders.jsf" %>
|
||||
|
@ -45,9 +47,7 @@
|
|||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="mindplot-div-container"></div>
|
||||
|
||||
<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" defer></script>
|
||||
|
||||
<script type="text/javascript" src="${baseJsUrl}/webapp/vendors.bundle.js" crossorigin="anonymous" defer></script>
|
||||
<script type="text/javascript" src="${baseJsUrl}/webapp/app.bundle.js" crossorigin="anonymous" defer></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<%@page pageEncoding="UTF-8" %>
|
||||
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
|
||||
<%@include file="init.jsp" %>
|
||||
<c:set var="baseUrl" value="${requestScope['site.baseurl']}" scope="request" />
|
||||
<c:set var="baseJsUrl" value="${requestScope['site.static.js.url']}" scope="request" />
|
||||
|
||||
<%--@elvariable id="mindmap" type="com.wisemapping.model.Mindmap"--%>
|
||||
|
||||
|
@ -7,9 +11,9 @@
|
|||
|
||||
<html lang="${fn:substring(locale,0,2)}">
|
||||
<head>
|
||||
<base href="${baseUrl}/static/mindplot/" />
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<base href="${requestScope['site.baseurl']}/static/mindplot/">
|
||||
|
||||
<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="preload" href="../../css/viewonly.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
|
@ -67,11 +71,11 @@
|
|||
</a>
|
||||
|
||||
<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>${creatorFullName}</span>
|
||||
<span class="title"><spring:message code="DESCRIPTION"/>:</span><span>${mindmap.title}</span>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="${requestScope['site.static.js.url']}/mindplot/loader.js" crossorigin="anonymous" defer></script>
|
||||
<script type="text/javascript" src="${baseJsUrl}/mindplot/loader.js" crossorigin="anonymous" defer></script>
|
||||
|
||||
<div id="floating-panel">
|
||||
<div id="zoom-button">
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<%@ taglib uri = "jakarta.tags.functions" prefix = "fn" %>
|
||||
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
|
||||
<%@taglib uri="jakarta.tags.functions" prefix="fn" %>
|
||||
<%@taglib uri="jakarta.tags.core" prefix="c"%>
|
||||
<c:set var="baseUrl" value="${requestScope['site.baseurl']}" scope="request" />
|
||||
<c:set var="baseJsUrl" value="${requestScope['site.static.js.url']}" scope="request" />
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="${fn:substring(locale,0,2)}">
|
||||
<head>
|
||||
<base href="${baseUrl}/static/webapp/" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<base href="${requestScope['site.baseurl']}/static/webapp/">
|
||||
|
||||
<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>
|
||||
<%@ include file="pageHeaders.jsf" %>
|
||||
|
@ -21,12 +24,15 @@
|
|||
googleOauth2Url: '${requestScope['security.oauth2.google.url']}'
|
||||
};
|
||||
|
||||
<!-- Hack to force view selection on react to move all the UI to react-->
|
||||
<%-- Hack to force view selection on react to move all the UI to react --%>
|
||||
window.errorMvcView = '${requestScope['exception']!=null?(fn:indexOf(requestScope['exception'],'SecurityException') gt 1?'securityError':'unexpectedError'):''}';
|
||||
/*
|
||||
${requestScope['exception']}
|
||||
*/
|
||||
</script>
|
||||
|
||||
<c:if test="${requestScope['google.analytics.enabled']}">
|
||||
<!-- Google Ads Sense Config. Lazy loading optimization -->
|
||||
<%-- Google Ads Sense Config. Lazy loading optimization --%>
|
||||
<script type="text/javascript">
|
||||
function downloadJsAtOnload() {
|
||||
setTimeout(function downloadJs() {
|
||||
|
@ -47,8 +53,8 @@
|
|||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<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" async></script>
|
||||
<script type="text/javascript" src="${baseJsUrl}/webapp/vendors.bundle.js" crossorigin="anonymous" async></script>
|
||||
<script type="text/javascript" src="${baseJsUrl}/webapp/app.bundle.js" crossorigin="anonymous" async></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -24,12 +24,7 @@
|
|||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/wisemapping-aop.xml
|
||||
/WEB-INF/wisemapping-datasource.xml
|
||||
/WEB-INF/wisemapping-dao.xml
|
||||
/WEB-INF/wisemapping-service.xml
|
||||
/WEB-INF/wisemapping-model.xml
|
||||
/WEB-INF/wisemapping-servlet.xml
|
||||
classpath:spring/wisemapping-common.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
|
||||
|
@ -37,17 +32,13 @@
|
|||
<param-name>contextInitializerClasses</param-name>
|
||||
<param-value>com.wisemapping.webmvc.ApplicationContextInitializer</param-value>
|
||||
</context-param>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
- Loads the root application context of this web app at startup.
|
||||
- The application context is then available via
|
||||
- WebApplicationContextUtils.getWebApplicationContext(servletContext).
|
||||
-->
|
||||
|
||||
<listener>
|
||||
<listener-class>com.wisemapping.service.HibernateAppListener</listener-class>
|
||||
</listener>
|
||||
<listener>
|
||||
<listener-class>com.wisemapping.listener.UnlockOnExpireListener</listener-class>
|
||||
</listener>
|
||||
|
@ -96,7 +87,7 @@
|
|||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/wisemapping-servlet.xml
|
||||
classpath:spring/wisemapping-servlet.xml
|
||||
</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
|
@ -108,7 +99,7 @@
|
|||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/wisemapping-rest.xml
|
||||
classpath:spring/wisemapping-rest.xml
|
||||
</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="viewSecurityAdvisor"
|
||||
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
|
||||
<property name="advice" ref="viewSecurityAdvice"/>
|
||||
<property name="mappedNames">
|
||||
<list>
|
||||
<value>getMindmapUserBy</value>
|
||||
<value>getMindmapById</value>
|
||||
<value>linkLabel</value>
|
||||
<value>find*</value>
|
||||
<value>filter*</value>
|
||||
<!-- Remove can be performed in view only maps -->
|
||||
<value>removeMindmap</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="updateSecurityAdvisor"
|
||||
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
|
||||
<property name="advice" ref="updateSecurityAdvice"/>
|
||||
<property name="mappedNames">
|
||||
<list>
|
||||
<value>save*</value>
|
||||
<value>update*</value>
|
||||
<value>add*</value>
|
||||
<value>revert*</value>
|
||||
<value>removeCollaboration</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="viewSecurityAdvice" class="com.wisemapping.security.aop.ViewBaseSecurityAdvise">
|
||||
<property name="mindmapService" ref="mindmapService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="updateSecurityAdvice" class="com.wisemapping.security.aop.UpdateSecurityAdvise">
|
||||
<property name="mindmapService" ref="mindmapService"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
<beans>
|
||||
<bean id="userManager" class="com.wisemapping.dao.UserManagerImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate"/>
|
||||
<property name="encoder" ref="passwordEncoder"/>
|
||||
</bean>
|
||||
|
||||
<bean id="mindmapManager" class="com.wisemapping.dao.MindmapManagerImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate"/>
|
||||
</bean>
|
||||
|
||||
<bean id="labelManager" class="com.wisemapping.dao.LabelManagerImpl">
|
||||
<property name="hibernateTemplate" ref="hibernateTemplate"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
</beans>
|
|
@ -1,124 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:property-placeholder location="/WEB-INF/app.properties" ignore-unresolvable="true"/>
|
||||
|
||||
<bean id="mailer" class="com.wisemapping.mail.Mailer">
|
||||
<constructor-arg index="0" value="${mail.serverSendEmail}"/>
|
||||
<constructor-arg index="1" value="${mail.supportEmail}"/>
|
||||
<constructor-arg index="2" value="${mail.errorReporterEmail}"/>
|
||||
|
||||
<property name="mailSender" ref="mailSender"/>
|
||||
<property name="velocityEngineWrapper" ref="velocityEngineWrapper"/>
|
||||
</bean>
|
||||
|
||||
<bean id="httpInvoker" class="com.wisemapping.service.google.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">
|
||||
<property name="userManager" ref="userManager"/>
|
||||
<property name="mindmapService" ref="mindMapServiceTarget"/>
|
||||
<property name="notificationService" ref="notificationService"/>
|
||||
<property name="messageSource" ref="messageSource"/>
|
||||
<property name="velocityEngineWrapper" ref="velocityEngineWrapper"/>
|
||||
<property name="googleService" ref="googleService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
<property name="target" ref="userServiceTarget"/>
|
||||
<property name="transactionAttributes">
|
||||
<props>
|
||||
<prop key="*">PROPAGATION_REQUIRED</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="mindMapServiceTarget" class="com.wisemapping.service.MindmapServiceImpl">
|
||||
<property name="mindmapManager" ref="mindmapManager"/>
|
||||
<property name="userService" ref="userService"/>
|
||||
<property name="notificationService" ref="notificationService"/>
|
||||
<property name="adminUser" value="${admin.user}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="recaptchaService" class="com.wisemapping.service.RecaptchaService">
|
||||
<property name="recaptchaSecret" value="${google.recaptcha2.secretKey}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="mindmapService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces" value="com.wisemapping.service.MindmapService"/>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<value>txInterceptor</value>
|
||||
<value>viewSecurityAdvisor</value>
|
||||
<value>updateSecurityAdvisor</value>
|
||||
</list>
|
||||
</property>
|
||||
<property name="target" ref="mindMapServiceTarget"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="labelServiceTarget" class="com.wisemapping.service.LabelServiceImpl">
|
||||
<property name="labelManager" ref="labelManager"/>
|
||||
</bean>
|
||||
|
||||
<bean id="labelService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
|
||||
<property name="transactionManager" ref="transactionManager"/>
|
||||
<property name="target" ref="labelServiceTarget"/>
|
||||
<property name="transactionAttributes">
|
||||
<props>
|
||||
<prop key="*">PROPAGATION_REQUIRED</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
|
||||
<property name="host" value="${mail.smtp.host}"/>
|
||||
<property name="port" value="${mail.smtp.port}"/>
|
||||
<property name="protocol" value="smtp"/>
|
||||
<property name="username" value="${mail.username}"/>
|
||||
<property name="password" value="${mail.password}"/>
|
||||
<property name="javaMailProperties">
|
||||
<props>
|
||||
<prop key="mail.smtp.auth">${mail.smtp.auth:false}</prop>
|
||||
<prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable:false}</prop>
|
||||
<prop key="mail.smtp.quitwait">${mail.smtp.quitwait:true}</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="velocityEngineWrapper" class="com.wisemapping.util.VelocityEngineWrapper">
|
||||
</bean>
|
||||
|
||||
<bean id="notificationService" class="com.wisemapping.mail.NotificationService">
|
||||
<property name="baseUrl" value="${site.baseurl:http://localhost:8080/}"/>
|
||||
<property name="mailer" ref="mailer"/>
|
||||
<property name="messageSource" ref="messageSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
|
||||
<property name="defaultEncoding" value="UTF-8"/>
|
||||
<property name="basenames">
|
||||
<list>
|
||||
<value>messages</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<import resource="wisemapping-security-${security.type}.xml"/>
|
||||
</beans>
|
|
@ -4,4 +4,6 @@ User-agent: *
|
|||
Allow: /
|
||||
Disallow: /c/restful/maps/*/document/xml-pub
|
||||
Disallow: /c/maps/*/edit
|
||||
Disallow: /c/maps/*/public
|
||||
Disallow: /c/maps/*/try
|
||||
|
||||
|
|
Loading…
Reference in New Issue