Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .docker/application.properties.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://{{.Env.JDBC_DATABASE_URL}}:{{.Env.JDBC_DATABASE_PORT}}/{{.Env.JDBC_DATABASE_NAME}}
spring.datasource.username={{.Env.JDBC_DATABASE_USERNAME}}
spring.datasource.password={{.Env.JDBC_DATABASE_PASSWORD}}
spring.jpa.show-sql=true
logging.level.io.github.patternatlas.api=info
spring.jpa.show-sql=false
spring.jpa.generate-ddl=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down Expand Up @@ -93,6 +94,7 @@ ResponseEntity<EntityModel<UserModel>> getUserById(@PathVariable UUID userId) {
*/
@RequestMapping(method = RequestMethod.GET, value = "/userinfo")
@ResponseBody
@PreAuthorize(value = "isLoggedIn()") // must be checked here since user needs to be logged in to get info
public Map<String, Object> user(Principal principal) {
if (principal != null) {
UUID id = UUID.fromString(principal.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
import org.springframework.security.core.Authentication;
Expand Down Expand Up @@ -52,6 +53,16 @@ public ResourceSecurityExpressionRoot(Authentication authentication,
this.userAuthService = userAuthService;
}

/**
* Checks if the user is logged in and makes sure the token-Information
* is stored in patternatlas db.
* @return true if the user is present in db and logged in, false otherwise
*/
public boolean isLoggedIn() {
Optional<UUID> userId = loggedInUUID();
return userId.isPresent();
}

/**
* Checks global permission for user.
* Will only check for the exact permission (e.g. ISSUE_CREATE)
Expand Down Expand Up @@ -83,13 +94,21 @@ private void createUser(UUID userId, Authentication authentication) {
UserModelRequest req = new UserModelRequest();
req.setId(userId);
req.setName(preferredUsername);

if(this.userAuthService.hasUsers()) {
// Create standard member user
this.userAuthService.createInitialMember(req);
} else {
// There are no other users registered => create admin user as first user
this.userAuthService.createInitialAdmin(req);
try {
if(this.userAuthService.hasUsers()) {
// Create standard member user
this.userAuthService.createInitialMember(req);
} else {
// There are no other users registered => create admin user as first user
this.userAuthService.createInitialAdmin(req);
}
} catch (DataIntegrityViolationException e) {
/*
Is thrown if two simultaneous calls are the first calls a user makes to the API.
In this case the second create user call will fail since both calls are made with
the same ID. Since the call only fails if the user was properly created
by the first call, this exception can be ignored.
*/
}
} catch (JsonProcessingException e) {
throw new UserNotFoundException("Cannot infer preferred username from Token");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@

import java.util.UUID;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

/**
* Service for manipulating users based on incomping JW-Tokens.
* Not to be used for REST-Access.
* Used to query user information to handle authentication.
*/
public interface UserAuthService {

@Transactional
UserEntity createInitialMember(UserModelRequest userModelRequest);

@Transactional
UserEntity createInitialAdmin(UserModelRequest userModelRequest);

boolean userExists(UUID userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import io.github.patternatlas.api.rest.model.user.RoleModelRequest;
import io.github.patternatlas.api.rest.model.user.UserModelRequest;

import javax.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -91,6 +93,7 @@ public UserEntity getUserById(UUID userId) {
}

private UserEntity createInitialUser(UserModelRequest userModelRequest, String requestedRole) {
logger.info("Automatically creating user " + userModelRequest.getName() + " (role: " + requestedRole + ")");
UserEntity user = new UserEntity(userModelRequest, "");
user.setEmail("");
user.getRoles().add(this.roleRepository.findByName(requestedRole));
Expand All @@ -99,14 +102,14 @@ private UserEntity createInitialUser(UserModelRequest userModelRequest, String r
}

@Override
@Transactional
public UserEntity createInitialMember(UserModelRequest userModelRequest) {
return createInitialUser(userModelRequest, RoleConstant.MEMBER);
}

@Override
@Transactional
public UserEntity createInitialAdmin(UserModelRequest userModelRequest) {
logger.info("Automatically creating admin user " + userModelRequest.getName());

return createInitialUser(userModelRequest, RoleConstant.ADMIN);
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ io.github.patternatlas.api.latexrenderer.port=5030
server.servlet.contextPath=/patternatlas
# liquibase file
spring.liquibase.change-log=patternatlas.xml
# DB debug logs
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.show_sql=false