001/*
002 * (C) Copyright 2006-2013 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 *     Nelson Silva <nelson.silva@inevo.pt> - initial API and implementation
018 *     Nuxeo
019 */
020
021package org.nuxeo.ecm.platform.oauth2.openid;
022
023import org.apache.commons.lang3.ArrayUtils;
024import org.apache.commons.lang3.StringUtils;
025import org.nuxeo.common.xmap.annotation.XNode;
026import org.nuxeo.common.xmap.annotation.XNodeList;
027import org.nuxeo.common.xmap.annotation.XObject;
028import org.nuxeo.ecm.platform.oauth2.openid.auth.DefaultOpenIDUserInfo;
029import org.nuxeo.ecm.platform.oauth2.openid.auth.EmailBasedUserResolver;
030import org.nuxeo.ecm.platform.oauth2.openid.auth.OpenIDUserInfo;
031import org.nuxeo.ecm.platform.oauth2.openid.auth.UserResolver;
032import org.nuxeo.runtime.model.Descriptor;
033
034@XObject("provider")
035public class OpenIDConnectProviderDescriptor implements Descriptor {
036
037    public static final String DEFAULT_ACCESS_TOKEN_KEY = "access_token";
038
039    public static final Class<? extends UserResolver> DEFAULT_USER_RESOLVER_CLASS = EmailBasedUserResolver.class;
040
041    public static final Class<? extends RedirectUriResolver> DEFAULT_REDIRECT_URI_RESOLVER_CLASS = RedirectUriResolverHelper.class;
042
043    public static final Class<? extends OpenIDUserInfo> DEFAULT_USER_INFO_CLASS = DefaultOpenIDUserInfo.class;
044
045    /**
046     * @since 11.1
047     */
048    public static final String URL_AUTHENTICATION_METHOD = "url";
049
050    /**
051     * @since 11.1
052     */
053    public static final String BEARER_AUTHENTICATION_METHOD = "bearer";
054
055    /**
056     * @since 11.1
057     */
058    public static final String DEFAULT_AUTHENTICATION_METHOD = URL_AUTHENTICATION_METHOD;
059
060    @XNode("@enabled")
061    protected boolean enabled = true;
062
063    @XNode("name")
064    protected String name;
065
066    @XNode("tokenServerURL")
067    protected String tokenServerURL;
068
069    @XNode("authorizationServerURL")
070    protected String authorizationServerURL;
071
072    @XNode("userInfoURL")
073    protected String userInfoURL;
074
075    @XNode("accessTokenKey")
076    protected String accessTokenKey = DEFAULT_ACCESS_TOKEN_KEY;
077
078    @XNode("clientId")
079    protected String clientId;
080
081    @XNode("clientSecret")
082    protected String clientSecret;
083
084    @XNodeList(value = "scope", type = String[].class, componentType = String.class)
085    protected String[] scopes;
086
087    @XNode("icon")
088    protected String icon;
089
090    @XNode("label")
091    protected String label;
092
093    @XNode("description")
094    protected String description;
095
096    @XNode("userResolverClass")
097    protected Class<? extends UserResolver> userResolverClass;
098
099    @XNode("userMapperName")
100    protected String userMapper;
101
102    @XNode("redirectUriResolver")
103    protected Class<? extends RedirectUriResolver> redirectUriResolver = DEFAULT_REDIRECT_URI_RESOLVER_CLASS;
104
105    @XNode("userInfoClass")
106    protected Class<? extends OpenIDUserInfo> userInfoClass = DEFAULT_USER_INFO_CLASS;
107
108    /**
109     * @since 11.1
110     */
111    @XNode("authenticationMethod")
112    protected String authenticationMethod = DEFAULT_AUTHENTICATION_METHOD;
113
114    @Override
115    public String getId() {
116        return getName();
117    }
118
119    public String getName() {
120        return name;
121    }
122
123    public String getTokenServerURL() {
124        return tokenServerURL;
125    }
126
127    public String getAuthorizationServerURL() {
128        return authorizationServerURL;
129    }
130
131    public String getClientId() {
132        return clientId;
133    }
134
135    public String getClientSecret() {
136        return clientSecret;
137    }
138
139    public String[] getScopes() {
140        return scopes;
141    }
142
143    public String getUserInfoURL() {
144        return userInfoURL;
145    }
146
147    public String getAccessTokenKey() {
148        return accessTokenKey;
149    }
150
151    public String getIcon() {
152        return icon;
153    }
154
155    public boolean isEnabled() {
156        return enabled;
157    }
158
159    public void setEnabled(boolean enabled) {
160        this.enabled = enabled;
161    }
162
163    public String getLabel() {
164        return label;
165    }
166
167    public String getDescription() {
168        return description;
169    }
170
171    public String getUserMapper() {
172        return userMapper;
173    }
174
175    public Class<? extends UserResolver> getUserResolverClass() {
176        if (userResolverClass == null && userMapper == null) {
177            return DEFAULT_USER_RESOLVER_CLASS;
178        }
179        return userResolverClass;
180    }
181
182    public Class<? extends RedirectUriResolver> getRedirectUriResolver() {
183        return redirectUriResolver;
184    }
185
186    public Class<? extends OpenIDUserInfo> getUserInfoClass() {
187        return userInfoClass;
188    }
189
190    /**
191     * @since 11.1
192     */
193    public String getAuthenticationMethod() {
194        return authenticationMethod;
195    }
196
197    @Override
198    public Descriptor merge(Descriptor o) {
199        OpenIDConnectProviderDescriptor other = (OpenIDConnectProviderDescriptor) o;
200        OpenIDConnectProviderDescriptor merged = new OpenIDConnectProviderDescriptor();
201        merged.name = name;
202        merged.enabled = other.enabled;
203        merged.authorizationServerURL = StringUtils.isNotBlank(other.authorizationServerURL)
204                ? other.authorizationServerURL
205                : authorizationServerURL;
206        merged.clientId = StringUtils.isNotBlank(other.clientId) ? other.clientId : clientId;
207        merged.clientSecret = StringUtils.isNotBlank(other.clientSecret) ? other.clientSecret : clientSecret;
208        merged.icon = StringUtils.isNotBlank(other.icon) ? other.icon : icon;
209        merged.scopes = ArrayUtils.isNotEmpty(other.scopes) ? other.scopes : scopes;
210        merged.tokenServerURL = StringUtils.isNotBlank(other.tokenServerURL) ? other.tokenServerURL : tokenServerURL;
211        merged.userInfoURL = StringUtils.isNotBlank(other.userInfoURL) ? other.userInfoURL : userInfoURL;
212        merged.label = StringUtils.isNotBlank(other.label) ? other.label : label;
213        merged.description = StringUtils.isNotBlank(other.description) ? other.description : description;
214        merged.accessTokenKey = !other.accessTokenKey.equals(DEFAULT_ACCESS_TOKEN_KEY) ? other.accessTokenKey
215                : accessTokenKey;
216        merged.userInfoClass = other.userInfoClass != DEFAULT_USER_INFO_CLASS ? other.userInfoClass : userInfoClass;
217        merged.redirectUriResolver = other.redirectUriResolver != DEFAULT_REDIRECT_URI_RESOLVER_CLASS
218                ? other.redirectUriResolver
219                : redirectUriResolver;
220        Class<? extends UserResolver> otherUserResolverClass = other.getUserResolverClass();
221        merged.userResolverClass = otherUserResolverClass != DEFAULT_USER_RESOLVER_CLASS ? otherUserResolverClass : userResolverClass;
222        merged.userMapper = StringUtils.isNotBlank(other.userMapper) ? other.userMapper : userMapper;
223        merged.authenticationMethod = !other.authenticationMethod.equals(DEFAULT_AUTHENTICATION_METHOD)
224                ? other.authenticationMethod
225                : authenticationMethod;
226        return merged;
227    }
228}