package org.ovirt.engine.core.sso.search; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; import org.ovirt.engine.api.extensions.ExtMap; import org.ovirt.engine.api.extensions.aaa.Authz; import org.ovirt.engine.core.extensions.mgr.ExtensionProxy; import org.ovirt.engine.core.sso.utils.AuthenticationUtils; import org.ovirt.engine.core.sso.utils.JsonExtMapMixIn; import org.ovirt.engine.core.sso.utils.SsoConstants; import org.ovirt.engine.core.sso.utils.SsoContext; import org.ovirt.engine.core.sso.utils.SsoUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public enum DirectorySearch { GetAvailableNameSpaces(SsoConstants.AVAILABLE_NAMESPACES_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return AuthenticationUtils.getAvailableNamesSpaces(ssoContext.getSsoExtensionsManager()); } }, GetDomainList(SsoConstants.DOMAIN_LIST_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return ssoContext.getSsoExtensionsManager().getExtensionsByService( Authz.class.getName()).stream() .map(AuthzUtils::getName) .collect(Collectors.toList()); } }, GetSessionStatuses(SsoConstants.SESSION_STATUES_QUERY, true) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return ((Set<String>) readParams(request).get(SsoConstants.HTTP_PARAM_TOKENS)).stream() .filter(StringUtils::isNotEmpty) .collect(Collectors.toMap(token -> token, token -> ssoContext.getSsoSession(token) != null)); } }, FetchPrincipalRecord(SsoConstants.FETCH_PRINCIPAL_RECORD_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { Map<String, Object> params = readParams(request); return Collections.singletonList(AuthzUtils.fetchPrincipalRecord( ssoContext.getSsoExtensionsManager().getExtensionByName( (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)), (String) params.get(SsoConstants.HTTP_PARAM_PRINCIPAL), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING_RECURSIVE))); } }, FindPrincipalById(SsoConstants.FIND_PRINCIPAL_BY_ID_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return getPrincipalById(ssoContext, readParams(request)); } }, FindPrincipalsByIds(SsoConstants.FIND_PRINCIPALS_BY_IDS_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return getPrincipalsByIds(ssoContext, readParams(request)); } }, FindLoginOnBehalfPrincipalById(SsoConstants.FIND_LOGIN_ON_BEHALF_PRINCIPAL_BY_ID_QUERY, true) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return getPrincipalsByIds(ssoContext, readParams(request)); } }, FindDirectoryGroupById(SsoConstants.FIND_DIRECTORY_GROUP_BY_ID_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return getDirectoryGroupById(ssoContext, readParams(request)); } }, ProfileList(SsoConstants.PROFILE_LIST_QUERY, true) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return getProfileList(ssoContext); } }, SearchUsers(SsoConstants.SEARCH_USERS_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return searchDirectoryUsers(ssoContext, readParams(request)); } }, SearchGroups(SsoConstants.SEARCH_GROUPS_QUERY, false) { public Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception { return searchDirectoryGroups(ssoContext, readParams(request)); } }; private static Map<String, Object> readParams(HttpServletRequest request) throws Exception { return initMapper().readValue( SsoUtils.getRequestParameter(request, SsoConstants.HTTP_PARAM_PARAMS), HashMap.class); } private static ObjectMapper initMapper() { ObjectMapper mapper = new ObjectMapper() .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false) .enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE); mapper.getDeserializationConfig().addMixInAnnotations(ExtMap.class, JsonExtMapMixIn.class); return mapper; } public static final Logger log = LoggerFactory.getLogger(DirectorySearch.class); private String name; private boolean isPublicQuery; DirectorySearch(String name, boolean isPublicQuery) { this.name = name; this.isPublicQuery = isPublicQuery; } public Object executeQuery(SsoContext ssoContext, HttpServletRequest request) throws Exception { return execute(ssoContext, request); } public abstract Object execute(SsoContext ssoContext, HttpServletRequest request) throws Exception; public String getName() { return name; } public boolean isPublicQuery() { return isPublicQuery; } private static List<ExtMap> searchDirectoryGroups(SsoContext ssoContext, Map<String, Object> params) { log.debug("Entered searchDirectoryGroups"); String authzName = (String) params.get("authz"); String query = (String) params.get("query"); ExtensionProxy authz = AuthenticationUtils.getExtensionProfileByAuthzName(ssoContext, authzName).getAuthz(); List<ExtMap> results = new ArrayList<>(); getNamespaces(ssoContext, (String) params.get("namespace"), authzName). forEach(namespace -> results.addAll(DirectoryUtils.findDirectoryGroupsByQuery(authz, namespace, query))); log.debug("DirectoryUtils.findDirectoryGroupsByQuery returned {} groups in authz {} for query {}", results.size(), authzName, query); return results; } private static List<ExtMap> getPrincipalById(SsoContext ssoContext, Map<String, Object> params) { List<ExtMap> users = new ArrayList<>(); final ExtensionProxy extension = ssoContext.getSsoExtensionsManager().getExtensionByName( (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)); String searchNamespace = (String) params.get(SsoConstants.HTTP_PARAM_NAMESPACE); for (String namespace : StringUtils.isEmpty(searchNamespace) ? getNamespaces(ssoContext, (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)) : Collections.singletonList(searchNamespace)) { users.addAll(AuthzUtils.findPrincipalsByIds( extension, namespace, Collections.singletonList((String) params.get(SsoConstants.HTTP_PARAM_ID)), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING_RECURSIVE))); } return users; } private static List<ExtMap> getDirectoryGroupById(SsoContext ssoContext, Map<String, Object> params) { List<ExtMap> groups = new ArrayList<>(); final ExtensionProxy extension = ssoContext.getSsoExtensionsManager().getExtensionByName( (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)); String searchNamespace = (String) params.get(SsoConstants.HTTP_PARAM_NAMESPACE); for (String namespace : StringUtils.isEmpty(searchNamespace) ? getNamespaces(ssoContext, (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)) : Collections.singletonList(searchNamespace)) { groups.addAll(AuthzUtils.findGroupRecordsByIds( extension, namespace, Collections.singletonList((String) params.get(SsoConstants.HTTP_PARAM_ID)), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING_RECURSIVE))); } return groups; } private static List<ExtMap> getPrincipalsByIds(SsoContext ssoContext, Map<String, Object> params) { final ExtensionProxy extension = ssoContext.getSsoExtensionsManager().getExtensionByName( (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)); List<ExtMap> results = new ArrayList<>(); getNamespaces(ssoContext, (String) params.get(SsoConstants.HTTP_PARAM_NAMESPACE), (String) params.get(SsoConstants.HTTP_PARAM_DOMAIN)). forEach(namespace -> results.addAll(AuthzUtils.findPrincipalsByIds( extension, namespace, (Collection<String>) params.get(SsoConstants.HTTP_PARAM_IDS), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING), (boolean) params.get(SsoConstants.HTTP_PARAM_GROUPS_RESOLVING_RECURSIVE)))); return results; } private static List<Map<String, Object>> getProfileList(SsoContext ssoContext) { return AuthenticationUtils.getProfileList(ssoContext.getSsoExtensionsManager()); } private static List<ExtMap> searchDirectoryUsers(SsoContext ssoContext, Map<String, Object> params) { log.debug("Entered searchDirectoryUsers"); String authzName = (String) params.get("authz"); String query = (String) params.get("query"); ExtensionProxy authz = AuthenticationUtils.getExtensionProfileByAuthzName(ssoContext, authzName).getAuthz(); List<ExtMap> results = new ArrayList<>(); getNamespaces(ssoContext, (String) params.get("namespace"), authzName). forEach(namespace -> results.addAll( DirectoryUtils.findDirectoryUsersByQuery(authz, namespace, query))); log.debug("DirectoryUtils.findDirectoryUsersByQuery returned {} users in authz {} for query {}", results.size(), authzName, query); return results; } private static List<String> getNamespaces(SsoContext ssoContext, String authzName) { Map<String, List<String>> namespacesMap = AuthenticationUtils.getAvailableNamesSpaces( ssoContext.getSsoExtensionsManager()); return namespacesMap.get(authzName); } private static List<String> getNamespaces(SsoContext ssoContext, String namespace, String authz) { log.debug("Entered getNamespaces"); List<String> namespaces; if (StringUtils.isNotEmpty(namespace)) { namespaces = Collections.singletonList(namespace); } else { namespaces = getNamespaces(ssoContext, authz); } log.debug("getNamespaces found {} namespaces in authz {}", namespaces == null ? 0 : namespaces.size(), authz); return namespaces == null ? Collections.emptyList() : namespaces; } }