Skip to content

Commit

Permalink
Merge pull request #275 from netgrif/NAE-1975
Browse files Browse the repository at this point in the history
[NAE-1975] NAE nodes gRPC communication
  • Loading branch information
machacjozef authored Nov 11, 2024
2 parents ea54563 + 285b47b commit 0d8a94f
Show file tree
Hide file tree
Showing 30 changed files with 277 additions and 155 deletions.
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: "3.3"

services:
docker-mongo:
image: mongo:7.0.9
image: mongo:8.0.3
ports:
- "27017:27017"
deploy:
Expand All @@ -15,7 +15,7 @@ services:
memory: "512M"

docker-elastic:
image: elasticsearch:8.10.4
image: elasticsearch:8.15.3
environment:
- cluster.name=elasticsearch
- discovery.type=single-node
Expand All @@ -35,7 +35,7 @@ services:
memory: "512M"

docker-redis:
image: redis:7.2.5
image: redis:7.4.1
ports:
- "6379:6379"
minio:
Expand Down
45 changes: 28 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<sonar.organization>netgrif-oss</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<jackson.version>2.17.1</jackson.version>
<jwt.version>0.11.5</jwt.version>
</properties>

<repositories>
Expand Down Expand Up @@ -205,17 +206,17 @@
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<version>${jwt.version}</version>
</dependency>

<!-- Session -->
Expand Down Expand Up @@ -575,6 +576,24 @@
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -618,7 +637,7 @@
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.1</version>
<version>3.0.2</version>
<executions>
<execution>
<goals>
Expand Down Expand Up @@ -661,19 +680,11 @@
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-source-plugin</artifactId>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>attach-sources</id>-->
<!-- <goals>-->
<!-- <goal>jar-no-fork</goal>-->
<!-- </goals>-->
<!-- <phase>package</phase>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ import com.netgrif.application.engine.petrinet.domain.events.DataEventType
import com.querydsl.core.annotations.PropertyType
import com.querydsl.core.annotations.QueryType
import org.bson.types.ObjectId
import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl
import org.springframework.data.annotation.Id
import org.springframework.data.annotation.Transient
import org.springframework.data.mongodb.core.mapping.Document

