Log in only with a certain attribute value#

The AccessByAttribute procedure uses the appList attribute to decide whether a user can access the application. This procedure requires the appList attribute to be created as an array (Array of strings). Application identifiers should be used as the values of the elements of this array. As a result, access to an application will be granted if among the values of appList a given user has the identifier of this application. This procedure architecture allows you to assign it to several applications at once and control access to them using a single attribute.

public class AccessByAttribute implements Strategy {

    private final Logger logger = LoggerFactory.getLogger("com.identityblitz.idp.flow.dynamic");

    @Override public StrategyBeginState begin(final Context ctx) {
        if(ctx.claims("subjectId") != null){
            int appListIdx = 0;
            boolean hasAccess = false;
            while (appListIdx > -1) {
                String app = ctx.claims("appList.[" + appListIdx + "]");
                logger.debug("app [" + appListIdx + "] = " + app);
                if (app == null){ appListIdx = -1; }
                else if (app.equals(ctx.appId())) { appListIdx = -1; hasAccess = true; }
                else { appListIdx ++; logger.debug("AppList index = " + appListIdx); }
            }
            if(hasAccess)
                return StrategyState.ENOUGH();
            else
                return StrategyState.DENY;
        }
        else
            return StrategyState.MORE(new String[]{});
    }

    @Override public StrategyState next(final Context ctx) {
        int appListIdx = 0;
        boolean hasAccess = false;
        while (appListIdx > -1) {
            String app = ctx.claims("appList.[" + appListIdx + "]");
            logger.debug("app [" + appListIdx + "] = " + app);
            if (app == null){ appListIdx = -1; }
            else if (app.equals(ctx.appId())) { appListIdx = -1; hasAccess = true; }
            else { appListIdx ++; logger.debug("AppList index = " + appListIdx); }
        }
        if(!hasAccess)
            return StrategyState.DENY;
        Integer reqFactor = 0;
        if (ctx.user() != null) {
            reqFactor = ctx.user().requiredFactor();
        }
        if (reqFactor == 0)
            return StrategyState.ENOUGH();
        else {
            if (reqFactor == ctx.justCompletedFactor())
                return StrategyState.ENOUGH();
            else
                return StrategyState.MORE(new String[]{});
        }
    }
}

An example of a simplified version of the procedure is to grant a user access to an application provided his e-mail address is ivanov@company.ru:

@Override public StrategyBeginState begin(final Context ctx) {
  if(ctx.claims("subjectId") != null){
    if("ivanov@company.ru".equals(ctx.claims("email")))
      return StrategyState.ENOUGH();
    else
      return StrategyState.DENY;
  }
  else
    return StrategyState.MORE(new String[]{});
}

@Override public StrategyState next(final Context ctx) {
  if(!"ivanov@company.ru".equals(ctx.claims("email")))
    return StrategyState.DENY;
  Integer reqFactor = (ctx.user() == null) ? null : ctx.user().requiredFactor();
  if(reqFactor == null)
    return StrategyState.ENOUGH();
  else {
    if(reqFactor == ctx.justCompletedFactor())
      return StrategyState.ENOUGH();
    else
      return StrategyState.MORE(new String[]{});
  }
}