not yet completed migration to jakarta - still keycloak roles missing
This commit is contained in:
@ -19,7 +19,12 @@
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
10
.project
10
.project
@ -10,11 +10,6 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
@ -25,6 +20,11 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
|
@ -1,11 +1,14 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.compliance=17
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=17
|
||||
|
@ -1,48 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
|
||||
|
||||
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="timetrack">
|
||||
|
||||
|
||||
|
||||
|
||||
<property name="context-root" value="timetrack"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/webapp"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<wb-resource deploy-path="/" source-path="src/main/webapp"/>
|
||||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
|
||||
|
||||
|
||||
|
||||
|
||||
</wb-module>
|
||||
|
||||
|
||||
|
||||
|
||||
</project-modules>
|
||||
|
@ -3,5 +3,5 @@
|
||||
<fixed facet="jst.java"/>
|
||||
<fixed facet="jst.web"/>
|
||||
<installed facet="jst.web" version="2.4"/>
|
||||
<installed facet="jst.java" version="11"/>
|
||||
<installed facet="jst.java" version="17"/>
|
||||
</faceted-project>
|
||||
|
39
build.gradle
39
build.gradle
@ -1,19 +1,18 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.6.5'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
id 'org.springframework.boot' version '3.1.1'
|
||||
id 'java'
|
||||
id 'war'
|
||||
}
|
||||
|
||||
group = 'de.jottyfan'
|
||||
version = '1.2.8'
|
||||
sourceCompatibility = '11'
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
|
||||
ext['spring-framework.version'] = '5.3.18'
|
||||
group = 'de.jottyfan'
|
||||
version = '1.2.9'
|
||||
|
||||
description = """timetrack"""
|
||||
|
||||
sourceCompatibility = 11
|
||||
targetCompatibility = 11
|
||||
sourceCompatibility = 17
|
||||
targetCompatibility = 17
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@ -23,12 +22,6 @@ repositories {
|
||||
// maven { url "https://gitlab.com/jottyfan/libs/-/raw/main" }
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom 'org.keycloak.bom:keycloak-adapter-bom:21.1.1'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
|
||||
@ -46,14 +39,14 @@ dependencies {
|
||||
|
||||
implementation 'org.webjars.bowergithub.datatables:datatables:1.10.21'
|
||||
|
||||
implementation 'org.keycloak:keycloak-spring-boot-starter:17.0.1'
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-jooq'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
|
||||
implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.1.1'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
||||
implementation 'de.jottyfan:timetrackjooq:0.1.1'
|
||||
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.0.0'
|
||||
@ -64,6 +57,18 @@ dependencies {
|
||||
testImplementation 'org.springframework.security:spring-security-test'
|
||||
}
|
||||
|
||||
war {
|
||||
doFirst {
|
||||
manifest {
|
||||
attributes("Implementation-Title": project.name,
|
||||
"Implementation-Version": version,
|
||||
"Implementation-Timestamp": new Date())
|
||||
}
|
||||
}
|
||||
baseName = project.name
|
||||
version = version
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
@ -2,14 +2,21 @@ package de.jottyfan.timetrack;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
public class TimetrackApplication {
|
||||
public class TimetrackApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(
|
||||
SpringApplicationBuilder application) {
|
||||
return application.sources(TimetrackApplication.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TimetrackApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
package de.jottyfan.timetrack.config;
|
||||
|
||||
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
|
||||
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
|
||||
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
|
||||
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
|
||||
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
|
||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
|
||||
@KeycloakConfiguration
|
||||
@ComponentScan(basePackageClasses = KeycloakSpringBootConfigResolver.class)
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
|
||||
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
|
||||
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
|
||||
auth.authenticationProvider(keycloakAuthenticationProvider);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
|
||||
return new KeycloakSpringBootConfigResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
@ConditionalOnMissingBean(HttpSessionManager.class)
|
||||
protected HttpSessionManager httpSessionManager() {
|
||||
return new HttpSessionManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
|
||||
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
super.configure(http);
|
||||
http.authorizeRequests().antMatchers("/public/**").permitAll();
|
||||
http.csrf().disable();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package de.jottyfan.timetrack.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler;
|
||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
import de.jottyfan.timetrack.config.converter.KeycloakRealmRoleConverter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Value("${spring.security.oauth2.client.provider.keycloak.jwk-set-uri}")
|
||||
private String jwtSetUri;
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity sec, InMemoryClientRegistrationRepository crr)
|
||||
throws Exception {
|
||||
sec.csrf(o -> o.disable()).anonymous(o -> o.disable())
|
||||
// @formatter:off
|
||||
.oauth2Login(o -> o.defaultSuccessUrl("/"))
|
||||
.logout(o -> o.logoutSuccessHandler(new OidcClientInitiatedLogoutSuccessHandler(crr)))
|
||||
.authorizeHttpRequests(o -> o.requestMatchers("/public/**").permitAll().anyRequest().authenticated())
|
||||
.oauth2ResourceServer(o -> o.jwt(j -> j.jwtAuthenticationConverter(getConverter())));
|
||||
// @formatter:on
|
||||
return sec.build();
|
||||
}
|
||||
|
||||
private Converter<Jwt, ? extends AbstractAuthenticationToken> getConverter() {
|
||||
JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
|
||||
jwtConverter.setJwtGrantedAuthoritiesConverter(new KeycloakRealmRoleConverter());
|
||||
return jwtConverter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
JwtDecoder jwtDecoder() {
|
||||
return NimbusJwtDecoder.withJwkSetUri(this.jwtSetUri).build();
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package de.jottyfan.timetrack.config.converter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public class KeycloakRealmRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
|
||||
@Override
|
||||
public Collection<GrantedAuthority> convert(Jwt jwt) {
|
||||
Object o = jwt.getClaims().get("realm_access");
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<String, Object> realmAccess = (Map<String, Object>) o;
|
||||
Object o2 = realmAccess.get("roles");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> l = (List<String>) o2;
|
||||
return l.stream().map(roleName -> "ROLE_" + roleName).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -4,13 +4,10 @@ import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -19,8 +16,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import de.jottyfan.timetrack.modules.done.DoneBean;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.IDoneService;
|
||||
import de.jottyfan.timetrack.modules.done.DoneService;
|
||||
import de.jottyfan.timetrack.modules.done.SummaryBean;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -31,15 +31,8 @@ import de.jottyfan.timetrack.modules.done.SummaryBean;
|
||||
public class IndexController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(IndexController.class);
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
private IDoneService doneService;
|
||||
|
||||
@Autowired
|
||||
public IndexController(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
private DoneService doneService;
|
||||
|
||||
@GetMapping("/logout")
|
||||
public String getLogout(HttpServletRequest request) throws ServletException {
|
||||
@ -49,8 +42,8 @@ public class IndexController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping("/")
|
||||
public String getIndex(@ModelAttribute DoneModel doneModel, Model model) {
|
||||
String username = doneService.getCurrentUser(request);
|
||||
public String getIndex(@ModelAttribute DoneModel doneModel, Model model, OAuth2AuthenticationToken token) {
|
||||
String username = doneService.getCurrentUser(token);
|
||||
Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file
|
||||
LocalDate day = LocalDate.now();
|
||||
List<DoneBean> list = doneService.getList(day, username);
|
||||
|
@ -3,13 +3,8 @@ package de.jottyfan.timetrack.modules.contact;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -20,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import de.jottyfan.timetrack.db.contact.enums.EnumContacttype;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -28,22 +24,14 @@ import de.jottyfan.timetrack.db.contact.enums.EnumContacttype;
|
||||
*/
|
||||
@Controller
|
||||
public class ContactController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ContactController.class);
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
private IContactService contactService;
|
||||
|
||||
@Autowired
|
||||
public ContactController(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
private ContactService contactService;
|
||||
|
||||
@ModelAttribute("currentUser")
|
||||
@ResponseBody
|
||||
public String getCurrentUser() {
|
||||
return contactService.getCurrentUser(request);
|
||||
public String getCurrentUser(OAuth2AuthenticationToken token) {
|
||||
return contactService.getCurrentUser(token);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
|
@ -31,11 +31,11 @@ import de.jottyfan.timetrack.db.contact.tables.records.TContactRecord;
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public class ContactGateway {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ContactGateway.class);
|
||||
public class ContactRepository {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ContactRepository.class);
|
||||
private final DSLContext jooq;
|
||||
|
||||
public ContactGateway(@Autowired DSLContext jooq) throws Exception {
|
||||
public ContactRepository(@Autowired DSLContext jooq) throws Exception {
|
||||
this.jooq = jooq;
|
||||
}
|
||||
|
@ -3,13 +3,13 @@ package de.jottyfan.timetrack.modules.contact;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -20,32 +20,41 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
*/
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManager")
|
||||
public class ContactService implements IContactService {
|
||||
public class ContactService {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ContactService.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
@Override
|
||||
public String getCurrentUser(HttpServletRequest request) {
|
||||
KeycloakSecurityContext ksc = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
return ksc == null ? "" : ksc.getIdToken().getPreferredUsername();
|
||||
@Autowired
|
||||
private OAuth2AuthorizedClientService security;
|
||||
|
||||
public String getCurrentUser(OAuth2AuthenticationToken token) {
|
||||
if (token != null) {
|
||||
OAuth2AuthorizedClient client = security.loadAuthorizedClient(token.getAuthorizedClientRegistrationId(),
|
||||
token.getName());
|
||||
if (client != null) {
|
||||
return client.getPrincipalName();
|
||||
} else {
|
||||
return "client is null";
|
||||
}
|
||||
} else {
|
||||
return "oauth token is null";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContactBean> getList() {
|
||||
try {
|
||||
return new ContactGateway(dsl).getAll();
|
||||
return new ContactRepository(dsl).getAll();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(ContactBean bean) {
|
||||
try {
|
||||
ContactGateway gw = new ContactGateway(dsl);
|
||||
ContactRepository gw = new ContactRepository(dsl);
|
||||
return bean.getPk() == null ? gw.add(bean) : gw.update(bean);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
@ -53,25 +62,22 @@ public class ContactService implements IContactService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doDelete(Integer pk) {
|
||||
try {
|
||||
return new ContactGateway(dsl).delete(pk);
|
||||
return new ContactRepository(dsl).delete(pk);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getAmount() {
|
||||
return getList().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactBean getBean(Integer id) {
|
||||
try {
|
||||
return new ContactGateway(dsl).getBean(id);
|
||||
return new ContactRepository(dsl).getBean(id);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return null;
|
||||
|
@ -1,19 +0,0 @@
|
||||
package de.jottyfan.timetrack.modules.contact;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public interface IContactService {
|
||||
public List<ContactBean> getList();
|
||||
public Integer doUpsert(ContactBean bean);
|
||||
public Integer doDelete(Integer pk);
|
||||
public Integer getAmount();
|
||||
public String getCurrentUser(HttpServletRequest request);
|
||||
public ContactBean getBean(Integer id);
|
||||
}
|
@ -4,13 +4,9 @@ import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -19,6 +15,8 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
@ -26,22 +24,14 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
*/
|
||||
@Controller
|
||||
public class DoneController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(DoneController.class);
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
private IDoneService doneService;
|
||||
|
||||
@Autowired
|
||||
public DoneController(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
private DoneService doneService;
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/list")
|
||||
public String getList(@ModelAttribute DoneModel doneModel, Model model) {
|
||||
String username = doneService.getCurrentUser(request);
|
||||
public String getList(@ModelAttribute DoneModel doneModel, Model model, OAuth2AuthenticationToken token) {
|
||||
String username = doneService.getCurrentUser(token);
|
||||
Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file
|
||||
LocalDate day = doneModel.getDay();
|
||||
List<DoneBean> list = doneService.getList(day, username);
|
||||
@ -61,10 +51,10 @@ public class DoneController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping("/done/abort/{day}")
|
||||
public String abort(@PathVariable String day, Model model) {
|
||||
public String abort(@PathVariable String day, Model model, OAuth2AuthenticationToken token) {
|
||||
DoneModel doneModel = new DoneModel();
|
||||
doneModel.setDayString(day);
|
||||
return getList(doneModel, model);
|
||||
return getList(doneModel, model, token);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@ -99,21 +89,21 @@ public class DoneController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/upsert", method = RequestMethod.POST)
|
||||
public String doUpsert(Model model, @ModelAttribute DoneBean bean) {
|
||||
String username = doneService.getCurrentUser(request);
|
||||
public String doUpsert(Model model, @ModelAttribute DoneBean bean, OAuth2AuthenticationToken token) {
|
||||
String username = doneService.getCurrentUser(token);
|
||||
Integer amount = doneService.doUpsert(bean, username);
|
||||
DoneModel doneModel = new DoneModel();
|
||||
doneModel.setDay(bean.getLocalDate());
|
||||
return amount.equals(1) ? getList(doneModel, model) : toItem(bean.getPk(), model);
|
||||
return amount.equals(1) ? getList(doneModel, model, token) : toItem(bean.getPk(), model);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/delete/{id}")
|
||||
public String doDelete(@PathVariable Integer id, Model model) {
|
||||
public String doDelete(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) {
|
||||
DoneBean bean = doneService.getBean(id);
|
||||
Integer amount = doneService.doDelete(id);
|
||||
DoneModel doneModel = new DoneModel();
|
||||
doneModel.setDay(bean.getLocalDate());
|
||||
return amount.equals(1) ? getList(doneModel, model) : toItem(id, model);
|
||||
return amount.equals(1) ? getList(doneModel, model, token) : toItem(id, model);
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -27,20 +27,29 @@ import de.jottyfan.timetrack.modules.note.NoteService;
|
||||
*/
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManager")
|
||||
public class DoneService implements IDoneService {
|
||||
public class DoneService {
|
||||
private static final Logger LOGGER = LogManager.getLogger(NoteService.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
@Override
|
||||
public String getCurrentUser(HttpServletRequest request) {
|
||||
KeycloakSecurityContext ksc = (KeycloakSecurityContext) request
|
||||
.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
return ksc == null ? "" : ksc.getIdToken().getPreferredUsername();
|
||||
@Autowired
|
||||
private OAuth2AuthorizedClientService security;
|
||||
|
||||
public String getCurrentUser(OAuth2AuthenticationToken token) {
|
||||
if (token != null) {
|
||||
OAuth2AuthorizedClient client = security.loadAuthorizedClient(token.getAuthorizedClientRegistrationId(),
|
||||
token.getName());
|
||||
if (client != null) {
|
||||
return client.getPrincipalName();
|
||||
} else {
|
||||
return "client is null";
|
||||
}
|
||||
} else {
|
||||
return "oauth token is null";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DoneBean> getList(LocalDate day, String username) {
|
||||
try {
|
||||
DoneGateway gw = new DoneGateway(dsl);
|
||||
@ -55,7 +64,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DoneBean> getWeek(LocalDate day, String username) {
|
||||
try {
|
||||
DoneGateway gw = new DoneGateway(dsl);
|
||||
@ -70,8 +78,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DoneBean getBean(Integer id) {
|
||||
try {
|
||||
return new DoneGateway(dsl).getBean(id);
|
||||
@ -81,7 +87,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VProjectRecord> getProjects(boolean includeNull) {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllProjects(includeNull);
|
||||
@ -91,7 +96,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VModuleRecord> getModules(boolean includeNull) {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllModules(includeNull);
|
||||
@ -101,7 +105,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VJobRecord> getJobs(boolean includeNull) {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllJobs(includeNull);
|
||||
@ -111,7 +114,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VBillingRecord> getBillings(boolean includeNull) {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllBillings(includeNull);
|
||||
@ -121,7 +123,6 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(DoneBean bean, String username) {
|
||||
try {
|
||||
DoneGateway gw = new DoneGateway(dsl);
|
||||
|
@ -1,29 +0,0 @@
|
||||
package de.jottyfan.timetrack.modules.done;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VBillingRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public interface IDoneService {
|
||||
public List<DoneBean> getList(LocalDate day, String username);
|
||||
public List<DoneBean> getWeek(LocalDate day, String username);
|
||||
public DoneBean getBean(Integer id);
|
||||
public String getCurrentUser(HttpServletRequest request);
|
||||
public List<VProjectRecord> getProjects(boolean includeNull);
|
||||
public List<VModuleRecord> getModules(boolean includeNull);
|
||||
public List<VJobRecord> getJobs(boolean includeNull);
|
||||
public List<VBillingRecord> getBillings(boolean includeNull);
|
||||
public Integer doUpsert(DoneBean bean, String username);
|
||||
public Integer doDelete(Integer id);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package de.jottyfan.timetrack.modules.done.job;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TJobRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public interface IJobService {
|
||||
public TJobRecord get(Integer id);
|
||||
public Integer doUpsert(TJobRecord bean);
|
||||
public Integer doDelete(Integer id);
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package de.jottyfan.timetrack.modules.done.job;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -16,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TJobRecord;
|
||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -24,10 +22,8 @@ import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
*/
|
||||
@Controller
|
||||
public class JobController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(JobController.class);
|
||||
|
||||
@Autowired
|
||||
private IJobService jobService;
|
||||
private JobService jobService;
|
||||
|
||||
@Autowired
|
||||
private DoneController doneController;
|
||||
@ -42,9 +38,9 @@ public class JobController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/upsert/job", method = RequestMethod.POST)
|
||||
public String doUpsert(Model model, @ModelAttribute TJobRecord bean) {
|
||||
public String doUpsert(Model model, @ModelAttribute TJobRecord bean, OAuth2AuthenticationToken token) {
|
||||
Integer amount = jobService.doUpsert(bean);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toJob(bean.getPk(), model);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toJob(bean.getPk(), model);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@ -55,8 +51,8 @@ public class JobController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/delete/job/{id}")
|
||||
public String doDeleteJob(@PathVariable Integer id, Model model) {
|
||||
public String doDeleteJob(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) {
|
||||
Integer amount = jobService.doDelete(id);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toJob(id, model);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toJob(id, model);
|
||||
}
|
||||
}
|
||||
|
@ -8,18 +8,15 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TJobRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord;
|
||||
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManager")
|
||||
public class JobService implements IJobService {
|
||||
public class JobService {
|
||||
private static final Logger LOGGER = LogManager.getLogger(JobService.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
|
||||
@Override
|
||||
public TJobRecord get(Integer id) {
|
||||
try {
|
||||
return id == null ? new TJobRecord() : new JobGateway(dsl).get(id);
|
||||
@ -29,7 +26,6 @@ public class JobService implements IJobService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(TJobRecord bean) {
|
||||
try {
|
||||
return new JobGateway(dsl).upsert(bean);
|
||||
@ -39,7 +35,6 @@ public class JobService implements IJobService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doDelete(Integer id) {
|
||||
try {
|
||||
return new JobGateway(dsl).delete(id);
|
||||
|
@ -1,14 +0,0 @@
|
||||
package de.jottyfan.timetrack.modules.done.module;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public interface IModuleService {
|
||||
public TModuleRecord get(Integer id);
|
||||
public Integer doUpsert(TModuleRecord bean);
|
||||
public Integer doDelete(Integer id);
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
package de.jottyfan.timetrack.modules.done.module;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -24,10 +25,9 @@ import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
*/
|
||||
@Controller
|
||||
public class ModuleController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ModuleController.class);
|
||||
|
||||
@Autowired
|
||||
private IModuleService moduleService;
|
||||
private ModuleService moduleService;
|
||||
|
||||
@Autowired
|
||||
private DoneController doneController;
|
||||
@ -42,9 +42,9 @@ public class ModuleController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/upsert/module", method = RequestMethod.POST)
|
||||
public String doUpsert(Model model, @ModelAttribute TModuleRecord bean) {
|
||||
public String doUpsert(Model model, @ModelAttribute TModuleRecord bean, OAuth2AuthenticationToken token) {
|
||||
Integer amount = moduleService.doUpsert(bean);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toModule(bean.getPk(), model);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toModule(bean.getPk(), model);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@ -55,8 +55,8 @@ public class ModuleController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/delete/module/{id}")
|
||||
public String doDeleteModule(@PathVariable Integer id, Model model) {
|
||||
public String doDeleteModule(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) {
|
||||
Integer amount = moduleService.doDelete(id);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toModule(id, model);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toModule(id, model);
|
||||
}
|
||||
}
|
||||
|
@ -8,19 +8,15 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
|
||||
import de.jottyfan.timetrack.modules.done.project.IProjectService;
|
||||
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManager")
|
||||
public class ModuleService implements IModuleService {
|
||||
public class ModuleService {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ModuleService.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
|
||||
@Override
|
||||
public TModuleRecord get(Integer id) {
|
||||
try {
|
||||
return id == null ? new TModuleRecord() : new ModuleGateway(dsl).getModule(id);
|
||||
@ -30,7 +26,6 @@ public class ModuleService implements IModuleService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(TModuleRecord bean) {
|
||||
try {
|
||||
return new ModuleGateway(dsl).upsert(bean);
|
||||
@ -40,7 +35,6 @@ public class ModuleService implements IModuleService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doDelete(Integer id) {
|
||||
try {
|
||||
return new ModuleGateway(dsl).delete(id);
|
||||
|
@ -1,14 +0,0 @@
|
||||
package de.jottyfan.timetrack.modules.done.project;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public interface IProjectService {
|
||||
public TProjectRecord get(Integer id);
|
||||
public Integer doUpsert(TProjectRecord bean);
|
||||
public Integer doDelete(Integer id);
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package de.jottyfan.timetrack.modules.done.project;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -16,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
|
||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -24,10 +22,8 @@ import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
*/
|
||||
@Controller
|
||||
public class ProjectController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ProjectController.class);
|
||||
|
||||
@Autowired
|
||||
private IProjectService projectService;
|
||||
private ProjectService projectService;
|
||||
|
||||
@Autowired
|
||||
private DoneController doneController;
|
||||
@ -42,9 +38,9 @@ public class ProjectController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/upsert/project", method = RequestMethod.POST)
|
||||
public String doUpsert(Model model, @ModelAttribute TProjectRecord bean) {
|
||||
public String doUpsert(Model model, @ModelAttribute TProjectRecord bean, OAuth2AuthenticationToken token) {
|
||||
Integer amount = projectService.doUpsert(bean);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toProject(bean.getPk(), model);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toProject(bean.getPk(), model);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@ -55,8 +51,8 @@ public class ProjectController {
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/delete/project/{id}")
|
||||
public String doDeleteProject(@PathVariable Integer id, Model model) {
|
||||
public String doDeleteProject(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) {
|
||||
Integer amount = projectService.doDelete(id);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toProject(id, model);
|
||||
return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toProject(id, model);
|
||||
}
|
||||
}
|
||||
|
@ -11,14 +11,12 @@ import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
|
||||
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManager")
|
||||
public class ProjectService implements IProjectService {
|
||||
public class ProjectService {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ProjectService.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
|
||||
@Override
|
||||
public TProjectRecord get(Integer id) {
|
||||
try {
|
||||
return id == null ? new TProjectRecord() : new ProjectGateway(dsl).getProject(id);
|
||||
@ -28,7 +26,6 @@ public class ProjectService implements IProjectService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(TProjectRecord bean) {
|
||||
try {
|
||||
return new ProjectGateway(dsl).upsert(bean);
|
||||
@ -38,7 +35,6 @@ public class ProjectService implements IProjectService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doDelete(Integer id) {
|
||||
try {
|
||||
return new ProjectGateway(dsl).delete(id);
|
||||
|
@ -1,19 +0,0 @@
|
||||
package de.jottyfan.timetrack.modules.note;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public interface INoteService {
|
||||
public List<NoteBean> getList();
|
||||
public Integer doUpsert(NoteBean bean);
|
||||
public Integer doDelete(Integer pk);
|
||||
public Integer getAmount();
|
||||
public String getCurrentUser(HttpServletRequest request);
|
||||
public NoteBean getBean(Integer id);
|
||||
}
|
@ -3,11 +3,6 @@ package de.jottyfan.timetrack.modules.note;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
@ -19,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import de.jottyfan.timetrack.db.note.enums.EnumCategory;
|
||||
import de.jottyfan.timetrack.db.note.enums.EnumNotetype;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -27,17 +23,9 @@ import de.jottyfan.timetrack.db.note.enums.EnumNotetype;
|
||||
*/
|
||||
@Controller
|
||||
public class NoteController {
|
||||
private static final Logger LOGGER = LogManager.getLogger(NoteController.class);
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
private INoteService noteService;
|
||||
|
||||
@Autowired
|
||||
public NoteController(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
private NoteService noteService;
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/note/list")
|
||||
@ -79,5 +67,4 @@ public class NoteController {
|
||||
Integer amount = noteService.doDelete(id);
|
||||
return amount.equals(1) ? getList(model) : toItem(id, model);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,13 +3,13 @@ package de.jottyfan.timetrack.modules.note;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -20,19 +20,29 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
*/
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManager")
|
||||
public class NoteService implements INoteService {
|
||||
public class NoteService {
|
||||
private static final Logger LOGGER = LogManager.getLogger(NoteService.class);
|
||||
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
@Override
|
||||
public String getCurrentUser(HttpServletRequest request) {
|
||||
KeycloakSecurityContext ksc = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
return ksc == null ? "" : ksc.getIdToken().getPreferredUsername();
|
||||
@Autowired
|
||||
private OAuth2AuthorizedClientService security;
|
||||
|
||||
public String getCurrentUser(OAuth2AuthenticationToken token) {
|
||||
if (token != null) {
|
||||
OAuth2AuthorizedClient client = security.loadAuthorizedClient(token.getAuthorizedClientRegistrationId(),
|
||||
token.getName());
|
||||
if (client != null) {
|
||||
return client.getPrincipalName();
|
||||
} else {
|
||||
return "client is null";
|
||||
}
|
||||
} else {
|
||||
return "oauth token is null";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoteBean> getList() {
|
||||
try {
|
||||
return new NoteGateway(dsl).getAll();
|
||||
@ -42,7 +52,6 @@ public class NoteService implements INoteService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(NoteBean bean) {
|
||||
try {
|
||||
NoteGateway gw = new NoteGateway(dsl);
|
||||
@ -53,7 +62,6 @@ public class NoteService implements INoteService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doDelete(Integer pk) {
|
||||
try {
|
||||
return new NoteGateway(dsl).delete(pk);
|
||||
@ -63,12 +71,10 @@ public class NoteService implements INoteService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getAmount() {
|
||||
return getList().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteBean getBean(Integer id) {
|
||||
try {
|
||||
return new NoteGateway(dsl).getBean(id);
|
||||
|
@ -1,21 +1,25 @@
|
||||
# jooq
|
||||
spring.datasource.driver-class-name = org.postgresql.Driver
|
||||
# todo: export to /etc/timetrack
|
||||
spring.datasource.url = jdbc:postgresql://localhost:5432/timetrack
|
||||
spring.datasource.username = timetrack
|
||||
spring.datasource.password = timetrack
|
||||
|
||||
# security
|
||||
keycloak.url = http://localhost:8080/realms/jottyfan
|
||||
keycloak.openid.url = ${keycloak.url}/protocol/openid-connect
|
||||
spring.security.oauth2.client.registration.keycloak.client-id = timetrack
|
||||
spring.security.oauth2.client.registration.keycloak.scope = openid
|
||||
spring.security.oauth2.client.registration.keycloak.authorization-grant-type = authorization_code
|
||||
# todo: export to /etc/timetrack
|
||||
spring.security.oauth2.client.registration.keycloak.redirect-uri = http://localhost:8888/timetrack/login/oauth2/code/timetrack
|
||||
spring.security.oauth2.client.provider.keycloak.issuer-uri = ${keycloak.url}
|
||||
spring.security.oauth2.client.provider.keycloak.authorization-uri = ${keycloak.openid.url}/auth
|
||||
spring.security.oauth2.client.provider.keycloak.token-uri = ${keycloak.openid.url}/token
|
||||
spring.security.oauth2.client.provider.keycloak.user-info-uri = ${keycloak.openid.url}/userinfo
|
||||
spring.security.oauth2.client.provider.keycloak.jwk-set-uri = ${keycloak.openid.url}/certs
|
||||
spring.security.oauth2.client.provider.keycloak.user-name-attribute = preferred_username
|
||||
|
||||
# application
|
||||
server.port = 8083
|
||||
|
||||
server:.port = 8083
|
||||
server.servlet.context-path = /timetrack
|
||||
|
||||
# keycloak
|
||||
keycloak.auth-server-url = https://www.jottyfan.de/auth
|
||||
keycloak.realm = jottyfan
|
||||
keycloak.resource = timetrack
|
||||
keycloak.public-client = true
|
||||
keycloak.security-constraints[0].authRoles[0] = timetrack_user
|
||||
keycloak.security-constraints[0].securityCollections[0].patterns[0] = /*
|
||||
#keycloak.credentia
|
||||
keycloak.use-resource-role-mappings=true
|
||||
#keycloak.bearer-only=true
|
||||
|
@ -259,8 +259,6 @@ body {
|
||||
|
||||
.spanlabel {
|
||||
display: inline-block;
|
||||
min-width: 128px;
|
||||
max-width: 128px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
@ -1,42 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security" layout:decorate="~{layout/main.html}">
|
||||
|
||||
<head>
|
||||
<title>Timetrack</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ul layout:fragment="menu">
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
<div class="card text-dark bg-light" style="width: 256px; margin: 24px">
|
||||
<div class="card-header"><a class="btn btn-seondary btn-bordered btn-secondaryhover" style="width: 100%" th:href="@{/done/list}">heutige Arbeitszeiten</a></div>
|
||||
<div class="card text-dark bg-light" style="width: 312px; margin: 24px">
|
||||
<div class="card-header"><a class="btn btn-seondary btn-bordered btn-secondaryhover" style="width: 100%"
|
||||
th:href="@{/done/list}">heutige Arbeitszeiten</a></div>
|
||||
<div class="card-body">
|
||||
<div>
|
||||
<span class="spanlabel">Start:</span> <span class="emphgreen" th:text="${sum.start}"></span>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-8"><span class="spanlabel">Start:</span></div>
|
||||
<div class="col-4"><span class="emphgreen" th:text="${sum.start}"></span></div>
|
||||
<div class="col-8"><span class="spanlabel">Ende:</span></div>
|
||||
<div class="col-4"><span class="emphgreen" th:text="${sum.end}"></span></div>
|
||||
<div class="col-8"><span class="spanlabel">Arbeitszeit total:</span></div>
|
||||
<div class="col-4"><span class="emphblue" th:text="${sum.total}"></span></div>
|
||||
<div class="col-8"><span class="spanlabel">Pausezeit total:</span></div>
|
||||
<div class="col-4"><span class="emphorange" th:text="${sum.pause}"></span></div>
|
||||
<div class="col-8"><span class="spanlabel">Überstunden:</span></div>
|
||||
<div class="col-4"><span class="emphred" th:text="${sum.overdue}"></span></div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="spanlabel">Ende:</span> <span class="emphgreen" th:text="${sum.end}"></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="spanlabel">Arbeitszeit total:</span> <span class="emphblue" th:text="${sum.total}"></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="spanlabel">Pausezeit total:</span> <span class="emphorange" th:text="${sum.pause}"></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="spanlabel">Überstunden:</span> <span class="emphred" th:text="${sum.overdue}"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<span th:if="${sum.getBillingTime('WP2') != '0,0 h'}"><span class="billing WP2">WP2</span><span
|
||||
th:text="${sum.getBillingTime('WP2')}" class="distfat"></span></span> <span th:if="${sum.getBillingTime('WP4') != '0,0 h'}"><span
|
||||
class="billing WP4">WP4</span><span th:text="${sum.getBillingTime('WP4')}" class="distfat"></span></span> <span
|
||||
th:text="${sum.getBillingTime('WP2')}" class="distfat"></span></span> <span
|
||||
th:if="${sum.getBillingTime('WP4') != '0,0 h'}"><span class="billing WP4">WP4</span><span
|
||||
th:text="${sum.getBillingTime('WP4')}" class="distfat"></span></span> <span
|
||||
th:if="${sum.getBillingTime('WP5') != '0,0 h'}"><span class="billing WP5">WP5</span><span
|
||||
th:text="${sum.getBillingTime('WP5')}" class="distfat"></span></span> <span th:if="${sum.getBillingTime('TA3') != '0,0 h'}"><span
|
||||
class="billing TA3">TA3</span><span th:text="${sum.getBillingTime('TA3')}" class="distfat"></span></span> <span class="billing">X</span><span
|
||||
th:text="${sum.getBillingTime('WP5')}" class="distfat"></span></span> <span
|
||||
th:if="${sum.getBillingTime('TA3') != '0,0 h'}"><span class="billing TA3">TA3</span><span
|
||||
th:text="${sum.getBillingTime('TA3')}" class="distfat"></span></span> <span class="billing">X</span><span
|
||||
th:text="${sum.getBillingTime(null)}" class="distfat"></span>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
Reference in New Issue
Block a user