public void Delete(ObjectClass objClass, Uid uid, OperationOptions options) { const string operation = "Delete"; plugins.OnBeforeDelete(objClass, uid, options, _configuration); ExchangeUtility.NullCheck(objClass, "objClass", this._configuration); ExchangeUtility.NullCheck(uid, "uid", this._configuration); LOG.Info("Exchange.Delete method; uid:\n{0}", uid.GetUidValue()); DeleteOpContext context = new DeleteOpContext() { Connector = this, ConnectorConfiguration = _configuration, ObjectClass = objClass, OperationName = operation, Uid = uid, Options = options }; try { _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain); if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain)) { DeleteMain(context); } _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain); } catch (Exception e) { LOG.Error(e, "Exception while executing Delete operation: {0}"); throw; } }
public virtual Uid Update(ObjectClass objectClass, Uid uid, ICollection <ConnectorAttribute> replaceAttributes, OperationOptions options) { var attributesAccessor = new ConnectorAttributesAccessor(replaceAttributes); Name newName = attributesAccessor.GetName(); Uid uidAfterUpdate = uid; if (newName != null) { Trace.TraceInformation("Rename the object {0}:{1} to {2}", objectClass.GetObjectClassValue(), uid.GetUidValue(), newName.GetNameValue()); uidAfterUpdate = new Uid(newName.GetNameValue().ToLower()); } if (ObjectClass.ACCOUNT.Equals(objectClass)) { } else if (ObjectClass.GROUP.Is(objectClass.GetObjectClassValue())) { if (attributesAccessor.HasAttribute("members")) { throw new InvalidAttributeValueException("Requested to update a read only attribute"); } } else { Trace.TraceWarning("Update of type {0} is not supported", _configuration.ConnectorMessages.Format(objectClass.GetDisplayNameKey(), objectClass.GetObjectClassValue())); throw new NotSupportedException("Update of type" + objectClass.GetObjectClassValue() + " is not supported"); } return(uidAfterUpdate); }
internal virtual void Delete(ObjectClass objectClass, Uid uid) { ConcurrentDictionary <string, Pair <ConnectorObject, DateTime> > storage = GetStore(objectClass); Pair <ConnectorObject, DateTime> removedValue; if (!storage.TryRemove(uid.GetUidValue(), out removedValue)) { throw new UnknownUidException(uid, objectClass); } }
internal virtual Pair <ConnectorObject, DateTime> Get(ObjectClass objectClass, Uid uid) { ConcurrentDictionary <string, Pair <ConnectorObject, DateTime> > storage = GetStore(objectClass); Pair <ConnectorObject, DateTime> entry; if (!storage.TryGetValue(uid.GetUidValue(), out entry)) { throw new UnknownUidException(uid, objectClass); } return(entry); }
public void TestCreateTestRunAs() { ICollection <ConnectorAttribute> createAttributes = GetTestCreateConnectorObject("TEST5"); var builder = new OperationOptionsBuilder(); builder.RunAsUser = "******"; builder.RunWithPassword = new GuardedString(GetSecure(Password)); Uid uid = GetFacade().Create(Test, createAttributes, builder.Build()); Assert.AreEqual(uid.GetUidValue(), "TEST5"); }
/// <summary> /// Finds a DirectoryEntry by it's uid /// </summary> /// <param name="serverName"></param> /// <param name="uid"></param> /// <param name="adminUserName"></param> /// <param name="adminPassword"></param> /// <returns></returns> internal static DirectoryEntry GetDirectoryEntryFromUid(String serverName, Uid uid, string adminUserName, string adminPassword) { DirectoryEntry foundDirectoryEntry = new DirectoryEntry( ActiveDirectoryUtils.GetLDAPPath(serverName, uid.GetUidValue()), adminUserName, adminPassword); string dn = (string)foundDirectoryEntry.Properties["distinguishedName"][0]; foundDirectoryEntry = new DirectoryEntry( ActiveDirectoryUtils.GetLDAPPath(serverName, dn), adminUserName, adminPassword); return(foundDirectoryEntry); }
public void TestCreateTestRunAsFailed() { ICollection <ConnectorAttribute> createAttributes = GetTestCreateConnectorObject("TEST5"); var builder = new OperationOptionsBuilder(); builder.RunAsUser = "******"; var secret = new SecureString(); "__FAKE__".ToCharArray().ToList().ForEach(secret.AppendChar); builder.RunWithPassword = new GuardedString(secret); Uid uid = GetFacade().Create(Test, createAttributes, builder.Build()); Assert.AreEqual(uid.GetUidValue(), "TEST5"); }
public void TestScriptOnConnector() { var builder = new ScriptContextBuilder(); builder.ScriptLanguage = "POWERShell"; builder.ScriptText = "Write-Warning \"Test\"; return $Connector.Arguments.uid.GetUidValue()"; var uid = new Uid("foo", "12345"); builder.AddScriptArgument("uid", uid); var res = GetFacade().RunScriptOnConnector(builder.Build(), null) as Collection <object>; if (res != null) { Assert.AreEqual(res[0], uid.GetUidValue()); } }
public static String ConvertUIDToSearchString(Uid uid) { // e.g. <GUID=8184d4af97d9ed4c949c21665768881b> string uidValue = uid.GetUidValue().ToLowerInvariant(); if (!uidValue.StartsWith("<guid=") || !uidValue.EndsWith(">") || uidValue.Length != 39) { throw new ArgumentException("Unsupported UID format: " + uidValue); } string raw = uidValue.Substring(6, 32); StringBuilder rv = new StringBuilder(); for (int i = 0; i < raw.Length; i += 2) { rv.Append("\\").Append(raw.Substring(i, 2)); } return(rv.ToString()); }
public void TestSyncTokenResults() { foreach (ConnectorFacade facade in CreateStateFulFacades()) { Uid uid = facade.Create(ObjectClass.ACCOUNT, CollectionUtil.NewReadOnlySet <ConnectorAttribute>(), null); SyncToken latest = facade.GetLatestSyncToken(ObjectClass.ACCOUNT); Assert.AreEqual(uid.GetUidValue(), latest.Value); for (int i = 0; i < 10; i++) { SyncToken lastToken = facade.Sync(ObjectClass.ACCOUNT, null, new SyncResultsHandler() { Handle = obj => { return(true); } }, null); Assert.IsNotNull(lastToken); Assert.AreEqual(lastToken.Value, latest.Value); } } }
public void TestAttributeTypeMap() { ConnectorPoolManager.Dispose(); ConnectorInfoManager manager = GetConnectorInfoManager(); ConnectorInfo info1 = FindConnectorInfo(manager, "1.0.0.0", "org.identityconnectors.testconnector.TstStatefulConnector"); Assert.IsNotNull(info1); APIConfiguration config = info1.CreateDefaultAPIConfiguration(); config.ConnectorPoolConfiguration.MinIdle = 0; config.ConnectorPoolConfiguration.MaxIdle = 0; ConnectorFacade facade = ConnectorFacadeFactory.GetInstance().NewInstance(config); HashSet <ConnectorAttribute> createAttributes = new HashSet <ConnectorAttribute>(); IDictionary <string, object> mapAttribute = new Dictionary <string, object>(); mapAttribute["email"] = "*****@*****.**"; mapAttribute["primary"] = true; mapAttribute["usage"] = new List <String>() { "home", "work" }; createAttributes.Add(ConnectorAttributeBuilder.Build("emails", mapAttribute)); Uid uid = facade.Create(ObjectClass.ACCOUNT, createAttributes, null); Assert.AreEqual(uid.GetUidValue(), "*****@*****.**"); ConnectorObject co = facade.GetObject(ObjectClass.ACCOUNT, new Uid("0"), null); object value = ConnectorAttributeUtil.GetSingleValue(co.GetAttributeByName("emails")); Assert.IsTrue(value is IDictionary); Assert.IsTrue(((IDictionary)value)["usage"] is IList); }
// implementation of CreateSpiOp public virtual Uid Create(ObjectClass objectClass, ICollection <ConnectorAttribute> createAttributes, OperationOptions options) { Trace.TraceInformation("Invoke Create ObjectClass:{0}", objectClass.GetObjectClassValue()); try { Uid uid = ExecuteCreate(_configuration.CreateScriptFileName, objectClass, createAttributes, options); if (uid == null) { throw new ConnectorException("Create script didn't return with a valid uid (__UID__) string value"); } Trace.TraceInformation("{0}:{1} created", objectClass.GetObjectClassValue(), uid.GetUidValue()); return(uid); } catch (Exception e) { if (e.InnerException != null) { throw e.InnerException; } throw; } }
public void TestMVCCControl() { foreach (ConnectorFacade facade in CreateStateFulFacades()) { Uid uid = facade.Create(ObjectClass.ACCOUNT, CollectionUtil.NewReadOnlySet <ConnectorAttribute>(), null); if (facade is LocalConnectorFacadeImpl) { try { facade.Delete(ObjectClass.ACCOUNT, uid, null); } catch (PreconditionRequiredException) { // Expected } catch (Exception) { Assert.Fail("Expecting PreconditionRequiredException"); } try { facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), "0"), null); } catch (PreconditionFailedException) { // Expected } catch (Exception) { Assert.Fail("Expecting PreconditionFailedException"); } facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), uid.GetUidValue()), null); } else { try { facade.Delete(ObjectClass.ACCOUNT, uid, null); } catch (RemoteWrappedException e) { if (!e.Is(typeof(PreconditionRequiredException))) { Assert.Fail("Expecting PreconditionRequiredException"); } } catch (Exception) { Assert.Fail("Expecting RemoteWrappedException"); } try { facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), "0"), null); } catch (RemoteWrappedException e) { if (!e.Is(typeof(PreconditionFailedException))) { Assert.Fail("Expecting PreconditionFailedException"); } } catch (Exception) { Assert.Fail("Expecting RemoteWrappedException"); } facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), uid.GetUidValue()), null); } } }
private void AddOrReplaceDatabase(ObjectClass oclass, Uid uid, ICollection <ConnectorAttribute> attributes, OperationOptions options, AbstractConfiguration connectorConfiguration) { if (!ObjectClass.ACCOUNT.Equals(oclass)) { LOG.Info("Nothing to do"); return; } // вычисляем значение атрибута Database только если он не был передан // и дополнительно пришёл атрибут RecipientType со значением UserMailbox ConnectorAttribute database = GetAttribute(attributes, "Database"); ConnectorAttribute recipientType = GetAttribute(attributes, "RecipientType"); if (database != null || recipientType == null || !recipientType.Value.First().ToString().Equals("UserMailbox")) { LOG.Info("Nothing to do"); return; } DirectoryEntry container = null; try { ActiveDirectoryConfiguration config = (ActiveDirectoryConfiguration)connectorConfiguration; // вычисляем dn, для update'а находим по uid string dn = ""; if (uid != null) { DirectoryEntry entry = new DirectoryEntry(ActiveDirectoryUtils.GetLDAPPath(config.LDAPHostName, uid.GetUidValue()), config.DirectoryAdminName, config.DirectoryAdminPassword); dn = (string)entry.Properties["distinguishedName"][0]; entry.Dispose(); } else { dn = GetAttribute(attributes, "__NAME__").Value.First().ToString(); } string parentDn = ActiveDirectoryUtils.GetParentDn(dn); string ldapContainerPath = ActiveDirectoryUtils.GetLDAPPath(config.LDAPHostName, parentDn); container = new DirectoryEntry(ldapContainerPath, config.DirectoryAdminName, config.DirectoryAdminPassword); // поиск значения Database в родительских OU string defaultHomeMdb = null; while (defaultHomeMdb == null && container != null) { LOG.Info("Looking for DefaultHomeMdb in {0}", container.Path); defaultHomeMdb = GetDefaultHomeMdb(container); if (defaultHomeMdb != null) { LOG.Info("Found! DefaultHomeMdb = {0} (in container {1})", defaultHomeMdb, container.Path); } else { LOG.Info("Did not found DefaultHomeMdb in container {0}", container.Path); } try { container = container.Parent; } catch (Exception e) { LOG.Info("Error: " + e.Message); container = null; } } // установка значения атрибута, если не нашли указываем значение по умолчанию if (defaultHomeMdb != null) { LOG.Info("Setting DefaultHomeMdb: " + defaultHomeMdb); AddOrReplaceAttribute(attributes, "Database", defaultHomeMdb); } else { LOG.Info("Did not found DefaultHomeMdb, will set default value"); AddOrReplaceAttribute(attributes, "Database", "MSK-RN-DAG01-1GB-02"); } } finally { if (container != null) { container.Dispose(); } } }
// implementation of DeleteSpiOp public virtual void Delete(ObjectClass objectClass, Uid uid, OperationOptions options) { Trace.TraceInformation("Invoke Delete ObjectClass:{0}/{1}", objectClass.GetObjectClassValue(), uid.GetUidValue()); try { ExecuteDelete(_configuration.DeleteScriptFileName, objectClass, uid, options); Trace.TraceInformation("Delete ok"); } catch (Exception e) { if (e.InnerException != null) { throw e.InnerException; } throw; } }
public Uid Update(ObjectClass objectClass, Uid uid, ICollection <ConnectorAttribute> valuesToReplace, OperationOptions options) { Trace.TraceInformation("Invoke Update ObjectClass: {0}/{1}", objectClass.GetObjectClassValue(), uid.GetUidValue()); try { Uid uidAfter = ExecuteUpdate(_configuration.UpdateScriptFileName, objectClass, uid, valuesToReplace, options); if (uidAfter == null) { throw new ConnectorException("Update script didn't return with a valid uid (__UID__) value"); } Trace.TraceInformation("{0}:{1} updated", objectClass.GetObjectClassValue(), uidAfter.GetUidValue()); return(uidAfter); } catch (Exception e) { if (e.InnerException != null) { throw e.InnerException; } throw; } }
/// <summary> /// Creates command based on the commanf info, reading the calues from attributes /// </summary> /// <param name="cmdInfo">Command defition</param> /// <param name="attributes">Attribute values - UID in these is ignored! It should be passed as a separate parameter</param> /// <param name="config">Configuration object</param> /// <returns> /// Ready to execute Command /// </returns> /// <exception cref="ArgumentNullException">if some of the param is null</exception> internal static Command GetCommand(PSExchangeConnector.CommandInfo cmdInfo, ICollection <ConnectorAttribute> attributes, Uid uidAttribute, Name nameAttribute, ExchangeConfiguration config) { Assertions.NullCheck(cmdInfo, "cmdInfo"); LOG.Trace("GetCommand: cmdInfo name = {0}", cmdInfo.Name); ISet <string> parametersSet = new HashSet <string>(); // create command Command cmd = new Command(cmdInfo.Name); if (!string.IsNullOrEmpty(cmdInfo.UidParameter) && !parametersSet.Contains(cmdInfo.UidParameter)) { Uid uidAttr = uidAttribute != null ? uidAttribute : ConnectorAttributeUtil.GetUidAttribute(attributes); string uid = uidAttr != null?uidAttr.GetUidValue() : null; if (uid != null) { cmd.Parameters.Add(cmdInfo.UidParameter, ActiveDirectoryUtils.ConvertADGUIDtoObjectGUID(uid)); parametersSet.Add(cmdInfo.UidParameter); } } // map name attribute, if mapping specified if (!string.IsNullOrEmpty(cmdInfo.NameParameter) && !parametersSet.Contains(cmdInfo.NameParameter)) { Name nameAttr = nameAttribute != null ? nameAttribute : ConnectorAttributeUtil.GetNameFromAttributes(attributes); string name = nameAttr != null?nameAttr.GetNameValue() : null;; if (name != null) { cmd.Parameters.Add(cmdInfo.NameParameter, name); parametersSet.Add(cmdInfo.NameParameter); } } if (cmdInfo.UsesConfirm) { cmd.Parameters.Add("confirm", false); parametersSet.Add("confirm"); } if (cmdInfo.UsesDomainController) { cmd.Parameters.Add("DomainController", ActiveDirectoryUtils.GetDomainControllerName(config)); parametersSet.Add("DomainController"); } // TODO check this only for user-related operations bool emailAddressesPresent = GetAttValues(ExchangeConnectorAttributes.AttEmailAddresses, attributes) != null; bool primarySmtpAddressPresent = GetAttValues(ExchangeConnectorAttributes.AttPrimarySmtpAddress, attributes) != null; if (emailAddressesPresent && primarySmtpAddressPresent) { throw new ArgumentException(ExchangeConnectorAttributes.AttEmailAddresses + " and " + ExchangeConnectorAttributes.AttPrimarySmtpAddress + " cannot be both set."); } if (attributes != null) { foreach (string attName in cmdInfo.Parameters) { object valueToSet = null; ConnectorAttribute attribute = ConnectorAttributeUtil.Find(attName, attributes); if (attribute != null) { if (attribute.Value != null && attribute.Value.Count > 1) { List <string> stringValues = new List <string>(); foreach (object val in attribute.Value) { stringValues.Add(val.ToString()); } valueToSet = stringValues.ToArray(); } else { valueToSet = ConnectorAttributeUtil.GetSingleValue(attribute); } if (parametersSet.Contains(attName)) { throw new InvalidOperationException("Parameter " + attName + " is already defined for command " + cmdInfo.Name); } cmd.Parameters.Add(attName, valueToSet); parametersSet.Add(attName); } } } LOG.Trace("GetCommand exit: cmdInfo name = {0}", cmdInfo.Name); return(cmd); }
/// <summary> /// Implementation of CreateOp.Create /// </summary> /// <param name="oclass">Object class</param>(oc /// <param name="attributes">Object attributes</param> /// <param name="options">Operation options</param> /// <returns>Uid of the created object</returns> public override Uid Create( ObjectClass oclass, ICollection <ConnectorAttribute> attributes, OperationOptions options) { ExchangeUtility.NullCheck(oclass, "oclass", this.configuration); ExchangeUtility.NullCheck(attributes, "attributes", this.configuration); // we handle accounts only if (!oclass.Is(ObjectClass.ACCOUNT_NAME)) { return(base.Create(oclass, attributes, options)); } const string METHOD = "Create"; Debug.WriteLine(METHOD + ":entry", ClassName); // get recipient type string rcptType = ExchangeUtility.GetAttValue(AttRecipientType, attributes) as string; PSExchangeConnector.CommandInfo cmdInfoEnable = null; PSExchangeConnector.CommandInfo cmdInfoSet = null; switch (rcptType) { case RcptTypeMailBox: cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailbox; cmdInfoSet = PSExchangeConnector.CommandInfo.SetMailbox; break; case RcptTypeMailUser: cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailUser; cmdInfoSet = PSExchangeConnector.CommandInfo.SetMailUser; break; case RcptTypeUser: break; default: throw new ArgumentException( this.configuration.ConnectorMessages.Format( "ex_bad_rcpt", "Recipient type [{0}] is not supported", rcptType)); } // first create the object in AD Uid uid = base.Create(oclass, FilterOut(attributes, cmdInfoEnable, cmdInfoSet), options); if (rcptType == RcptTypeUser) { // AD account only, we do nothing return(uid); } // prepare the command Command cmdEnable = ExchangeUtility.GetCommand(cmdInfoEnable, attributes, this.configuration); Command cmdSet = ExchangeUtility.GetCommand(cmdInfoSet, attributes, this.configuration); try { this.InvokePipeline(cmdEnable); this.InvokePipeline(cmdSet); } catch { Trace.TraceWarning("Rolling back AD create for UID: " + uid.GetUidValue()); // rollback AD create try { Delete(oclass, uid, options); } catch { Trace.TraceWarning("Not able to rollback AD create for UID: " + uid.GetUidValue()); // note: this is not perfect, we hide the original exception throw; } // rethrow original exception throw; } Debug.WriteLine(METHOD + ":exit", ClassName); return(uid); }
public void Create(CreateOpContext context) { context.Attributes = DeduplicateEmailAddresses(context, context.Attributes); // get recipient type string rcptType = ExchangeUtility.GetAttValue(ExchangeConnectorAttributes.AttRecipientType, context.Attributes) as string; if (rcptType == null || rcptType.Equals("")) { rcptType = ExchangeConnectorAttributes.RcptTypeUser; } ExchangeConnector exconn = (ExchangeConnector)context.Connector; ActiveDirectoryConnector adconn = exconn.ActiveDirectoryConnector; PSExchangeConnector.CommandInfo cmdInfoEnable = null; PSExchangeConnector.CommandInfo cmdInfoSet = null; switch (rcptType) { case ExchangeConnectorAttributes.RcptTypeMailBox: cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailbox; cmdInfoSet = PSExchangeConnector.CommandInfo.SetMailbox; break; case ExchangeConnectorAttributes.RcptTypeMailUser: cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailUser; cmdInfoSet = PSExchangeConnector.CommandInfo.SetMailUser; break; case ExchangeConnectorAttributes.RcptTypeUser: break; default: throw new ArgumentException( context.ConnectorConfiguration.ConnectorMessages.Format( "ex_bad_rcpt", "Recipient type [{0}] is not supported", rcptType)); } // first create the object in AD ICollection <ConnectorAttribute> adAttributes = ExchangeUtility.FilterOut(context.Attributes, PSExchangeConnector.CommandInfo.EnableMailbox, PSExchangeConnector.CommandInfo.SetMailbox, PSExchangeConnector.CommandInfo.EnableMailUser, PSExchangeConnector.CommandInfo.SetMailUser); Uid uid = adconn.Create(context.ObjectClass, adAttributes, context.Options); if (rcptType == ExchangeConnectorAttributes.RcptTypeUser) { // AD account only, we do nothing context.Uid = uid; return; } // add a empty "EmailAddresses" attribute if needed (address policy is disabled and no addresses are provided) ICollection <ConnectorAttribute> enhancedAttributes; ConnectorAttribute policyEnabledAttribute = ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttEmailAddressPolicyEnabled, context.Attributes); if (policyEnabledAttribute != null && ConnectorAttributeUtil.GetBooleanValue(policyEnabledAttribute).HasValue&& ConnectorAttributeUtil.GetBooleanValue(policyEnabledAttribute).Value == false && ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttPrimarySmtpAddress, context.Attributes) == null && ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttEmailAddresses, context.Attributes) == null) { enhancedAttributes = new HashSet <ConnectorAttribute>(context.Attributes); enhancedAttributes.Add(ConnectorAttributeBuilder.Build(ExchangeConnectorAttributes.AttEmailAddresses)); LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Added empty EmailAddresses attribute because address policy use is disabled and no addresses were provided"); } else { enhancedAttributes = context.Attributes; // no change } // prepare the command Command cmdEnable = ExchangeUtility.GetCommand(cmdInfoEnable, enhancedAttributes, uid, (ExchangeConfiguration)context.ConnectorConfiguration); Command cmdSet = ExchangeUtility.GetCommand(cmdInfoSet, enhancedAttributes, uid, (ExchangeConfiguration)context.ConnectorConfiguration); try { _helper.InvokePipeline(exconn, cmdEnable); _helper.InvokePipeline(exconn, cmdSet); } catch { LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Rolling back AD create for UID: " + uid.GetUidValue()); // rollback AD create try { adconn.Delete(context.ObjectClass, uid, context.Options); } catch { LOGGER.TraceEvent(TraceEventType.Warning, CAT_DEFAULT, "Not able to rollback AD create for UID: " + uid.GetUidValue()); // note: this is not perfect, we hide the original exception throw; } // rethrow original exception throw; } context.Uid = uid; }