/* * Copyright @ 2013 CurisTEC, S.A.S. All Rights Reserved. */ package net.curisit.securis.security; import java.security.Principal; import java.util.Map; import java.util.Set; import jakarta.ws.rs.core.SecurityContext; import net.curisit.integrity.commons.Utils; import net.curisit.securis.db.User; /** * BasicSecurityContext *

* Lightweight implementation of JAX-RS {@link SecurityContext} based on: * - A {@link Principal} holding the username. * - An integer bitmask of roles (see {@link User.Rol}). * - Optional scope restrictions (organization/application IDs). * * Role checks: * - {@link #isUserInRole(String)} maps string names to bit constants via {@link #ROLES}. * * Scope helpers: * - {@link #isOrgAccesible(Integer)} and {@link #isAppAccesible(Integer)}. * * @author JRA * Last reviewed by JRA on Oct 5, 2025. */ public class BasicSecurityContext implements SecurityContext { /** String role names mapped to bit flags. */ public static final String ROL_ADVANCE = "advance"; public static final String ROL_ADMIN = "admin"; public static final String ROL_BASIC = "basic"; /** Mapping from role name to bit flag. */ static final Map ROLES = Utils.createMap(ROL_BASIC, User.Rol.BASIC, ROL_ADVANCE, User.Rol.ADVANCE, ROL_ADMIN, User.Rol.ADMIN); Principal user = null; int roles = 0; boolean secure = false; Set organizationsIds = null; Set applicationsIds = null; double ran = 0; // small unique marker for debugging instances /** * BasicSecurityContext

* Construct a context for given user, roles and transport security flag. * * @param username principal name * @param roles bitmask of roles * @param secure whether the request is HTTPS */ public BasicSecurityContext(String username, int roles, boolean secure) { user = new UserPrincipal(username); this.roles = roles; this.secure = secure; ran = Math.random(); } /** * getUserPrincipal

* Return the user principal. * * @return mainUser */ @Override public Principal getUserPrincipal() { return user; } /** * isUserInRole

* Check role membership by name (mapped to bitmask). * * @param role * @return isUserInRole */ @Override public boolean isUserInRole(String role) { Integer introle = ROLES.get(role); return introle != null && (introle & roles) != 0; } /** * isSecure

* Return whether transport is secure (HTTPS). * * @return isSecure */ @Override public boolean isSecure() { return secure; } /** * getAuthenticationScheme

* Not used; returns null. * * @return authenticationsScheme */ @Override public String getAuthenticationScheme() { return null; } /** * toString

* Get the string describing the current object * * @return object string */ @Override public String toString() { return String.format("SecurityContextWrapper(%f) %s", ran, user); } /** * setOrganizationsIds

* Set org scope (IDs allowed). * * @param organizationsIds */ public void setOrganizationsIds(Set orgs) { this.organizationsIds = orgs; } /** * getOrganizationsIds

* Return org scope. * * @return organizationsIds */ public Set getOrganizationsIds() { return this.organizationsIds; } /** * getApplicationsIds

* Return app scope. * * @return applicationIds */ public Set getApplicationsIds() { return applicationsIds; } /** * setApplicationsIds

* Set app scope. * * @param applicationIds */ public void setApplicationsIds(Set applicationsIds) { this.applicationsIds = applicationsIds; } /** * UserPrincipal

* Inner Principal holding only the username. */ private class UserPrincipal implements Principal { final String name; /** * UserPrincipal

* Main user * * @param username */ public UserPrincipal(String name) { this.name = name; } /** * getName

* Get the username * * @return userName */ @Override public String getName() { return this.name; } /** * toString

* Get the string describing the current object * * @return object string */ @Override public String toString() { return String.format("[%s]", name); } } /** * isOrgAccesible

* Check if org id is within scope. * * @param orgId * @return isOrgAccesible */ public boolean isOrgAccesible(Integer orgid) { if (organizationsIds == null || orgid == null) return false; return organizationsIds.contains(orgid); } /** * isAppAccesible

* Check if app id is within scope. * * @param appId * @return isAppAccesible */ public boolean isAppAccesible(Integer appid) { if (applicationsIds == null || appid == null) return false; return applicationsIds.contains(appid); } }