001package com.identityworksllc.iiq.common.access;
002
003import com.identityworksllc.iiq.common.CommonSecurityConfig;
004import com.identityworksllc.iiq.common.auth.DummyAuthContext;
005import com.identityworksllc.iiq.common.auth.DummyPluginResource;
006import sailpoint.api.SailPointContext;
007import sailpoint.object.Identity;
008import sailpoint.tools.GeneralException;
009import sailpoint.web.UserContext;
010
011import java.util.Map;
012
013/**
014 * Implements a fluent API for access checks.
015 *
016 * Use {@link AccessCheck#setup()} to begin one of these chains.
017 *
018 * @see AccessCheck#setup()
019 */
020public class FluentAccessCheck {
021    /**
022     * The mid-construction input object
023     */
024    private final AccessCheckInput input;
025
026    /**
027     * Constructs a new FluentAccessCheck object with an empty input config
028     */
029    public FluentAccessCheck() {
030        this.input = new AccessCheckInput();
031    }
032
033    /**
034     * Validates and executes the constructed {@link AccessCheck}, returning
035     * the response.
036     *
037     * @return The response from {@link AccessCheck#accessCheck(AccessCheckInput)}.
038     * @throws AccessCheckException if the validation or access check fails
039     * @see AccessCheck#accessCheck(AccessCheckInput) 
040     */
041    public AccessCheckResponse execute() throws AccessCheckException {
042        input.validate();
043        return AccessCheck.accessCheck(this.input);
044    }
045
046    /**
047     * Sets the security config for this access check
048     * @param config The security config
049     * @return This object, for chaining
050     * @throws GeneralException if parsing the Map into a {@link CommonSecurityConfig} fails
051     * @see CommonSecurityConfig#decode(Map) 
052     */
053    public FluentAccessCheck config(Map<String, Object> config) throws GeneralException {
054        input.setConfiguration(config);
055        return this;
056    }
057
058    /**
059     * Sets the security config for this access check
060     * @param config The security config
061     * @return This object, for chaining
062     */
063    public FluentAccessCheck config(CommonSecurityConfig config) {
064        input.setConfiguration(config);
065        return this;
066    }
067
068    /**
069     * Sets debug mode to true for this access check
070     * @return This object, for chaining
071     * @see AccessCheckInput#setDebug(boolean)
072     */
073    public FluentAccessCheck debug() {
074        input.setDebug(true);
075        return this;
076    }
077
078    /**
079     * Returns true if this access check passes for the current configuration
080     * @return True if this access check passes, false otherwise
081     * @throws AccessCheckException if the configuration is not valid
082     * @see AccessCheckResponse#isAllowed()
083     */
084    public boolean isAllowed() throws AccessCheckException {
085        return execute().isAllowed();
086    }
087
088    public FluentAccessCheck name(String name) {
089        input.setThingName(name);
090        return this;
091    }
092
093    public FluentAccessCheck state(Map<String, Object> state) {
094        input.setState(state);
095        return this;
096    }
097
098    public FluentAccessCheck state(String name, Object value) {
099        input.putState(name, value);
100        return this;
101    }
102
103    public FluentAccessCheck subject(SailPointContext ctx, Identity subject, String pluginName) {
104        input.setUserContext(new DummyPluginResource(ctx, subject, pluginName));
105        return this;
106    }
107
108    public FluentAccessCheck subject(SailPointContext ctx, Identity subject) {
109        input.setUserContext(new DummyAuthContext(ctx, subject.getName()));
110        return this;
111    }
112
113    public FluentAccessCheck subject(UserContext userContext) {
114        input.setUserContext(userContext);
115        return this;
116    }
117
118    public FluentAccessCheck target(String targetName) {
119        input.setTarget(targetName);
120        return this;
121    }
122
123    public FluentAccessCheck target(Identity target) {
124        input.setTarget(target);
125        return this;
126    }
127}