All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.novartis.opensource.yada.YADASecuritySpec Maven / Gradle / Ivy

The newest version!
/**
 * 
 */
package com.novartis.opensource.yada;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * @author dvaron
 * @since 9.0.0
 */
public class YADASecuritySpec extends HashMap {
  
  /**
   * 
   */
  private static Logger l = Logger.getLogger(YADASecuritySpec.class); 
  
  /**
   * 
   */
  private static final long serialVersionUID = 1L;
  
  /**
   * 
   */
  public final static String KEY_AUTH_PATH_RX = "auth.path.rx";
  /**
   * 
   */
  public final static String KEY_POLICY = "policy";
  /**
   * 
   */
  public final static String KEY_TYPE = "type";
  /**
   * 
   */
  public final static String KEY_QUALIFIER = "qualifier";
  /**
   * 
   */
  public final static String KEY_PREDICATE = "predicate";
  /**
   * 
   */
  public final static String KEY_PROTECTOR = "protector";
  /**
   * 
   */
  public final static String KEY_COLUMNS = "columns";
  /**
   * 
   */
  public final static String KEY_INDEXES = "indexes";
  /**
   * 
   */
  public final static String KEY_INDICES = "indices";
  /**
   * 
   */
  public final static String KEY_TOKEN_VALIDATOR = "token.validator";
  /**
   * 
   */
  public final static String POLICY_EXECUTION = "E";
  /**
   * 
   */
  public final static String POLICY_CONTENT = "C";
  /**
   * 
   */
  public final static String POLICY_AUTHORIZATION  = "A";
  /**
   * 
   */
  public final static String TYPE_ALLOWLIST = "whitelist";
  /**
   * 
   */
  public final static String TYPE_DENYLIST = "blacklist";
  /**
   * Constant equal to {@value}
   * 
   * @since 9.0.0 (moved from {@link com.novartis.opensource.yada.plugin.Gatekeeper}
   */
  public static final String RX_COL_INJECTION = "(?:([a-zA-Z0-9_]+):)?(get[A-Z][a-zA-Z0-9_]+\\(([A-Za-z0-9_]*)\\))";

  
  /**
   * Constant equal to {@value}
   * 
   * @since 9.0.0 (moved from {@link com.novartis.opensource.yada.plugin.Gatekeeper}
   */
  public static final String RX_IDX_INJECTION = "(?:([0-9]+):)?(get[A-Z][a-zA-Z0-9_]+\\(([A-Za-z0-9_]*)\\))";
  
  
  /**
   * Constant equal to {@value}
   * @since 9.0.0
   */
  public final static String RX_COL = "^"+RX_COL_INJECTION+"|[A-Za-z0-9_]+$";
  
  /**
   * Constant equal to {@value}
   * @since 9.0.0
   */
  public final static String RX_IDX = "^"+RX_IDX_INJECTION+"|[\\d]+$";
  
  /**
   * 
   */
  public final static List keyFields = getKeyFields(); 
  

  
  /**
   * 
   */
  public YADASecuritySpec() {}
  
  /**
   * @param spec a {@link JSONObject} containing the specification to be instantiated
   * @throws YADAQueryConfigurationException when the spec is invalid
   */
  public YADASecuritySpec(JSONObject spec) throws YADAQueryConfigurationException
  {    
    for(String key : JSONObject.getNames(spec))
    {      
      // only add key to spec if it matches a private "KEY" field
      if(keyFields.contains(key))
      {
        try
        {
          this.put(key, spec.get(key));
        }
        catch(JSONException e)
        {
          String msg = String.format("[%s] key caused an error", key);
          throw new YADAQueryConfigurationException(msg);
        }        
      }
      else
      {
        String msg = String.format("[%s] is not permitted in YADASecuritySpec", key);
        throw new YADAQueryConfigurationException(msg);
      }
    }
  }
  