@Document
abstract class Field<T> extends Imported {
abstract class Field<T> extends Imported implements Serializable {

@Serial
static final long serialVersionUID = 8315043110342747937L

@Id
protected ObjectId _id

Expand Down Expand Up @@ -313,7 +317,7 @@ abstract class Field<T> extends Imported {
@Override
@QueryType(PropertyType.NONE)
MetaClass getMetaClass() {
return this.metaClass
return this.metaClass != null ? this.metaClass : ((MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry()).getMetaClass(this)
}

void clone(Field clone) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ public void addDefaultRole(IUser user) {
user.addProcessRole(processRoleService.defaultRole());
}

@Override
public void addAnonymousRole(IUser user) {
user.addProcessRole(processRoleService.defaultRole());
}

@Override
public void addDefaultAuthorities(IUser user) {
if (user.getAuthorities().isEmpty()) {
Expand All @@ -53,6 +58,15 @@ public void addDefaultAuthorities(IUser user) {
}
}

@Override
public void addAnonymousAuthorities(IUser user) {
if (user.getAuthorities().isEmpty()) {
HashSet<Authority> authorities = new HashSet<>();
authorities.add(authorityService.getOrCreate(Authority.anonymous));
user.setAuthorities(authorities);
}
}

@Override
public IUser assignAuthority(String userId, String authorityId) {
IUser user = resolveById(userId, true);
Expand Down Expand Up @@ -92,7 +106,8 @@ public IUser removeRole(IUser user, String roleStringId) {
return removeRole(user, processRoleService.findByImportId(roleStringId));
}

protected IUser removeRole(IUser user, ProcessRole role) {
@Override
public IUser removeRole(IUser user, ProcessRole role) {
user.removeProcessRole(role);
securityContextService.saveToken(user.getStringId());
securityContextService.reloadSecurityContext(user.transformToLoggedUser());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.netgrif.application.engine.auth.domain.LoggedUser;
import com.netgrif.application.engine.auth.web.requestbodies.UpdateUserRequest;
import com.netgrif.application.engine.petrinet.domain.PetriNet;
import com.netgrif.application.engine.petrinet.domain.roles.ProcessRole;
import com.netgrif.application.engine.workflow.domain.ProcessResourceId;
import org.bson.types.ObjectId;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -45,10 +46,12 @@ public interface IUserService {
Page<IUser> findAllActiveByProcessRoles(Set<String> roleIds, boolean small, Pageable pageable);

void addDefaultRole(IUser user);
void addAnonymousRole(IUser user);

List<IUser> findAllByProcessRoles(Set<String> roleIds, boolean small);

void addDefaultAuthorities(IUser user);
void addAnonymousAuthorities(IUser user);

IUser assignAuthority(String userId, String authorityId);

Expand All @@ -67,6 +70,7 @@ public interface IUserService {
Page<IUser> searchAllCoMembers(String query, LoggedUser principal, Boolean small, Pageable pageable);

IUser removeRole(IUser user, String roleStringId);
IUser removeRole(IUser user, ProcessRole processRole);

void removeRoleOfDeletedPetriNet(PetriNet net);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.netgrif.application.engine.auth.web.requestbodies;

public class UpdateUserRequest {
import java.io.Serial;
import java.io.Serializable;

public class UpdateUserRequest implements Serializable {
@Serial
private static final long serialVersionUID = 3681503301565489613L;
public String telNumber;
public String avatar;
public String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,11 @@ protected PublicAuthenticationFilter createPublicAuthenticationFilter() throws E
return new PublicAuthenticationFilter(
(ProviderManager) authenticationManager(authenticationManagerBuilder),
new AnonymousAuthenticationProvider(ANONYMOUS_USER),
authority,
this.naeAuthProperties.getServerPatterns(),
this.naeAuthProperties.getAnonymousExceptions(),
this.jwtService,
this.userService
naeAuthProperties.getServerPatterns(),
naeAuthProperties.getAnonymousExceptions(),
jwtService,
userService,
authorityService
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.netgrif.application.engine.configuration.security;

import com.netgrif.application.engine.auth.domain.*;
import com.netgrif.application.engine.auth.service.interfaces.IAuthorityService;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.configuration.security.jwt.IJwtService;
import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.security.authentication.AnonymousAuthenticationProvider;
Expand All @@ -15,37 +19,35 @@
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.Collections;
import java.util.Map;

@Slf4j
public class PublicAuthenticationFilter extends OncePerRequestFilter {

private final static String JWT_HEADER_NAME = "X-Jwt-Token";
private final static String BEARER = "Bearer ";
private final static String USER = "user";
private final ProviderManager authenticationManager;
private final AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
private final Authority anonymousAuthority;
private final String[] anonymousAccessUrls;
private final String[] exceptions;

private final IJwtService jwtService;
private final IUserService userService;
private final IAuthorityService authorityService;

public PublicAuthenticationFilter(ProviderManager authenticationManager, AnonymousAuthenticationProvider provider,
Authority anonymousAuthority, String[] urls, String[] exceptions, IJwtService jwtService,
IUserService userService) {
String[] urls, String[] exceptions, IJwtService jwtService,
IUserService userService, IAuthorityService authorityService) {
this.authenticationManager = authenticationManager;
this.authenticationManager.getProviders().add(provider);
this.anonymousAuthority = anonymousAuthority;
this.anonymousAccessUrls = urls;
this.exceptions = exceptions;
this.jwtService = jwtService;
this.userService = userService;
this.authorityService = authorityService;
}

@Override
Expand All @@ -62,64 +64,53 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
private void authenticate(HttpServletRequest request, String jwtToken) {
AnonymousAuthenticationToken authRequest = new AnonymousAuthenticationToken(
UserProperties.ANONYMOUS_AUTH_KEY,
jwtService.getLoggedUser(jwtToken, this.anonymousAuthority),
Collections.singleton(this.anonymousAuthority)
jwtService.getLoggedUser(jwtToken, Authority.anonymous),
Collections.singleton(authorityService.getOrCreate(Authority.anonymous))
);
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
Authentication authResult = this.authenticationManager.authenticate(authRequest);
SecurityContextHolder.getContext().setAuthentication(authResult);
}

private String resolveValidToken(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> claims = new HashMap<>();
String jwtHeader = request.getHeader(JWT_HEADER_NAME);
String jwtToken;
String jwtToken = null;

if (jwtHeader == null || !jwtHeader.startsWith(BEARER)) {
log.warn("There is no JWT token or token is invalid.");
resolveClaims(claims, request);
jwtToken = jwtService.tokenFrom(claims);
LoggedUser loggedUser = resolveLoggedUser(jwtToken);
jwtToken = jwtService.tokenFrom(Collections.emptyMap(), loggedUser.getUsername(), Map.of(USER, loggedUser));
} else {
jwtToken = jwtHeader.replace(BEARER, "");
}

try {
jwtService.isExpired(jwtToken);
} catch (ExpiredJwtException e) {
claims = e.getClaims();
resolveClaims(claims, request);
jwtToken = jwtService.tokenFrom(claims);
if (jwtService.isTokenExpired(jwtToken)) {
LoggedUser loggedUser = resolveLoggedUser(jwtToken);
jwtToken = jwtService.tokenFrom(Collections.emptyMap(), loggedUser.getUsername(), Map.of(USER, loggedUser));
}

return jwtToken;
}

private void resolveClaims(Map<String, Object> claims, HttpServletRequest request) {
LoggedUser loggedUser = createAnonymousUser(request);

if (claims.containsKey("user")) {
IUser user = userService.findAnonymousByEmail((String) ((LinkedHashMap) claims.get("user")).get("email"), false);
if (user != null)
loggedUser = user.transformToLoggedUser();
private LoggedUser resolveLoggedUser(String existingToken) {
LoggedUser loggedUser;
if (existingToken != null) {
loggedUser = jwtService.getLoggedUser(existingToken, Authority.anonymous);
} else {
loggedUser = createAnonymousUser();
}
loggedUser.eraseCredentials();
claims.put("user", loggedUser);
return loggedUser;
}

private LoggedUser createAnonymousUser(HttpServletRequest request) {
private LoggedUser createAnonymousUser() {
String hash = new ObjectId().toString();

AnonymousUser anonymousUser = (AnonymousUser) this.userService.findAnonymousByEmail(hash + "@nae.com", false);

if (anonymousUser == null) {
anonymousUser = new AnonymousUser(hash + "@anonymous.nae",
"n/a",
"User",
"Anonymous"
);
anonymousUser.setState(UserState.ACTIVE);
userService.saveNewAnonymous(anonymousUser);
}
AnonymousUser anonymousUser = new AnonymousUser(hash + "@anonymous.nae",
"n/a",
"User",
"Anonymous"
);
anonymousUser.setState(UserState.ACTIVE);
anonymousUser = userService.saveNewAnonymous(anonymousUser);
return anonymousUser.transformToLoggedUser();
}

Expand Down
Loading

0 comments on commit 0d8a94f

Please sign in to comment.