From 252aef12fbb5be2b8785ed6334ae46b1e70282d1 Mon Sep 17 00:00:00 2001 From: Ethan Kromhout Date: Fri, 30 Aug 2019 09:34:02 -0400 Subject: [PATCH] Intial commit of connector for Federation Manager --- connector-federation-manager/pom.xml | 94 +++++++ .../FederationManagerConfiguration.java | 30 +++ .../FederationManagerConnector.java | 248 ++++++++++++++++++ .../FederationManagerFilter.java | 19 ++ .../FederationManagerFilterTranslator.java | 64 +++++ .../FederationManagerConfiguration.class | Bin 0 -> 765 bytes .../FederationManagerConnector.class | Bin 0 -> 8371 bytes .../FederationManagerFilter.class | Bin 0 -> 871 bytes .../FederationManagerFilterTranslator.class | Bin 0 -> 3207 bytes ...nnector-federation-manager-.1-SNAPSHOT.jar | Bin 0 -> 9091 bytes .../target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 4 + .../compile/default-compile/inputFiles.lst | 4 + 13 files changed, 468 insertions(+) create mode 100644 connector-federation-manager/pom.xml create mode 100644 connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.java create mode 100644 connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConnector.java create mode 100644 connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilter.java create mode 100644 connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.java create mode 100644 connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.class create mode 100644 connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerConnector.class create mode 100644 connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerFilter.class create mode 100644 connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.class create mode 100644 connector-federation-manager/target/connector-federation-manager-.1-SNAPSHOT.jar create mode 100644 connector-federation-manager/target/maven-archiver/pom.properties create mode 100644 connector-federation-manager/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 connector-federation-manager/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/connector-federation-manager/pom.xml b/connector-federation-manager/pom.xml new file mode 100644 index 0000000..be0ee68 --- /dev/null +++ b/connector-federation-manager/pom.xml @@ -0,0 +1,94 @@ + + + + 4.0.0 + + + polygon + com.evolveum.polygon + 1.5.0.0 + + + edu.unc.polygon + connector-federation-manager + .1-SNAPSHOT + jar + + Federation Manager Connector + + + edu.unc.polygon.connector.federationManager + FederationManagerConnector + + + + + evolveum-nexus-releases + Internal Releases + http://nexus.evolveum.com/nexus/content/repositories/releases/ + + + evolveum-nexus-snapshots + Internal Releases + http://nexus.evolveum.com/nexus/content/repositories/snapshots/ + + + apache-snapshots + Apache Snapshots + http://repository.apache.org/snapshots/ + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-resources-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + connector-rest + com.evolveum.polygon + 1.4.2.14-SNAPSHOT + + + org.json + json + 20190722 + + + + + + diff --git a/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.java b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.java new file mode 100644 index 0000000..d3d3395 --- /dev/null +++ b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.java @@ -0,0 +1,30 @@ +package edu.unc.polygon.connector.federationManager; + +import com.evolveum.polygon.rest.AbstractRestConfiguration; +import org.identityconnectors.common.logging.Log; +import org.identityconnectors.framework.common.exceptions.ConfigurationException; +import org.identityconnectors.framework.common.objects.ObjectClass; +import org.identityconnectors.framework.spi.AbstractConfiguration; +import org.identityconnectors.framework.spi.ConfigurationProperty; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.*; + + +/** + * @author ekromhout@gmail.com + * + */ +public class FederationManagerConfiguration extends AbstractRestConfiguration { + + private static final Log LOG = Log.getLog(FederationManagerConfiguration.class); + +@Override + public void validate() { + // TODO + } + +} + + diff --git a/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConnector.java b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConnector.java new file mode 100644 index 0000000..083a02d --- /dev/null +++ b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerConnector.java @@ -0,0 +1,248 @@ +package edu.unc.polygon.connector.federationManager; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.HttpEntity; +import org.apache.http.HttpRequest; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.apache.http.entity.StringEntity; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.client.methods.*; +import org.apache.http.annotation.NotThreadSafe; +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONException; +import org.identityconnectors.common.Base64; +import org.identityconnectors.common.StringUtil; +import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder; +import org.identityconnectors.framework.common.objects.Schema; +import org.identityconnectors.framework.common.objects.SchemaBuilder; +import org.identityconnectors.framework.spi.Configuration; +import org.identityconnectors.framework.spi.Connector; +import org.identityconnectors.framework.spi.PoolableConnector; +import org.identityconnectors.framework.spi.ConnectorClass; +import org.identityconnectors.framework.spi.operations.*; +import org.identityconnectors.framework.common.exceptions.*; +import org.identityconnectors.framework.common.exceptions.ConfigurationException; +import org.identityconnectors.framework.common.exceptions.ConnectorException; +import org.identityconnectors.framework.common.objects.*; +import org.identityconnectors.common.logging.Log; +import org.identityconnectors.common.security.GuardedString; +import org.identityconnectors.framework.common.objects.filter.FilterTranslator; +import java.io.IOException; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.ArrayList; +import java.io.*; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.Object; + + +import com.evolveum.polygon.rest.AbstractRestConnector; +/** + * @author ethan@unc.edu + * + */ +@ConnectorClass(displayNameKey = "connector.federation.manager.display", configurationClass = FederationManagerConfiguration.class) +public class FederationManagerConnector extends AbstractRestConnector implements TestOp, SchemaOp, PoolableConnector, SearchOp { + + private static final Log LOG = Log.getLog(FederationManagerConnector.class); + private static final String ATTR_ID = "id"; //__UID__ + private static final String ATTR_ORGANIZATION_ID = "organization_id"; + public static final String ATTR_MAIL = "email"; + public static final String ATTR_FAX_NUMBER = "faxnumber"; + public static final String ATTR_MOBILE_NUMBER = "mobilenumber"; + public static final String ATTR_PHONE_NUMBER = "phonenumber"; + //public static final String ATTR_ROLES = "roles"; + public static final String ATTR_FIRST_NAME = "firstname"; + public static final String ATTR_LAST_NAME = "lastname"; + public static final String ATTR_MIDDLE_NAME = "middlename"; + public static final String ATTR_INFORMAL_NAME = "informalname"; + public static final String ATTR_WEBSITE = "website"; + public static final String CONTENT_TYPE = "application/json"; + + + private FederationManagerConfiguration configuration; + + @Override + public void init(Configuration configuration) { + LOG.info(">>> Initializing connector"); + + if (!(configuration instanceof FederationManagerConfiguration)) { + throw new ConfigurationException("Configuration is not instance of " + FederationManagerConfiguration.class.getName()); + } + + FederationManagerConfiguration wordpressConfig = (FederationManagerConfiguration) configuration; + wordpressConfig.validate(); + this.configuration = wordpressConfig; + //super.init(configuration); + getConfiguration(); + LOG.info(">>> Connector initialization finished"); + } + @Override + public void dispose() { + configuration = null; + //handler = null; + } + @Override + public void test() { + + } + + @Override + public void checkAlive() { + test(); + } + + @Override + public Schema schema() { + SchemaBuilder schemaBuilder = new SchemaBuilder(FederationManagerConnector.class); + //Begin Account Objectclass + Set accountAttributes = new HashSet(); + AttributeInfoBuilder id = new AttributeInfoBuilder(); + id.setName("ATTR_ID"); + id.setCreateable(true); + id.setUpdateable(true); + id.setReadable(true); + id.setRequired(true); + id.setMultiValued(false); + accountAttributes.add(id.build()); + AttributeInfoBuilder email = new AttributeInfoBuilder(); + email.setName("ATTR_EMAIL"); + email.setCreateable(true); + email.setUpdateable(true); + email.setReadable(true); + email.setRequired(false); + email.setMultiValued(true); + accountAttributes.add(email.build()); + AttributeInfoBuilder faxnumber = new AttributeInfoBuilder(); + faxnumber.setName("ATTR_FAX_NUMBER"); + faxnumber.setCreateable(true); + faxnumber.setUpdateable(true); + faxnumber.setReadable(true); + faxnumber.setRequired(false); + faxnumber.setMultiValued(false); + accountAttributes.add(faxnumber.build()); + AttributeInfoBuilder firstname = new AttributeInfoBuilder(); + firstname.setName("ATTR_FIRST_NAME"); + firstname.setCreateable(true); + firstname.setUpdateable(true); + firstname.setReadable(true); + firstname.setRequired(false); + firstname.setMultiValued(false); + accountAttributes.add(firstname.build()); + AttributeInfoBuilder informalname = new AttributeInfoBuilder(); + informalname.setName("ATTR_INFORMAL_NAME"); + informalname.setCreateable(true); + informalname.setUpdateable(true); + informalname.setReadable(true); + informalname.setRequired(false); + informalname.setMultiValued(false); + accountAttributes.add(informalname.build()); + AttributeInfoBuilder lastname = new AttributeInfoBuilder(); + lastname.setName("ATTR_LAST_NAME"); + lastname.setCreateable(true); + lastname.setUpdateable(true); + lastname.setReadable(true); + lastname.setRequired(false); + lastname.setMultiValued(false); + accountAttributes.add(lastname.build()); + AttributeInfoBuilder middlename = new AttributeInfoBuilder(); + middlename.setName("ATTR_MIDDLE_NAME"); + middlename.setCreateable(true); + middlename.setUpdateable(true); + middlename.setReadable(true); + middlename.setRequired(false); + middlename.setMultiValued(false); + accountAttributes.add(middlename.build()); + AttributeInfoBuilder mobilenumber = new AttributeInfoBuilder(); + mobilenumber.setName("ATTR_MOBILE_NAME"); + mobilenumber.setCreateable(true); + mobilenumber.setUpdateable(true); + mobilenumber.setReadable(true); + mobilenumber.setRequired(false); + mobilenumber.setMultiValued(false); + accountAttributes.add(mobilenumber.build()); + AttributeInfoBuilder organization_id = new AttributeInfoBuilder(); + organization_id.setName("ATTR_ORGANIZATION_ID"); + organization_id.setCreateable(true); + organization_id.setUpdateable(true); + organization_id.setReadable(true); + organization_id.setRequired(false); + organization_id.setMultiValued(false); + accountAttributes.add(organization_id.build()); + AttributeInfoBuilder phonenumber = new AttributeInfoBuilder(); + phonenumber.setName("ATTR_PHONE_NUMBER"); + phonenumber.setCreateable(true); + phonenumber.setUpdateable(true); + phonenumber.setReadable(true); + phonenumber.setRequired(false); + phonenumber.setMultiValued(false); + accountAttributes.add(phonenumber.build()); + AttributeInfoBuilder website = new AttributeInfoBuilder(); + website.setName("ATTR_WEBSITE"); + website.setCreateable(true); + website.setUpdateable(true); + website.setReadable(true); + website.setRequired(false); + website.setMultiValued(false); + accountAttributes.add(website.build()); + accountAttributes.add(OperationalAttributeInfos.ENABLE); + schemaBuilder.defineObjectClass(ObjectClass.ACCOUNT.getDisplayNameKey(),accountAttributes); + //Finish Account Objectclass, add others before return if needed + LOG.info(">>> schema finished"); + return schemaBuilder.build(); + + + + } + + public FilterTranslator createFilterTranslator(ObjectClass oc, OperationOptions oo) { + LOG.info("inside createFilterTranslator"); + return new FederationManagerFilterTranslator(); + } + + @Override + public void executeQuery(ObjectClass oc, FederationManagerFilter filter, ResultsHandler handler, OperationOptions oo) { + if ( oc.is(ObjectClass.ACCOUNT_NAME)) { + if (filter != null && filter.byUid != null) { + //not sure if this use case exists yet + } + + else if (filter != null && filter.byName != null) { + //not sure if this use case exists yet + } + + else if (filter != null && filter.byEmailAddress != null) { + //not sure if this use case exists yet + } + + else { + //wide open search + } + + + + + } + + } +} diff --git a/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilter.java b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilter.java new file mode 100644 index 0000000..d1028b6 --- /dev/null +++ b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilter.java @@ -0,0 +1,19 @@ +package edu.unc.polygon.connector.federationManager; + +/** + * + */ +public class FederationManagerFilter { + public String byName; + public String byUid; + public String byEmailAddress; + + @Override + public String toString() { + return "FederationManagerFilter{" + + "byName='" + byName + '\'' + + ", byUid=" + byUid + + ", byEmailAddress='" + byEmailAddress + '\'' + + '}'; + } +} diff --git a/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.java b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.java new file mode 100644 index 0000000..0f7b56b --- /dev/null +++ b/connector-federation-manager/src/main/java/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.java @@ -0,0 +1,64 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.unc.polygon.connector.federationManager; + +import org.identityconnectors.common.logging.Log; +import org.identityconnectors.framework.common.objects.Attribute; +import org.identityconnectors.framework.common.objects.Name; +import org.identityconnectors.framework.common.objects.Uid; +import org.identityconnectors.framework.common.objects.filter.AbstractFilterTranslator; +import org.identityconnectors.framework.common.objects.filter.EqualsFilter; + +/** + */ +public class FederationManagerFilterTranslator extends AbstractFilterTranslator { + private static final Log LOG = Log.getLog(FederationManagerFilterTranslator.class); + + @Override + protected FederationManagerFilter createEqualsExpression(EqualsFilter filter, boolean not) { + LOG.ok("createEqualsExpression, filter: {0}, not: {1}", filter, not); + + if (not) { + return null; // not supported + } + + Attribute attr = filter.getAttribute(); + LOG.ok("attr.getName: {0}, attr.getValue: {1}, Uid.NAME: {2}, Name.NAME: {3}", attr.getName(), attr.getValue(), Uid.NAME, Name.NAME); + if (Uid.NAME.equals(attr.getName())) { + if (attr.getValue() != null && attr.getValue().get(0) != null) { + FederationManagerFilter lf = new FederationManagerFilter(); + lf.byUid = String.valueOf(attr.getValue().get(0)); + LOG.ok("lf.byUid: {0}, attr.getValue().get(0): {1}", lf.byUid, attr.getValue().get(0)); + return lf; + } + } + else if (Name.NAME.equals(attr.getName())) { + if (attr.getValue() != null && attr.getValue().get(0) != null) { + FederationManagerFilter lf = new FederationManagerFilter(); + lf.byName = String.valueOf(attr.getValue().get(0)); + return lf; + } + } + else if (FederationManagerConnector.ATTR_MAIL.equals(attr.getName())) { + if (attr.getValue() != null && attr.getValue().get(0) != null) { + FederationManagerFilter lf = new FederationManagerFilter(); + lf.byEmailAddress = String.valueOf(attr.getValue().get(0)); + return lf; + } + } + + return null; // not supported + } +} diff --git a/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.class b/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..a193683305cd3fae7da3508bcc4082d5aac3e2be GIT binary patch literal 765 zcmb_aO-o}j6g}y8>r-di@!L&tV-+TgnVm%#3JUU6P;sBWm&Qn%NM2sSpEb;4#Dzb= zA2rNvEk#|3f}7-?L(aYD=HADD_YVMmVzYrVT2*{&UQqQH5VKLTLp5(*6^cSLU zh-tXPHVARL8QtZbzhJ*9C}57x%7knoqBwebfO#wsq7|8mcPE&* m*TVH@LN*oF@MR`!Pf`N)X5kLSKPZh8uxFK*2z@24faZVCV8c}a literal 0 HcmV?d00001 diff --git a/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerConnector.class b/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerConnector.class new file mode 100644 index 0000000000000000000000000000000000000000..dd91a0f87a124063d5a42ee2ef943e8219d8be96 GIT binary patch literal 8371 zcmds5d3;pW75?r^GH)`OuneFETmp3=Y@>*x2BSj=5X^!}AOceQX67Y%Fqs)=fdnls z)z+f5R%%@k7hG{g)I^LTZm75yY8PB8ZEe-I($%iC-+gy7GfChlA@raAG55^5?|$c= zbMCq4o_n|NeQFDUDI(W}v#>57BXFw|x9Paug*&ib$DKOv(s8#7PONj{9!c+Y;XZ7T z|L%7|#{(`n@SsFK#ffK~sBxmfiG@zgcj7!JwmLD#i8?3F&&P9kJ|8dOMHicwa>>pRleAL`hlW2cTE>3CPij|Fn7 zYG(|7E4HY#FOBxo;WzSD&I$hUfH78?6!it0is;bOj(whtiywOOgy_ud&`_|iJ z22C}t+6WuXX3RUYcMlzzkw(utrdeStQN~ppTQXlDw>%OwX>XMkHfxftelyl!_(SaR zR7Ct>%hIY?(J6wY)v8kp@gT z7$6O%$Y3;P#^XvP{a&9i0?Vq6Xv$VSXvL$EI9-vOFyqwG6=*R7%X}egIr|)Oa;=8I z8DmSnT!YjWi1?RsPsF|THdcnYk}^GMg}9IcXC0)dlmJQ`Y6Jq2WH{kVa4Y$f)LbsE zy~C0TE99*=6C9;kL4le5o-8f2GTao&%$Y|=SRwAiCZjEE$B_JQ#o~!D*N!o6ad@oN z2r1SXGP=LGTCHF(WTu9-M*J3;l!U=dCq~#>X>WriQsIJVOC+5BuCFltaVtUjhxH8A z_Govw&h2UVw1F91T1L+u7KoWf!klS^65J{=BODJI%yI(T4&$pEl!(tZ!b}LUL$M!t zI5<>@3sf8uU$bm!QThp-Jx~h;b`EfzGIf*6B>i{V|HSFeX@QWcF~t2rQG_#qOlk zXcns+mZ@@WX>RxtaAO841V)yXl@(XA(6o$@wURfC;P`RJ$QKrC6l?P^9z*J{?&vLh-yItJ#*f`@{6hNcYcSmSC4MDvoOBwcsTHD#l>6*8E^Zz zL?CO012wK^37l4&(KfIRLDcg;{R=8++aO5B~|s zMu7MI@-gw@narr1vvL6dlDJ1Ky#lB)Uu@WCUw(mpBqO7h|4I%H;4o+x>dE=V64@^lG zrbqJOy{C+4HF*NLsJQyH#G8Js_oV|F2p5N+g`Ukkgdgmr3>DQaN_vA(cHZ zDqW^z7jUjR(+FmB7bLBi$u%CtZ`CZlE&HjB9eIBF93kL4h?k8Xwn`&2nYdnN;T$7K z$vqajJMI?tf8|`?bW@7ad?-E(xi}j> zOh-8eVWh0W_ma>)L&2&@_Y27Aho}8R#klTU0@z23=Gsbj5U(f~Tf==Xn zTpcLzI6B}a?Lc8C20c4|D;(7mIxu+LgeNd$TnC0WN+F(<5UEKHq$bBBpKT+xSb$+P zc`_DbDorcJ5-yU#rSaojnjE1?SQ5j3XRrN3eDzPC8;de^Npp4~DXUA`OhDfhQBD+~0v=y=RWny%%H& z$V&^j05LUl-WZxZhyl5$3&R(9Ms)Hyu?vUO>qk^~p@?*3%|y?r4jkDyk&APb-5zbX z$JlLg)f^<0~2(Q@As7i*h~3N@P*44YkS9iaUmcxMIZ-Uc@22@Oedf zp5ttMp2AB)yd=cuDZC^SpVtTPC~|m?xA6{zmxOpph<7NwBofc?>NUS!qk2Q4#Or7ZeqE#@qM;g_neQNr*2{cu6Fl8?zVQ zUF7y~hjM*mqg+V)A$LSFiAz? z_)YM3;6y5Ml1vVhyE9A&PTt7fW+w=-lF0x_GOw+G2W`yD?abmUaRM&HL|lZE@pYVz zRm|!aGh<(ZdR&S{xQuDz8%$-FBZ@1C{3b_y3#)M@*5KP%%YW-}6*k~%Y-E++iEFS0 z-^F%ZiyinLcHuhg=EzU*eeA*Y_yRw`UfdvDxKRwlO=1*o7Gtnhl;9R|BG!qixK)(l zHZcdci+bE47Gb^c<4$4WE)m7uVg>FIt8lMajr+tJY!GX4zgUk4#0ESlHsT@CiHF4& zJR-JZqu7B*#V%|TyYZO#1doe7ctU)E4zU-VnhQ^A!?0N!g{QPJ=+a8?w00t%(WYXH zR)%M_IoPVz<2h{+p4a?%L9_6p7R5{23T)F>;bm<#UeVUzRc$S{YwPivwgIne8}WwL zi8r+^cuU)kx3!&kNBa;vw9l~9&P~^-{FBN}F70E)kzjW6XdiG@mNSQr)ZV3s+qho! z+B&XI8}r&4Z86uVjk$G)b`)2t4Gu9(ywCM&gD&dDI<8t9oMMew%#~?FzStp-;tICG zMGN2OI<}#Jwyfi7w!uxU7jsS9P{>tPN0yrZayz$Q!S&VbOg*1k$RlgG45%rofa=02 z%#^3fn9}S+M`iw9Japc(ZBz%#@RW^2Gghv&6ZddN%W9&ovawgQk9R_qn{gZa^VmO` zaXhsHr`?2c6Skpn!s9r78yxrI$P{;m%?%>w; z@g~osDN1@;tI27tCNoyAA*jL(UO}t|2}uyC$XVR0@;I7LFS~ zVJoIhlnMRJ%!#B5g0r(uqr%j@PVRy3b8xin6Y$6%@g&L~gC+$C+oeiCIaN`vx}IA` Xy88y)NIHb0ZX$PcoO|z<0F3_vK*q(> literal 0 HcmV?d00001 diff --git a/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerFilter.class b/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..17e6f922e404bdb6b3b09308b581f1e35cebf194 GIT binary patch literal 871 zcmb_aQBM;=5dO9;?NN_%o+yeHi=e$Ca4)_oO{9URiVrA>k9&7(S#sTNjysZu_@6W} zCDFtm;EyuS-k}h%Z@%m|GduIm%(wgV*S8-4USO+^29|4hTt^AZ7Fq^ZW-*5+##*(o zW}K%Mo*8VLpjShuhINK&Fy7}w!Ql3f`6>5ft_J==nn*Qx$uJX)-^+-h5sY_-T*j}X zC=n+oRQ5_LnRXe}N{EJ{EJ(9$++ZR#h zXDakZIvx+S@)9X#Y#tMC@ z2K~b_=>6f4#mt^L(pH2eijb;w-X+f`WP~&8=U`v*>w9!o^I#Q=WZOjo?&AS@%;-X= zDL%@{fbMscKAfZMRwhLB6;%SKJweU2ioh&^TQBTee=eO*lre$*nV3qr>^gU)Yxi&0 IW}fxvH<3WkKL7v# literal 0 HcmV?d00001 diff --git a/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.class b/connector-federation-manager/target/classes/edu/unc/polygon/connector/federationManager/FederationManagerFilterTranslator.class new file mode 100644 index 0000000000000000000000000000000000000000..b9418820114ea64f902eff84de9fa0910598fecc GIT binary patch literal 3207 zcmb_e-*XdH6#j0Tbd#_^sZi_>B&`BTe{G>ap()i;T0qlQ4Xw7QxJkC@((P{9Y|xIw zn@`U84u60%J|aq~I_euUIzIU~IODs%I*#AnO-d-uIFU|fa?ibc&Uena=ey_LU;g>- zM*ydBJBAJnN706J5u8^r5}Afso<>$-j-q}M*M3E<|OXCf_DTO)3cWadee?u(9FDHd#1OZ zb8Oqld5&Aua?a|iV{4XED42FZOFM;>K+~vco8B0W6Uljj(1epW1oo#*+n6b>W)1h6 zp0&8rl6G>sHLts-oR=3v-m+N~m`xk`l2)>F+L~jn7wBWltF~n14OjO}$DY=0y#?x~v)B2iUeg*FeEbdx8ZtAyn&C*HCS-)`f7a7f2Wp+k0X2I6Il1nPy ztviV_1;(>Q&((8YK!PWP8{L)qjWOa_#wocugAN$y@&9D{fJ|D&OE{{c6GsI4cjkRx zJjh@q{>k8-zBsE&>Es=O=Iy(tU_r$qt}A#?#rya`!3`B3LMNvr0|p9)H^Xx>5)Y6n zYxBBQ;vzBo;&WzxU}k)JlG9V1O7+To=njjnB8!}gJPZX(DhgOuU@Ew&Vg;6hRTVZI zfr(w{2{M&66}PY~&|@tPWY-y7c@v%rJ&}}|B?gmz4k}z}!R>#Jt~60;oC0BERW~ga zMJ%g0hT{U$&jr1me=0nb*hc^7p|3@2f%EkuZk=|415c=R(Qzz8XZKZZOP^)Q#C94EDKZU;ybE??>2#U*@P*DD6=Q?KhBxP zQE&|RJc9U&LIX{JCV#OV-IUcp0Waef&O)+Ba3xO6KcOJZ@x%i(v^0i)Kxm<{H?t7x z+(bCDfu_!T2#fo@8&GDXMnv&7`Zo}z5{Fo3A^ZS)G7C))ph^Qy>^N+;BBG%bhCwjCcw9< z@o&_|KS=YI*6r2<)z)3Ltq;>$+~@W+`rEsRR?0_ln6nOU@)2%oH@Ec)PGAlRm`JkA z_uy0X;tTZQOV;Tj2Jtga;y0Ya?-;@#IE%k9EEJp*%{VW*F(Qs(%rDs$7RKfG6T}M9 z;!q$_uPn);l?y7RBz=(ulzQo{0o@{uehe^LjdAWl=*ZvrOu^vTh2~2P^<+?gj*a{Q yN>6X+240l;)uNA5_7-9E74CKU!~&u%ZJTKS8V!i8VH-dDBbV)aegv3a9w{%NO$B2MGd>-Yz zdd_+O?>gU}>v^6%GwWV!$C|y@UiZjL!NH@#+!SPKQn~-B{Bc9Me#(d{3o=N^f|%t0 z5JQGRx)uw~is-bt{yO0L!u_+DjG(LpNK{FgQ3iA*)7L94#lSd>A;myD&^K72$UMfn z_{o-Da-fS|ia`h&X*FB*H9lPvrE_hHB&(gIeJX7Uu3|;Vp&jd?l+^WyA&NLsib_o_ z;Rr$9fCAKpAaH>TYKLpCD;1UuO`SH))B`vAWAx>)&`{@E=USK_O@#TMCSJGdXMw-2 zfejpfcH(ylh^&Mpl;pAWifa()w1GmSBB*E8Bm-(f=dP5NrUp z)wMUVvXs%a)HMR%YWhAk9HeVZVRv9)E@5F{o1wz4!dF>?5Bk5S)T*Uqj) zQN{{~1e(E1Y}#29NbRuTAasS9CUdeuJVcl4v`~i!}xrk(e*L5aU6N^+Ga;ytwrU+Xv`M zl}uh?9<@EAi&=EJ3wp)M(ewI|UHwTR1#|#HuRF<}KX}h!;UoRWO()`Xsy2i+YV{&670c5(@#~1tjK$}yc zq6;DlsS+W=)ZnKW&sW;$FCApHc5z(t3Bq1{(=gbppce7PpGNPDST70sjLhQ<$nd6W z)o_((L^DE798^8jHuP>xH*5}}Op&({^U;MaZVp+$MhDw62NI|)gN7#B0_kVSt~wLS zrM$9by#k^<4rQOk+PabjlN3HF37t4kw$f31t^5{LuHfS#f}6Ds=j?N$m|ssG(L>~g z<79bnDtfYI6wl`U?49WkJxU$D13-gyQt048Z-8Dn z`0v($ja2xu62o`Ra~MX)M#91CW0h46mWhSB;EK9Ll@(Qv9(k_ZvRDc&)ywO7Si7y&zzvweUR`>vw%$`Tu~8CN=j9!SgRJwgG3Cno4>8_f0O!H#v>JS>U#QeDWW%`jP@_LIsZUee8>t8l zCe3!wj5#=^kFOfgu21rQzHd=e{%*|5hZmEo7?L^>DD3HYVU%|k^ac;&dxV-a+%lw5 zx99f!12RZMU~^&DB&QIY{cXRz6Pp<@8a2*Zs>2O+z7q*(Ne9JBah0@x`a;!ijankB zgj6x=eODM{P4BdlaU-#zwtI?ZT06T0i)k0>eZdB*qBvdGOKzQKg7|bmdq5HDgie>b znof&eVC=&@^4Ay$PH$U=!1QN1)m^p2*rfp!KIms+vxK;lLi*>myn%RrfQxDFj~EDC z#nd$~G5x3BVe%qi9vSgJLD!o89*-^E5-0rlzC^a(A4MdTv zvlZdi(dYWe0e6=uyC8{S^RBK$ft@s}{tB&czXpAW|Ffl-O?a*QSOJrmIN~QJ3;}x@gbxd z!`O{ajkCVxQ=MDs8{-NmPzM<&bst;gq)O6djW3*F?eO2j%Z631>jPDesvW@Z1GR0& zO+d~)J9oRUaX>_P}QX@M|Sk&az``WI594K{?|P7k0);(W?p%JqA19cK=v*Ts`R%b&Yjy2i`P zEgU@&tEZB*MSE10I>P-*mi_@c$-SgQEhz3B6qXMfy>$$82}OZ};t?DWBOdTDuE?RY z0@Tz=KewbJC)Ck&@|nhdKB%-p)d^A#F;%FQtOBmXV)KQR z@)!l5nB1wdy!0TuM77-V#%Xu3_lIen960xu+Ecwu$ZB;Mp3W1vmG$%8DHOu^YJ7o; zcQyy&gE1zr5hSojj-Nd_6!;N7d|yjV^X9aMueVVnI2ag-|C_b+cK;lGisg}<9Yj1k z#_o4`PZHJdNlppV?3<_urg9ngpVQiC&Pdh8R)kk`DEdO>9%LxP2Hk9-ebaXeU(eR; zBqz?D8Lof6f_^#Sd6_p^lI49uwEIz^rOq#|IZTv($vcSj`6OF61zH3~wajo)hEglO zFgqdHVTO+NSECEQGyPJ;D}}-wB3^xUufmKg1Pa;hU$}2#W*{$ zMOSG{IH`|N081?s2$SpXU#UvQA?oc!C5|>Q@2z>_AHK+49o0nN@D$$sjL>5V77}_P z|Hyh8XH2t*njX96guLO@ZS;$HFZ^j`Gv+?B`iu6Csi=ab_(@A$vOtbyOcexS>isnFbo1q&a8LUji| z8wxy%=1u4$Hu8qYi#IhJeoj}#7>HI{18YhSy2q(Ji&llELT6zyUOh5iTD{)DlPC?` zH>(yn-zKx$OZmF%v^%w1yFSnNg8u_f6I)!-vbnjfF1n?fbwDVO%B){Ma5v5-BGgTV zdNO;Fe}18C`HuP0H&W$?D-ZExdHbRw^2c}!7g^@5V#{SZ9PtpGH9K%?x0?t&pIwVE*rIap-z;~5$=v6^9#XLpCc`2Ql^@H za&5%|mqey&jb=KCmrAo4@HGEPY|#n1_B!jlwJzfPYQF}=MWcg9bHb_i-9mi1S_eNs zAo3tBlnl74{BZ!BplH#aX?ndeEojUr zN9Ys?3x!h^Trb@0wa!dcyt%3z*sr$6pzY{M zd<`|WsvatEVVZ&zcvas1Jx^PM{U4zjuZm@JCzf`b%XS?5nurn>7KO==#D~IrDA3K$ zOUFsiOnfx(MQ14kMQrqg`Z)9U#6_t%-xb^W16XiAtyX19gb>=&6-Nr5t0v#0h%~og z)5CDppIo#o_i=TOB4y=DCF+x@OtA5H5yqF0rn0fEWkUyx285*LCd``_m+KX|ALMUt zmtd&rOzXVNX7)f4)d%r1Hbl;CC$@=Jz^Eo{R=Ijxo79nF zllk1ipEZQ)(g{UTqsdfLB7M2RmAJQ6(>gJht<`|SzXGY7w*BRk@R3)7bN~q`PGu}n z3?-LS>4(;66xN+0PHZ+QpfI`}B1ApOL?yd>>)EIvc7pD7fQ+j~TlmAPh0u1KdwL=) zmLtdNMWp!I*c0`Q`6Y(bxEzY3&r3itfw%$pC{syUK2DQrG$RazRI5iFJGq1n6LR9f z-=E=8p2?b9s(bT(nbkjc|JZiK!JOG}14Ta^AUmWQv>D~B{+JZq?fhP|N6p7+4}?St zevidPV^gJZkPC4-|30(%yV(7calg(0JcB1@;;1%M_^rhmbf9KsD-N+^5uhP6$JV!w z0apJwQ3M_yYWA#tWX0EM$!vO`L%W69hOGnHbx^iKoq;KVgQFC$u@JonPjN^vWp!Qs zdvq0oqh&)PBXrl~*$pN+MFdX9Wb~k3Z5utII_hJDJI$uB(9m&J=c*`knVGckIp4tr zLbixO@~+V2>|g=xa%>?Ef2FTluY>N+ ziGldbYFk|0UK*zA%QJXs67f`tB^HzjWfl}nDHop>CR$h$5#1YOCXPj4>FMo7E25^9 z;WIDIAqMFtF{tc&ypIYcGlQa>vi6ZR=osX0?X3Z)ef%e7KNL;$?ArKKoNFhJ;H~;< zM+&iOi(AsLeeP8rqOMFrWxv4P>xDjT4S**4M>vlL!V!56e0I2FkI~q~1PEUTNx9_@ z?Qo>)%!=4U+L2A(HktW794}E0!5sASF*{_zYvuzl@bb+I<&d@REKxhMU!XQl?4$6H z?*ptnTay!DZ14Qln>WW0x_zuYgzCOM}pmP$squJT)^Y z@mbr#!Cn91+2du?NZpM=L4R(4O^N5Y_@t$nB>;c>p;oz80T#8^#{C?BuTcTSdFCOH zMm<9Ok$ncuJeHtO%uqyUW#$x)nwS)7*eBp8RmSY)F^#TL0QyEr2)c`-0e&JjD;r(jAPerH=t zP=O=*fn*EzH$caIQ+93n;#>&M$QKnW%JS_PwcbFhM&Z1V#7_m+T$hoTd%F)TqvA;w zFLmqK>rE0--EcyBO;v_RbU%GyCXzfFpr{)d5>6cRlVCNBj5rD^%%B~rOrJJx8t(eS z3`IJ4H~h6l+UL0LCF|-&hCG>=Q|H{so%>PGPVz{1tAGe;6~M)G6)mm=&e#S?X)>YM zffw9#w59}zL>uavi>Y&YO#nO~bt~})tWFa0opau${U_s!p`TZL8#mkTR`|u)rdKnq z%25w=INqE7681UvV!VS4^+1gIT&QJgGxGwgUJpjDKH(+H6XMzg6am8w*e`^gMa(bH zxf0O)U5;M};SC?LZrCk~Iv{EZ+dp_!`p8uf(Svc=0btKJi~%?n$|L{}g#__4z0wvs z9zk~n46hpv^#)y;B7X4kR3;hritWg+$>tDw9pTE2zmzbGQr(|sD!*NcbZMNaii0y0 zioXSrE|&Ioip;RhFPp*aj)^& zRRK;gK?-|22_Z`@R3bEG)>|Qj3r8*(C7!Y~ZWX>JUrSn%zS&r@_O&t{#dvOvB&$S* zq~e;UVt~|h>TC&#o^M(&RVd8>9Td`bk1D6#pV44|MmQ2cWHrG9-Ju4XEIyKaf#t6z zPY7EQIecT+nA>xsESjwmBXhim+4f&oe&J!R+v`yP?)e4SH~R&mAchBJ%knp4I%enu z8A(6xP<2{Des>X~yL23|+ zifc(t-0nZQ-x)QpNo?xW8Mv#yW&3107kRh8zl8^aIe5S^|8O7E+X)#Wyhx(wQbvKc zcg)TAc+xqqi3eexW?$CZDR+N>9;6 z4PN`6^CLgCcl(TGy{z3G_3-nL_8GmMP#|=EPT(b#vaLk(6%}ta1Z_NLmBn#f?f#Z^ zmm^*!bN95Sb(HTnZPfI5zmJflyvYtT*fJCd)qYZw84V=P&&h2r4V!om-}!x0J;FT0 z{x0r(Y6pQ;r}BYSk0X@Z8XLt1D2JId2grrXGyg1$WzO&j?tz4xAqKB;7GzfTnLC4Q zn<#a2du2OgGeBMJ*`;F7WV}M|hm?1p@LqE?fC_dbr@?CX4!7A>h}9#C%I_?+fzICp zKI)*AwyPE%^4O3#F3(K9+Ab$pX!e|a3CDJX<4%BNL($N5w*SadkJi#K%La`&LSstA z+#tr9mdW&G-v=Ed8RM?4l}TU57@Tj2;1(PHl#(_GKoRufL(ALt9GU z{;~9z7YxMN>_bzK9fv$Sj1Vq^(#L_b*XI zZ@`4Nb=u$e4343hPuj8TT}z8AWMfdFY2P}j#>~Mj;hY?apN?Le7JCE7B~~{c<%#Vm zEIA1zTHTqA$-~`i3B^tu8r*VA>F;|IHe29;Hw`z}IR*a}ZKI3q2)BnUpt7I8)Rj;< zlDb8ib0lu*Ql=*HJnHxaKhrX7biSSe`SRzv_V)z;-Rtwo&ji1Pt|R!*+3a800J7hO zuT$!b*9mjR-&5hgf_eWt_-AIE;Wop~VDVduTg?q$ZunvW=HU8VK5%``68@K(t*tB= zoh{7!)tYT*II#FMUX+j1B(g|IIE+rj#ww7wWfm~FNY|Q#W7S44MZ>_ojI-~4?}QSG zYa%5vw^=#d-r7DhcZMH=!0TQwf#WQaQ;Taf*RZe+8!XzU?1WjFc zfZ=bg?W+zh+r@wcYq!4n=mkd*0d#5OWtd=C3l^hh>xc{?#7l7Vwdo)~S1P^Vy2tns z{el!i3o~b1@b#R4Sf9>Ld zS0^w~lMv(#A_aIbB#Z0hQfXi8hIPxn()pnMwJ-WK=Q%X`uS{*vSN<)KY_mY|nSh81fQWb`%7AXm4Sx|D$k`WbN z2``+d?fS5FD_B&z1fC=TG5eFCFU*OJ>2v){tMpCGRJHfSDUriTEd%F@wbDyM%x@ak%Hj8kV9xqzY`DD~66FDNsJsaZF`_ zZQHtGh$Ee&_2mZ#!eiIV#fa^qNb>By6`|xzv!vambklm*M-;tBR@niN%@cYEW8Qrgb95lAG$#q@&8P7NjH3rg0~!pX65Fz*sb*qvTi@u;+)A6Um&Q2M=*iS5xKw}3E|#sdXq zveKmTH=!O(DdAQvXBA(RB$YP=rh=ba95*QozCEYsLXBJAcqfbakrB{e8r{wOHnMO` zQn8mPyiOrD=_D*HTn^zYd(%R9U8yqP(L4^6SNA!maohk#wA`CrsvWm46Y9G%26uE_$!9?x9RE;h7>Lbr8yI>L20 z5mm;2n#R}`v+%f?nObj$6843BUdu( z4nkjmU_D%_P1I2~m(e@QJmJFhed~$pVMgU6-x}r0*%XGA9RRq>N*Fp>(fme>ByP2u?Da_jooCOsqGpW2MnNpXuI+*O zd^ToBr@iP-YUFsMl?5auBp;4Z%anFX4{^K}&*U)Y-pG#gS0g>DSjf;wzaYb+uECe?eO}0QC~4*JstLF&}(uK8neXJM6QYuC3_v$;+i441B(my_XO{CXRiwu z%xA%y=g)rM!v31@y%D}C+1`(@?>}LGqJM8S{LZ%C@UhqgP_F;4@PE*N@2S>b&HkF!y)`R{_Aku}|7Vi-*79EmY~L+o z!F>C+MDV9y-jDF@hqL?+z6s!N!I*@