001/* 002 * (C) Copyright 2006-2013 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nelson Silva 016 */ 017 018package org.nuxeo.ecm.platform.oauth2.openid; 019 020import java.util.ArrayList; 021import java.util.Arrays; 022import java.util.Collection; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import org.apache.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029import org.nuxeo.ecm.platform.oauth2.providers.OAuth2ServiceProvider; 030import org.nuxeo.ecm.platform.oauth2.providers.OAuth2ServiceProviderRegistry; 031import org.nuxeo.ecm.platform.ui.web.auth.LoginScreenHelper; 032import org.nuxeo.runtime.api.Framework; 033import org.nuxeo.runtime.model.ComponentContext; 034import org.nuxeo.runtime.model.ComponentInstance; 035import org.nuxeo.runtime.model.DefaultComponent; 036 037/** 038 * @author Nelson Silva <nelson.silva@inevo.pt> 039 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> 040 * @since 5.7 041 */ 042public class OpenIDConnectProviderRegistryImpl extends DefaultComponent implements OpenIDConnectProviderRegistry { 043 044 protected static final Log log = LogFactory.getLog(OpenIDConnectProviderRegistryImpl.class); 045 046 public static final String PROVIDER_EP = "providers"; 047 048 protected Map<String, OpenIDConnectProvider> providers = new HashMap<String, OpenIDConnectProvider>(); 049 050 protected OpenIDProviderFragmentRegistry pendingProviders = new OpenIDProviderFragmentRegistry(); 051 052 protected OAuth2ServiceProviderRegistry getOAuth2ServiceProviderRegistry() { 053 return Framework.getLocalService(OAuth2ServiceProviderRegistry.class); 054 } 055 056 @Override 057 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 058 if (PROVIDER_EP.equals(extensionPoint)) { 059 OpenIDConnectProviderDescriptor provider = (OpenIDConnectProviderDescriptor) contribution; 060 061 if (provider.getClientId() == null || provider.getClientSecret() == null) { 062 log.info("OpenId provider for " + provider.getName() 063 + " is disabled because clientId and/or clientSecret are empty (component id = " 064 + contributor.getName().toString() + ")"); 065 provider.setEnabled(false); 066 } 067 log.info("OpenId provider for " + provider.getName() + " will be registred at application startup"); 068 // delay registration because data sources may not be available 069 // at this point 070 pendingProviders.addContribution(provider); 071 } 072 } 073 074 @Override 075 public Collection<OpenIDConnectProvider> getProviders() { 076 return providers.values(); 077 } 078 079 @Override 080 public Collection<OpenIDConnectProvider> getEnabledProviders() { 081 List<OpenIDConnectProvider> result = new ArrayList<OpenIDConnectProvider>(); 082 for (OpenIDConnectProvider provider : getProviders()) { 083 if (provider.isEnabled()) { 084 result.add(provider); 085 } 086 } 087 return result; 088 } 089 090 @Override 091 public OpenIDConnectProvider getProvider(String name) { 092 return providers.get(name); 093 } 094 095 protected void registerPendingProviders() { 096 for (OpenIDConnectProviderDescriptor provider : pendingProviders.getContribs()) { 097 registerOpenIdProvider(provider); 098 } 099 } 100 101 protected void registerOpenIdProvider(OpenIDConnectProviderDescriptor provider) { 102 103 OAuth2ServiceProviderRegistry oauth2ProviderRegistry = getOAuth2ServiceProviderRegistry(); 104 RedirectUriResolver redirectUriResolver; 105 try { 106 redirectUriResolver = provider.getRedirectUriResolver().newInstance(); 107 } catch (ReflectiveOperationException e) { 108 throw new RuntimeException(e); 109 } 110 111 if (oauth2ProviderRegistry != null) { 112 113 OAuth2ServiceProvider oauth2Provider = oauth2ProviderRegistry.getProvider(provider.getName()); 114 115 if (oauth2Provider == null) { 116 oauth2Provider = oauth2ProviderRegistry.addProvider(provider.getName(), provider.getDescription(), 117 provider.getTokenServerURL(), provider.getAuthorizationServerURL(), provider.getClientId(), 118 provider.getClientSecret(), Arrays.asList(provider.getScopes())); 119 } else { 120 log.warn("Provider " + provider.getName() 121 + " is already in the Database, XML contribution won't overwrite it"); 122 } 123 providers.put(provider.getName(), new OpenIDConnectProvider(oauth2Provider, provider.getAccessTokenKey(), 124 provider.getUserInfoURL(), provider.getUserInfoClass(), provider.getIcon(), provider.isEnabled(), 125 redirectUriResolver, provider.getUserResolverClass(), provider.getUserMapper())); 126 127 // contribute icon and link to the Login Screen 128 LoginScreenHelper.registerLoginProvider(provider.getName(), provider.getIcon(), provider.getUserInfoURL(), 129 provider.getLabel(), provider.getDescription(), providers.get(provider.getName())); 130 131 } else { 132 if (Framework.isTestModeSet()) { 133 providers.put(provider.getName(), 134 new OpenIDConnectProvider(null, provider.getAccessTokenKey(), provider.getUserInfoURL(), 135 provider.getUserInfoClass(), provider.getIcon(), provider.isEnabled(), 136 redirectUriResolver, provider.getUserResolverClass(),provider.getUserMapper())); 137 } else { 138 log.error("Can not register OAuth Provider since OAuth Registry is not available"); 139 } 140 } 141 142 } 143 144 @Override 145 public void applicationStarted(ComponentContext context) { 146 super.applicationStarted(context); 147 registerPendingProviders(); 148 } 149 150}