001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.runtime.api.login;
023
024import java.util.ArrayList;
025import java.util.List;
026
027import javax.security.auth.Subject;
028import javax.security.auth.callback.CallbackHandler;
029import javax.security.auth.login.AppConfigurationEntry;
030import javax.security.auth.login.LoginContext;
031import javax.security.auth.login.LoginException;
032import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
033
034import org.nuxeo.common.xmap.annotation.XNode;
035import org.nuxeo.common.xmap.annotation.XNodeList;
036import org.nuxeo.common.xmap.annotation.XObject;
037import org.nuxeo.runtime.api.LoginModuleWrapper;
038
039/**
040 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
041 */
042@XObject("domain")
043public class SecurityDomain {
044
045    @XNode("@name")
046    private String name;
047
048    private AppConfigurationEntry[] entries;
049
050    public SecurityDomain() {
051    }
052
053    public SecurityDomain(String name) {
054        this.name = name;
055    }
056
057    public SecurityDomain(String name, AppConfigurationEntry[] entries) {
058        this.name = name;
059        this.entries = entries;
060    }
061
062    public String getName() {
063        return name;
064    }
065
066    public AppConfigurationEntry[] getAppConfigurationEntries() {
067        return entries;
068    }
069
070    public void setAppConfigurationEntries(AppConfigurationEntry[] entries) {
071        this.entries = entries;
072    }
073
074    @XNodeList(value = "login-module", type = ArrayList.class, componentType = LoginModuleDescriptor.class)
075    public void setEntries(List<LoginModuleDescriptor> descriptors) {
076        entries = new AppConfigurationEntry[descriptors.size()];
077        int i = 0;
078        for (LoginModuleDescriptor descriptor : descriptors) {
079            LoginModuleControlFlag flag = null;
080            if (descriptor.flag == null) {
081                flag = LoginModuleControlFlag.OPTIONAL;
082            } else if ("optional".equals(descriptor.flag)) {
083                flag = LoginModuleControlFlag.OPTIONAL;
084            } else if ("sufficient".equals(descriptor.flag)) {
085                flag = LoginModuleControlFlag.SUFFICIENT;
086            } else if ("required".equals(descriptor.flag)) {
087                flag = LoginModuleControlFlag.REQUIRED;
088            } else if ("requisite".equals(descriptor.flag)) {
089                flag = LoginModuleControlFlag.REQUISITE;
090            }
091            descriptor.options.put(LoginModuleWrapper.DELEGATE_CLASS_KEY, descriptor.code);
092            entries[i++] = new AppConfigurationEntry(LoginModuleWrapper.class.getName(), flag, descriptor.options);
093        }
094    }
095
096    public LoginContext login(Subject subject) throws LoginException {
097        LoginContext ctx = new LoginContext(name, subject);
098        ctx.login();
099        return ctx;
100    }
101
102    public LoginContext login(CallbackHandler handler) throws LoginException {
103        LoginContext ctx = new LoginContext(name, handler);
104        ctx.login();
105        return ctx;
106    }
107
108    public LoginContext login(Subject subject, CallbackHandler handler) throws LoginException {
109        LoginContext ctx = new LoginContext(name, subject, handler);
110        ctx.login();
111        return ctx;
112    }
113
114    public LoginContext login(String username, Object credentials) throws LoginException {
115        CredentialsCallbackHandler handler = new CredentialsCallbackHandler(username, credentials);
116        LoginContext ctx = new LoginContext(name, handler);
117        ctx.login();
118        return ctx;
119    }
120
121    public static String controlFlagToString(LoginModuleControlFlag flag) {
122        if (flag == LoginModuleControlFlag.OPTIONAL) {
123            return "optional";
124        } else if (flag == LoginModuleControlFlag.REQUIRED) {
125            return "required";
126        } else if (flag == LoginModuleControlFlag.REQUISITE) {
127            return "requisite";
128        } else if (flag == LoginModuleControlFlag.SUFFICIENT) {
129            return "sufficient";
130        }
131        throw new IllegalArgumentException("Not a supported LoginModuleControlFlag: " + flag);
132    }
133
134    public static LoginModuleControlFlag controlFlagFromString(String flag) {
135        if (flag == null) {
136            return LoginModuleControlFlag.OPTIONAL;
137        } else if ("optional".equals(flag)) {
138            return LoginModuleControlFlag.OPTIONAL;
139        } else if ("sufficient".equals(flag)) {
140            return LoginModuleControlFlag.SUFFICIENT;
141        } else if ("required".equals(flag)) {
142            return LoginModuleControlFlag.REQUIRED;
143        } else if ("requisite".equals(flag)) {
144            return LoginModuleControlFlag.REQUISITE;
145        }
146        throw new IllegalArgumentException("Not a supported LoginModuleControlFlag: " + flag);
147    }
148
149}