001package ca.cdr.api.model.json; 002 003/* 004 * #%L 005 * Smile CDR - CDR 006 * %% 007 * Copyright (C) 2016 - 2024 Smile CDR, Inc. 008 * %% 009 * All rights reserved. 010 * #L% 011 */ 012 013import ca.cdr.api.model.enm.PermissionEnum; 014import com.fasterxml.jackson.annotation.JsonIgnore; 015import com.fasterxml.jackson.annotation.JsonProperty; 016import io.swagger.v3.oas.annotations.media.Schema; 017import jakarta.annotation.Nonnull; 018import org.apache.commons.lang3.builder.EqualsBuilder; 019import org.apache.commons.lang3.builder.HashCodeBuilder; 020import org.slf4j.Logger; 021import org.slf4j.LoggerFactory; 022import org.springframework.security.core.GrantedAuthority; 023 024import static org.apache.commons.lang3.StringUtils.*; 025 026@Schema( 027 name = "GrantedAuthority", 028 description = 029 "A granted authority is a single user authority (permission) that has been granted to a user. This authority has a permission name, and optionally an argument.") 030public class GrantedAuthorityJson implements GrantedAuthority, IModelJson, Comparable<GrantedAuthorityJson> { 031 032 private static final long serialVersionUID = 1L; 033 private static final Logger ourLog = LoggerFactory.getLogger(GrantedAuthorityJson.class); 034 035 @JsonProperty("permission") 036 @Schema( 037 description = 038 "The name of the permission. See [permissions](/docs/security/roles_and_permissions.html) for " 039 + "information on available permissions.", 040 accessMode = Schema.AccessMode.READ_ONLY) 041 private PermissionEnum myPermission; 042 043 @JsonProperty("argument") 044 @Schema( 045 description = 046 "The argument for this authority. Note that some permissions do not take an argument while " 047 + "others require an argument. Consult the [permission](/docs/security/roles_and_permissions.html) documentation for more information.", 048 accessMode = Schema.AccessMode.READ_ONLY) 049 private String myArgument; 050 051 @JsonIgnore 052 private transient Integer myHashCode; 053 054 /** 055 * Constructor 056 */ 057 public GrantedAuthorityJson() { 058 super(); 059 } 060 061 /** 062 * Constructor 063 */ 064 public GrantedAuthorityJson(PermissionEnum thePermission) { 065 this(thePermission, null); 066 } 067 068 /** 069 * Constructor 070 */ 071 public GrantedAuthorityJson(PermissionEnum thePermission, String theArgument) { 072 super(); 073 myPermission = thePermission; 074 myArgument = theArgument; 075 if (isNotBlank(theArgument)) { 076 if (!myPermission.isTakesArgument()) { 077 ourLog.warn("Permission " + thePermission + " does not take any argument"); 078 } 079 } else { 080 if (myPermission.isTakesArgument() && !myPermission.isArgumentOptional()) { 081 ourLog.warn("Permission " + thePermission + " requires an argument"); 082 } 083 } 084 } 085 086 @Override 087 public boolean equals(Object theObj) { 088 if (!(theObj instanceof GrantedAuthorityJson)) { 089 return false; 090 } 091 092 GrantedAuthorityJson obj = (GrantedAuthorityJson) theObj; 093 EqualsBuilder b = new EqualsBuilder(); 094 b.append(myPermission, obj.myPermission); 095 b.append(defaultString(myArgument, ""), defaultString(obj.myArgument, "")); 096 return b.isEquals(); 097 } 098 099 public String getArgument() { 100 return defaultString(myArgument, null); 101 } 102 103 @Override 104 public String getAuthority() { 105 return myPermission.name(); 106 } 107 108 public PermissionEnum getPermission() { 109 return myPermission; 110 } 111 112 @Override 113 public int hashCode() { 114 Integer retVal = myHashCode; 115 if (retVal == null) { 116 HashCodeBuilder b = new HashCodeBuilder(); 117 b.append(myPermission); 118 b.append(defaultString(myArgument, "")); 119 retVal = b.toHashCode(); 120 myHashCode = retVal; 121 } 122 return retVal; 123 } 124 125 @Override 126 public String toString() { 127 if (isBlank(myArgument)) { 128 return myPermission.name(); 129 } else { 130 return myPermission.name() + "/" + myArgument; 131 } 132 } 133 134 /** 135 * Create a copy of this authority with the same permission but a different argument 136 */ 137 public GrantedAuthorityJson withArgument(String theArgument) { 138 return new GrantedAuthorityJson(myPermission, theArgument); 139 } 140 141 @Override 142 public int compareTo(@Nonnull GrantedAuthorityJson theOther) { 143 return toString().compareTo(theOther.toString()); 144 } 145 146 /** 147 * @param theValue E.g. "ROLE_FHIR_CLIENT" or "FHIR_READ_ALL_IN_COMPARTMENT/Patient/123" 148 * @throws IllegalArgumentException If the permission is invalid 149 */ 150 public static GrantedAuthorityJson parse(String theValue) throws IllegalArgumentException { 151 String permName; 152 String argument; 153 int slashIdx = theValue.indexOf('/'); 154 if (slashIdx == -1) { 155 permName = theValue; 156 argument = null; 157 } else { 158 permName = theValue.substring(0, slashIdx); 159 argument = theValue.substring(slashIdx + 1); 160 } 161 162 PermissionEnum permission; 163 try { 164 permission = PermissionEnum.valueOf(permName); 165 } catch (Exception e) { 166 throw new IllegalArgumentException("Unknown permission: " + permName); 167 } 168 169 argument = defaultIfBlank(argument, null); 170 171 return new GrantedAuthorityJson(permission, argument); 172 } 173}