Several fixes
All checks were successful
Build, Push and Deploy / build-and-deploy (push) Successful in 55s

- added organizations
- added industries
- added logo in 2 colors for light and dark theme
- improved authorization to allow multi tenancy
- added Bruno configs
This commit is contained in:
Murat Özkorkmaz
2025-11-13 19:56:12 +01:00
parent 62c13ff0b1
commit fb416dff55
38 changed files with 948 additions and 53 deletions

View File

@@ -0,0 +1,17 @@
package de.iwomm.propify_api.security;
public class TenantContext {
private static final ThreadLocal<String> CURRENT_TENANT = new ThreadLocal<>();
public static void setTenantId(String tenantId) {
CURRENT_TENANT.set(tenantId);
}
public static String getTenantId() {
return CURRENT_TENANT.get();
}
public static void clear() {
CURRENT_TENANT.remove();
}
}

View File

@@ -0,0 +1,75 @@
package de.iwomm.propify_api.security;
import jakarta.persistence.EntityManager;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.List;
@Component
@Order(1)
public class TenantFilter extends OncePerRequestFilter {
private final EntityManager entityManager;
public TenantFilter(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String tenantId = null;
// 1⃣ Tenant-ID aus JWT lesen
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof JwtAuthenticationToken jwtAuth) {
Jwt jwt = jwtAuth.getToken();
// tenant_id Claim
tenantId = jwt.getClaimAsString("tenant_id");
// Rollen prüfen, Superadmin darf alles sehen
List<String> roles = jwt.getClaimAsStringList("roles");
if (roles != null && roles.contains("ROLE_SUPERADMIN")) {
tenantId = null; // kein Filter für Superadmin
}
}
// 2⃣ Fallback: Header (optional, falls JWT fehlt)
if (tenantId == null) {
tenantId = request.getHeader("X-Tenant-ID");
}
// 3⃣ TenantContext für diesen Thread setzen
TenantContext.setTenantId(tenantId);
// 4⃣ Hibernate Filter aktivieren (falls Tenant-ID vorhanden)
if (tenantId != null) {
Session session = entityManager.unwrap(Session.class);
session.enableFilter("tenantFilter")
.setParameter("tenantId", tenantId);
}
try {
filterChain.doFilter(request, response);
} finally {
// 5⃣ Aufräumen nach Request
TenantContext.clear();
}
}
}