package org.atricore.idbus.capabilities.spmlr2.command; import oasis.names.tc.spml._2._0.*; import oasis.names.tc.spml._2._0.search.ScopeType; import oasis.names.tc.spml._2._0.search.SearchQueryType; import oasis.names.tc.spml._2._0.search.SearchRequestType; import oasis.names.tc.spml._2._0.search.SearchResponseType; import org.apache.felix.gogo.commands.Argument; import org.apache.felix.gogo.commands.Option; import org.apache.karaf.shell.console.OsgiCommandSupport; import org.atricore.idbus.capabilities.spmlr2.command.printer.CmdPrinter; import org.atricore.idbus.capabilities.spmlr2.main.SPMLR2Constants; import org.atricore.idbus.capabilities.spmlr2.main.SpmlR2Service; import org.atricore.idbus.capabilities.spmlr2.main.binding.SpmlR2Binding; import org.atricore.idbus.capabilities.spmlr2.main.psp.SpmlR2PSPMediator; import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptor; import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptorImpl; import org.atricore.idbus.kernel.main.mediation.Channel; import org.atricore.idbus.kernel.main.mediation.IdentityMediationException; import org.atricore.idbus.kernel.main.mediation.IdentityMediationUnit; import org.atricore.idbus.kernel.main.mediation.IdentityMediationUnitRegistry; import org.atricore.idbus.kernel.main.mediation.channel.PsPChannel; import org.atricore.idbus.kernel.main.mediation.endpoint.IdentityMediationEndpoint; import org.atricore.idbus.kernel.main.mediation.provider.ProvisioningServiceProvider; import org.atricore.idbus.kernel.main.provisioning.exception.GroupNotFoundException; import org.atricore.idbus.kernel.main.util.UUIDGenerator; import org.osgi.framework.ServiceReference; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import java.util.List; /** * @author <a href=mailto:sgonzalez@atricore.org>Sebastian Gonzalez Oyuela</a> */ public abstract class SpmlCommandSupport extends OsgiCommandSupport { protected UUIDGenerator uuidGenerator = new UUIDGenerator(); @Argument(index = 0, name = "idauId", description = "The id if the identity appliance", required = true) String idauId; @Argument(index = 1, name = "pspId", description = "The id if the Provisioning Service Provider", required = true) String pspId; @Argument(index = 2, name = "targetId", description = "Provisionig Service Target id", required = false) String targetId; @Option(name = "-v", aliases = "--verbose", description = "Verbose command", required = false, multiValued = false) boolean verbose = false; protected CmdPrinter cmdPrinter; public CmdPrinter getCmdPrinter() { return cmdPrinter; } public void setCmdPrinter(CmdPrinter cmdPrinter) { this.cmdPrinter = cmdPrinter; } @Override protected Object doExecute() throws Exception { // Get repository admin service. ServiceReference ref = getBundleContext().getServiceReference(IdentityMediationUnitRegistry.class.getName()); if (ref == null) { cmdPrinter.printMsg("Identity Mediation Unit Registry Service is unavailable. (no service reference)"); return null; } try { IdentityMediationUnitRegistry svc = (IdentityMediationUnitRegistry) getBundleContext().getService(ref); if (svc == null) { cmdPrinter.printMsg("Identity Mediation Unit Registry Service service is unavailable. (no service)"); return null; } IdentityMediationUnit idau = svc.lookupUnit(idauId); if (idau == null) { throw new Exception("IdAU not found " + idauId); } if (verbose) cmdPrinter.printMsg("IdAU " + idau.getName()); PsPChannel pspChannel = null; ProvisioningServiceProvider psp = null; for (Channel c : idau.getChannels()) { if (c instanceof PsPChannel) { PsPChannel pc = (PsPChannel) c; if (pc.getProvider() != null && pc.getProvider().getName().equals(pspId)) { pspChannel = pc; psp = pc.getProvider(); break; } } } if (pspChannel == null || psp == null) { throw new Exception("PSP not found " + pspId); } if (verbose) cmdPrinter.printMsg("PSP " + psp.getName()); if (verbose) cmdPrinter.printMsg("PSP Channel " + pspChannel.getName()); doExecute(psp, pspChannel); } finally { getBundleContext().ungetService(ref); } return null; } protected EndpointDescriptor resolvePsPEndpoint(PsPChannel pspChannel, SpmlR2Binding binding) { String b = binding.getValue(); QName qName = SpmlR2Service.PSPService.getQname(); for (IdentityMediationEndpoint endpoint : pspChannel.getEndpoints()) { if (endpoint.getBinding().equals(b)) { if (endpoint.getType().equals("{" + qName.getNamespaceURI() + "}" + qName.getLocalPart())) { String location = endpoint.getLocation(); if (location.startsWith("/")) location = pspChannel.getLocation() + location; return new EndpointDescriptorImpl(endpoint.getName(), endpoint.getType(), endpoint.getBinding(), location, null); } } } cmdPrinter.printErrMsg("No SPML PSP Endpoint found in channel " + pspChannel.getName()); return null; } protected Object doExecute(ProvisioningServiceProvider psp, PsPChannel pspChannel) throws Exception { SpmlR2PSPMediator mediator = (SpmlR2PSPMediator) pspChannel.getIdentityMediator(); EndpointDescriptor ed = resolvePsPEndpoint(pspChannel, SpmlR2Binding.SPMLR2_LOCAL); RequestType spmlRequest = buildSpmlRequest(psp, pspChannel); if (verbose) cmdPrinter.printMsg("SPML Endpoint " + ed.getLocation()); Object o = mediator.sendMessage(spmlRequest, ed, pspChannel); if (o instanceof ResponseType) { ResponseType spmlResponse = (ResponseType) o; if (verbose) cmdPrinter.printRequest(spmlRequest); if (verbose) cmdPrinter.printResponse(spmlResponse); cmdPrinter.printOutcome(spmlResponse); } else { cmdPrinter.printErrMsg("Unexpected message received, command execution error. Type 'log:display-exception' for details"); } return null; } protected abstract RequestType buildSpmlRequest(ProvisioningServiceProvider psp, PsPChannel pspChannel) throws Exception; //----------------------------< SPML Utils > protected PSOType lookupGroup(PsPChannel pspChannel, String groupName) throws IdentityMediationException { SpmlR2PSPMediator mediator = (SpmlR2PSPMediator) pspChannel.getIdentityMediator(); EndpointDescriptor ed = resolvePsPEndpoint(pspChannel, SpmlR2Binding.SPMLR2_LOCAL); SearchRequestType spmlRequest = new SearchRequestType(); spmlRequest.setRequestID(uuidGenerator.generateId()); spmlRequest.getOtherAttributes().put(SPMLR2Constants.userAttr, "true"); SearchQueryType spmlQry = new SearchQueryType(); spmlQry.setScope(ScopeType.ONE_LEVEL); spmlQry.setTargetID(targetId); spmlRequest.setQuery(spmlQry); SelectionType spmlSelect = new SelectionType(); spmlSelect.setNamespaceURI("http://www.w3.org/TR/xpath20"); String qry = "/groups[name='"+groupName+"']"; spmlSelect.setPath(qry); spmlSelect.getOtherAttributes().put(SPMLR2Constants.userAttr, "true"); JAXBElement jaxbSelect= new JAXBElement( new QName( SPMLR2Constants.SPML_NS, "select"), spmlSelect.getClass(), spmlSelect ); spmlQry.getAny().add(jaxbSelect); SearchResponseType spmlResponse = (SearchResponseType) mediator.sendMessage(spmlRequest, ed, pspChannel); List<PSOType> psoGroups = spmlResponse.getPso(); if (psoGroups.size() > 1) throw new IdentityMediationException("Too many groups found for name " + groupName); if (psoGroups.size() < 1) throw new IdentityMediationException("Group not found for '" + groupName + "'"); return psoGroups.get(0); } protected LookupResponseType lookupGroup(PsPChannel pspChannel, Long id) throws IdentityMediationException, GroupNotFoundException { SpmlR2PSPMediator mediator = (SpmlR2PSPMediator) pspChannel.getIdentityMediator(); EndpointDescriptor ed = resolvePsPEndpoint(pspChannel, SpmlR2Binding.SPMLR2_LOCAL); PSOIdentifierType psoGroupId = new PSOIdentifierType(); psoGroupId.setTargetID(targetId); psoGroupId.setID(id + ""); psoGroupId.getOtherAttributes().put(SPMLR2Constants.groupAttr, "true"); LookupRequestType spmlRequest = new LookupRequestType(); spmlRequest.setRequestID(uuidGenerator.generateId()); spmlRequest.setPsoID(psoGroupId); return (LookupResponseType) mediator.sendMessage(spmlRequest, ed, pspChannel); } protected PSOType lookupUser(PsPChannel pspChannel, Long id) throws IdentityMediationException { SpmlR2PSPMediator mediator = (SpmlR2PSPMediator) pspChannel.getIdentityMediator(); EndpointDescriptor ed = resolvePsPEndpoint(pspChannel, SpmlR2Binding.SPMLR2_LOCAL); PSOIdentifierType psoUserId = new PSOIdentifierType(); psoUserId.setTargetID(targetId); psoUserId.setID(id + ""); psoUserId.getOtherAttributes().put(SPMLR2Constants.userAttr, "true"); LookupRequestType spmlRequest = new LookupRequestType(); spmlRequest.setRequestID(uuidGenerator.generateId()); spmlRequest.setPsoID(psoUserId); LookupResponseType spmlResponse = (LookupResponseType) mediator.sendMessage(spmlRequest, ed, pspChannel); return spmlResponse.getPso(); } }