WIP Commit to save the dev state
This commit is contained in:
parent
81d39042a6
commit
9f3197792a
|
|
@ -94,6 +94,10 @@
|
|||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.appsmith.server.aspects;
|
||||
|
||||
import com.appsmith.server.domains.User;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ContextAspect {
|
||||
|
||||
// @Around("execution(reactor.core.publisher.Mono+ com.appsmith.server.services.CrudService+")
|
||||
@Around("execution(reactor.core.publisher.Mono+ com.appsmith.server.services.CrudService.*(..))")
|
||||
public Mono<?> addAuthorization(ProceedingJoinPoint joinPoint) {
|
||||
try {
|
||||
log.debug("In the custom aspect");
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map(ctx -> ctx.getAuthentication())
|
||||
.map(auth -> auth.getPrincipal())
|
||||
.map(principal -> {
|
||||
User user = (User) principal;
|
||||
log.debug("{}", user.getAuthorities());
|
||||
if(user.getAuthorities().contains(new SimpleGrantedAuthority("read:applications"))) {
|
||||
log.debug("Got the permission");
|
||||
}
|
||||
return principal;
|
||||
})
|
||||
.then((Mono<?>) joinPoint.proceed());
|
||||
// return Mono.just(true);
|
||||
// return ((Mono<?>) joinPoint.proceed());
|
||||
// .subscriberContext(Context.of(UserRepository.CONTEXT_CLIENT_KEY, getClient()));
|
||||
} catch (Throwable throwable) {
|
||||
return Mono.error(throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ import com.appsmith.server.constants.Security;
|
|||
import com.appsmith.server.domains.LoginSource;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.UserState;
|
||||
import com.appsmith.server.repositories.GroupRepository;
|
||||
import com.appsmith.server.services.GroupService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -33,6 +35,9 @@ public class AuthenticationSuccessHandler implements ServerAuthenticationSuccess
|
|||
@Autowired
|
||||
UserService userService;
|
||||
|
||||
@Autowired
|
||||
GroupRepository groupRepository;
|
||||
|
||||
private ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy();
|
||||
|
||||
/**
|
||||
|
|
@ -48,6 +53,7 @@ public class AuthenticationSuccessHandler implements ServerAuthenticationSuccess
|
|||
public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange,
|
||||
Authentication authentication) {
|
||||
log.debug("Login succeeded for user: {}", authentication.getPrincipal());
|
||||
|
||||
if (authentication instanceof OAuth2AuthenticationToken) {
|
||||
OAuth2AuthenticationToken oauthAuthentication = (OAuth2AuthenticationToken) authentication;
|
||||
return checkAndCreateUser(oauthAuthentication)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import lombok.Setter;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ import java.util.stream.Collectors;
|
|||
@Getter
|
||||
@Setter
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy
|
||||
public class CommonConfig {
|
||||
|
||||
private String ELASTIC_THREAD_POOL_NAME = "appsmith-elastic-pool";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.appsmith.server.configurations;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.PermissionEvaluator;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CustomPermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
|
||||
log.debug("In hasPermission with permission: {}", permission);
|
||||
SimpleGrantedAuthority authority = new SimpleGrantedAuthority((String) permission);
|
||||
return authentication.getAuthorities().contains(authority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
|
||||
log.debug("In hasPermission 2");
|
||||
SimpleGrantedAuthority authority = new SimpleGrantedAuthority((String) permission);
|
||||
return authentication.getAuthorities().contains(authority);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.appsmith.server.configurations;
|
||||
|
||||
import org.springframework.security.access.PermissionEvaluator;
|
||||
import org.springframework.security.access.expression.SecurityExpressionOperations;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
|
||||
import org.springframework.security.web.access.expression.WebSecurityExpressionRoot;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomWebExpressionHandler extends DefaultWebSecurityExpressionHandler {
|
||||
|
||||
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||
private String defaultRolePrefix = "ROLE_";
|
||||
|
||||
@Override
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(
|
||||
Authentication authentication, FilterInvocation fi) {
|
||||
|
||||
System.out.println("In the custom security expresssion root");
|
||||
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi);
|
||||
root.setPermissionEvaluator(getPermissionEvaluator());
|
||||
root.setTrustResolver(trustResolver);
|
||||
root.setRoleHierarchy(getRoleHierarchy());
|
||||
root.setDefaultRolePrefix(this.defaultRolePrefix);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PermissionEvaluator getPermissionEvaluator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,9 +7,15 @@ import com.appsmith.server.constants.Url;
|
|||
import com.appsmith.server.services.UserService;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.access.expression.SecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||
|
|
@ -30,6 +36,7 @@ import java.util.Arrays;
|
|||
import static com.appsmith.server.constants.Url.USER_URL;
|
||||
|
||||
@EnableWebFluxSecurity
|
||||
@EnableReactiveMethodSecurity
|
||||
public class SecurityConfig {
|
||||
|
||||
@Autowired
|
||||
|
|
@ -130,4 +137,12 @@ public class SecurityConfig {
|
|||
.and().build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler() {
|
||||
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||
expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
|
||||
|
||||
return expressionHandler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package com.appsmith.server.constants;
|
||||
|
||||
import com.appsmith.external.models.BaseDomain;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AclComponent<T extends BaseDomain> {
|
||||
|
||||
public String getPermission(Object entity) {
|
||||
System.out.println("In the getPermission");
|
||||
return "read:applications";
|
||||
}
|
||||
}
|
||||
|
|
@ -17,4 +17,10 @@ public interface AclConstants {
|
|||
"create:users",
|
||||
"read:users"
|
||||
);
|
||||
|
||||
String READ_APPLICATION_PERMISSION = "read:applications";
|
||||
String CREATE_APPLICATION_PERMISSION = "create:applications";
|
||||
String DELETE_APPLICATION_PERMISSION = "delete:applications";
|
||||
String UPDATE_APPLICATION_PERMISSION = "update:applications";
|
||||
String PUBLISH_APPLICATION_PERMISSION = "publish:applications";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,15 +59,9 @@ public class User extends BaseDomain implements UserDetails {
|
|||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
|
||||
if (roles == null || roles.isEmpty()) //No existing roles found.
|
||||
return null;
|
||||
|
||||
Collection<SimpleGrantedAuthority> authorities = roles.stream()
|
||||
.map(role -> new SimpleGrantedAuthority(role.toString()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return authorities;
|
||||
return this.getPermissions().stream()
|
||||
.map(permission -> new SimpleGrantedAuthority(permission))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package com.appsmith.server.repositories;
|
||||
|
||||
import com.appsmith.server.domains.Application;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Repository
|
||||
|
|
@ -10,4 +13,10 @@ public interface ApplicationRepository extends BaseRepository<Application, Strin
|
|||
Mono<Application> findByIdAndOrganizationId(String id, String orgId);
|
||||
|
||||
Mono<Application> findByName(String name);
|
||||
|
||||
@Override
|
||||
Flux<Application> findAll(Example example);
|
||||
|
||||
@Override
|
||||
Mono<Application> findById(String id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.appsmith.server.repositories;
|
||||
|
||||
import com.appsmith.server.domains.User;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
@ -8,4 +9,8 @@ import reactor.core.publisher.Mono;
|
|||
public interface UserRepository extends BaseRepository<User, String> {
|
||||
|
||||
Mono<User> findByEmail(String email);
|
||||
// {
|
||||
// System.out.println("In the custom findByEmail");
|
||||
// return Mono.empty();
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,31 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.server.domains.Application;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
//@Domain("applications")
|
||||
public interface ApplicationService extends CrudService<Application, String> {
|
||||
|
||||
// @Override
|
||||
// @PreAuthorize("hasPermission('someValue', T(com.appsmith.server.constants.AclConstants).READ_APPLICATION_PERMISSION)")
|
||||
// Mono<Application> getById(String id);
|
||||
|
||||
@PreAuthorize("hasPermission(#user, T(com.appsmith.server.constants.AclConstants).READ_APPLICATION_PERMISSION)")
|
||||
Mono<Application> findById(String id);
|
||||
|
||||
@PreAuthorize("hasPermission(#user, T(com.appsmith.server.constants.AclConstants).READ_APPLICATION_PERMISSION)")
|
||||
Mono<Application> findByIdAndOrganizationId(String id, String organizationId);
|
||||
|
||||
@PreAuthorize("hasPermission(#user, T(com.appsmith.server.constants.AclConstants).READ_APPLICATION_PERMISSION)")
|
||||
Mono<Application> findByName(String name);
|
||||
|
||||
@PreAuthorize("hasPermission(#user, T(com.appsmith.server.constants.AclConstants).PUBLISH_APPLICATION_PERMISSION)")
|
||||
Mono<Boolean> publish(String applicationId);
|
||||
|
||||
@PreAuthorize("hasPermission(#user, T(com.appsmith.server.constants.AclConstants).CREATE_APPLICATION_PERMISSION)")
|
||||
Mono<Application> save(Application application);
|
||||
|
||||
@PreAuthorize("hasPermission(#user, T(com.appsmith.server.constants.AclConstants).DELETE_APPLICATION_PERMISSION)")
|
||||
Mono<Application> archive(Application application);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public interface CrudService<T extends BaseDomain, ID> {
|
|||
|
||||
Mono<T> update(ID id, T resource);
|
||||
|
||||
// @PreAuthorize("hasPermission('someValue', @aclComponent.getPermission(#returnObject))")
|
||||
Mono<T> getById(ID id);
|
||||
|
||||
Mono<T> delete(ID id);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
//public @interface Domain {
|
||||
//}
|
||||
|
|
@ -11,6 +11,7 @@ import com.appsmith.server.exceptions.AppsmithError;
|
|||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.helpers.BeanCopyUtils;
|
||||
import com.appsmith.server.notifications.EmailSender;
|
||||
import com.appsmith.server.repositories.GroupRepository;
|
||||
import com.appsmith.server.repositories.InviteUserRepository;
|
||||
import com.appsmith.server.repositories.PasswordResetTokenRepository;
|
||||
import com.appsmith.server.repositories.UserRepository;
|
||||
|
|
@ -46,7 +47,7 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
|
|||
private final PasswordResetTokenRepository passwordResetTokenRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final EmailSender emailSender;
|
||||
private final GroupService groupService;
|
||||
private final GroupRepository groupRepository;
|
||||
private final InviteUserRepository inviteUserRepository;
|
||||
private final UserOrganizationService userOrganizationService;
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
|
|||
PasswordResetTokenRepository passwordResetTokenRepository,
|
||||
PasswordEncoder passwordEncoder,
|
||||
EmailSender emailSender,
|
||||
GroupService groupService,
|
||||
GroupRepository groupRepository,
|
||||
InviteUserRepository inviteUserRepository,
|
||||
UserOrganizationService userOrganizationService) {
|
||||
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
||||
|
|
@ -79,7 +80,7 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
|
|||
this.passwordResetTokenRepository = passwordResetTokenRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.emailSender = emailSender;
|
||||
this.groupService = groupService;
|
||||
this.groupRepository = groupRepository;
|
||||
this.inviteUserRepository = inviteUserRepository;
|
||||
this.userOrganizationService = userOrganizationService;
|
||||
}
|
||||
|
|
@ -485,6 +486,15 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
|
|||
.switchIfEmpty(Mono.error(new UsernameNotFoundException("Unable to find username: " + username)))
|
||||
// This object cast is required to ensure that we send the right object type back to Spring framework.
|
||||
// Doesn't work without this.
|
||||
.map(user -> (UserDetails) user);
|
||||
.flatMap(user -> {
|
||||
Set<String> groupSet = user.getGroupIds();
|
||||
|
||||
return groupRepository.findAllById(groupSet)
|
||||
.map(group -> group.getPermissions())
|
||||
// Adding permissions from all the groups that the user is a part of
|
||||
.map(permissions -> user.getPermissions().addAll(permissions))
|
||||
.collectList()
|
||||
.thenReturn((UserDetails) user);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Appsmith Configurations
|
||||
appsmith.baseUri=http://localhost:8080
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
|
||||
#Mongo properties
|
||||
spring.data.mongodb.database=mobtools
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user