  /**
   * @return all the keys in this spec which correspond to constants having the {@code KEY} prefix 
   */
  public final static List getKeyFields() 
  {
    List names = new ArrayList();
    for(Field field : YADASecuritySpec.class.getDeclaredFields())
    {
      if(field.getName().startsWith("KEY"))
      {
        try
        {
          names.add(field.get(null).toString());
          l.debug("YADASecuritySpec KEY field: "+field.get(null).toString());
        }
        catch (IllegalArgumentException e)
        {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        
      }
    }
    return names;
  }
  
  /**
   * @param value the classname of the {@link com.novartis.opensource.yada.plugin.TokenValidator}
   * @throws YADAQueryConfigurationException when {@code value} is {@code null}
   */
  public void setTokenValidator(String value) throws YADAQueryConfigurationException 
  {
    if(null == value)
      throw new YADAQueryConfigurationException("Token validator value must be non-null");
    this.put(KEY_TOKEN_VALIDATOR, value);
  }
  
  /**
   * @return the value of the {@link #KEY_TOKEN_VALIDATOR} entry
   */ 
  public String getTokenValidator()
  {
    return (String) this.get(KEY_TOKEN_VALIDATOR);
  }
  
  /**
   * @param value a regular expression for validating request urls
   * @throws YADAQueryConfigurationException when {@code value} is {@code null}
   */
  public void setURLSpec(String value) throws YADAQueryConfigurationException 
  {
    if(null == value)
      throw new YADAQueryConfigurationException("Authorized URL path expression must be non-null");
    this.put(KEY_AUTH_PATH_RX, value);
  }
  
  /**
   * @return the value of the {@link #KEY_AUTH_PATH_RX} entry
   */
  public String getURLSpec() 
  {
    return (String) this.get(KEY_AUTH_PATH_RX);
  }
  
  /**
   * @param type {@link #TYPE_ALLOWLIST} or {@link #TYPE_DENYLIST}
   * @param protector the name of the protector query
   * @param columnsOrIndexes a {@link List} of columns or indices from the query config
   * @throws YADAQueryConfigurationException if any parameter is {@code null}
   */
  @SuppressWarnings("unchecked")
  public void setExecutionPolicy(String type, String protector, List columnsOrIndexes) throws YADAQueryConfigurationException 
  {
    List list = (List) columnsOrIndexes;
    boolean isColumns = (null != list && list.stream().filter(c -> c.matches(RX_COL)).collect(Collectors.toList()).size() > 0);
    if(null == type || null == protector 
        || (!isColumns && list.stream().filter(c -> c.matches(RX_IDX)).collect(Collectors.toList()).size() == 0))
      throw new YADAQueryConfigurationException("policy, type, protector, and columns, indexes, or indices must be non-null");
//    this.put(KEY_POLICY, POLICY_EXECUTION);
    this.put(KEY_TYPE, type);
    this.put(KEY_PROTECTOR, protector);
    if(isColumns)
    {
      this.put(KEY_COLUMNS, columnsOrIndexes);
    }
    else
    {
      this.put(KEY_INDEXES, columnsOrIndexes);
    }
  }
  /**
   * @return {@code true} if {@link #KEY_PROTECTOR} is present in the specification
   */
  public boolean hasExecutionPolicy()
  {
    return (this.get(KEY_PROTECTOR) != null);
  }
  
  /**
   * @return a {@link Map} containing the {@link #POLICY_EXECUTION} specs
   */
  public Map getExecutionPolicy()  
  {
    Map policy = null;
//    if(this.get(KEY_POLICY) == POLICY_EXECUTION)
    if(hasExecutionPolicy())
    {
      policy = new HashMap();
      policy.put(KEY_TYPE, (String) this.get(KEY_TYPE));
      policy.put(KEY_PROTECTOR, (String) this.get(KEY_PROTECTOR));
      if(this.get(KEY_COLUMNS) != null)
        policy.put(KEY_COLUMNS, getValueAsList(this.get(KEY_COLUMNS)));
      else if(this.get(KEY_INDEXES) != null)
        policy.put(KEY_INDEXES, getValueAsList(this.get(KEY_INDEXES)));
      else
        policy.put(KEY_INDEXES, getValueAsList(this.get(KEY_INDICES)));
      
    }
    return policy;
  }
  
  /**
   * @param type {@link #TYPE_ALLOWLIST} or {@link #TYPE_DENYLIST}
   * @param qualifier the grants associated to the query
   * @throws YADAQueryConfigurationException if any parameter is {@code null}
   */
  @SuppressWarnings("unchecked")
  public void setAuthorizationPolicy(String type, List qualifier) throws YADAQueryConfigurationException 
  {
    List list = (List) qualifier;
    if(null == type || null == qualifier || null == list || list.size() == 0)
      throw new YADAQueryConfigurationException("type and qualifier must be non-null");
//    this.put(KEY_POLICY, POLICY_AUTHORIZATION);
    this.put(KEY_TYPE, type);
    this.put(KEY_QUALIFIER, qualifier);    
  }
  
  /**
   * @return {@code true} if {@link #KEY_QUALIFIER} is present in the specification
   */
  public boolean hasAuthorizationPolicy()
  {
    return (this.get(KEY_QUALIFIER) != null);
  }
  
  /**
   * @return a {@link Map} containing the {@link #POLICY_AUTHORIZATION} specs
   */
  public Map getAuthorizationPolicy()  
  {
    Map policy = null;
    if(hasAuthorizationPolicy())
    {
      policy = new HashMap();
      policy.put(KEY_TYPE, (String) this.get(KEY_TYPE));
      policy.put(KEY_QUALIFIER, getValueAsList(this.get(KEY_QUALIFIER)));
    }
    return policy;
  }
  
  /**
   * @param type {@link #TYPE_ALLOWLIST} or {@link #TYPE_DENYLIST}
   * @param predicate the dynamic sql config associated to the query
   * @throws YADAQueryConfigurationException if any parameter is {@code null}
   */
  public void setContentPolicy(String type, String predicate) throws YADAQueryConfigurationException 
  {
    if(null == predicate)
      throw new YADAQueryConfigurationException("policy, type, protector, and columns, indexes, or indices must be non-null");
//    this.put(KEY_POLICY, POLICY_CONTENT);
    this.put(KEY_TYPE, type);
    this.put(KEY_PREDICATE, predicate);    
  }
  
  /**
   * @return {@code true} if {@link #KEY_PREDICATE} is present in the specification
   */
  public boolean hasContentPolicy()
  {
    return (this.get(KEY_PREDICATE) != null);
  }
  
  /**
   * @return a {@link Map} containing the {@link #POLICY_CONTENT} specs
   */
  public Map getContentPolicy()  
  {
    Map policy = null;
//    if(this.get(KEY_POLICY) == POLICY_CONTENT)
    if(hasContentPolicy())
    {
      policy = new HashMap();
      policy.put(KEY_TYPE, (String) this.get(KEY_TYPE));
      policy.put(KEY_PREDICATE, (String) this.get(KEY_PREDICATE));
    }
    return policy;
  }
  
  /**
   * @param value a {@link JSONArray} mapped to {@link #KEY_QUALIFIER}, {@link #KEY_COLUMNS}, {@link #KEY_INDEXES}, or {@link #KEY_INDICES}
   * @return a {@link List} containing the entries associated to {@code value}
   */
  private List getValueAsList(Object value) {
    if(null == value)
      return null;
    return Arrays.asList(((JSONArray)value).toString().split(","));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy