Skip to content
This repository was archived by the owner on Jul 30, 2019. It is now read-only.

Commit 3a07553

Browse files
Laszlo HordosLaszlo Hordos
Laszlo Hordos
authored and
Laszlo Hordos
committedMay 1, 2014
CR-3457 / OPENICF-223 - The C# delegate type is not compatible with Java and it does not work in PowerShell Runspace
CR-3457 / OPENICF-224 - The SyncDelta can not hold the ObjectClass of deleted object for Sync operation with ObjectClass.ALL
1 parent 3c0bd47 commit 3a07553

File tree

8 files changed

+599
-466
lines changed

8 files changed

+599
-466
lines changed
 

‎Common/Security.cs

+71-25
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,39 @@ public interface UnmanagedArray<T> : IDisposable
7474
/// </remarks>
7575
public sealed class GuardedByteArray : IDisposable
7676
{
77+
7778
/// <summary>
78-
/// This method will be called with the clear text of the byte array.
79+
/// Callback interface for those times that it is necessary to access the
80+
/// clear text of the guarded bytes.
7981
/// </summary>
80-
/// <remarks>
81-
/// After the call the clearBytes array will be automatically zeroed
82-
/// out, thus keeping the window of potential exposure to a bare-minimum.
83-
/// </remarks>
84-
/// <param name="clearChars"></param>
85-
public delegate void Accessor(UnmanagedArray<byte> clearBytes);
82+
public interface Accessor
83+
{
84+
85+
/// <summary>
86+
/// This method will be called with the clear text of the byte array.
87+
/// </summary>
88+
/// <remarks>
89+
/// After the call the clearBytes array will be automatically zeroed
90+
/// out, thus keeping the window of potential exposure to a bare-minimum.
91+
/// </remarks>
92+
/// <param name="clearBytes"></param>
93+
void Access(UnmanagedArray<byte> clearBytes);
94+
}
95+
96+
public class LambdaAccessor : Accessor
97+
{
98+
private readonly Action<UnmanagedArray<byte>> _accessor;
99+
100+
public LambdaAccessor(Action<UnmanagedArray<byte>> accessor)
101+
{
102+
_accessor = accessor;
103+
}
86104

105+
public void Access(UnmanagedArray<byte> clearBytes)
106+
{
107+
_accessor(clearBytes);
108+
}
109+
}
87110

88111
private SecureString _target;
89112
private String _base64SHA1Hash;
@@ -128,7 +151,7 @@ public void Access(Accessor accessor)
128151
{
129152
using (SecureStringToByteArrayAdapter adapter = new SecureStringToByteArrayAdapter(_target))
130153
{
131-
accessor(adapter);
154+
accessor.Access(adapter);
132155
}
133156
}
134157

@@ -140,7 +163,7 @@ public void Access(Accessor accessor)
140163
/// appended, and then it will be re-encrypted.
141164
/// </remarks>
142165
/// <param name="b">The byte to append.</param>
143-
/// <exception cref="IllegalStateException">If the byte array is read-only</exception>
166+
/// <exception cref="InvalidOperationException">If the byte array is read-only</exception>
144167
/// <exception cref="IllegalStateException">If the byte array has been disposed</exception>
145168
public void AppendByte(byte b)
146169
{
@@ -251,10 +274,10 @@ public override int GetHashCode()
251274

252275
private void ComputeHash()
253276
{
254-
Access(array =>
277+
Access(new LambdaAccessor(array =>
255278
{
256279
_base64SHA1Hash = SecurityUtil.ComputeBase64SHA1Hash(array);
257-
});
280+
}));
258281
}
259282

260283
}
@@ -292,16 +315,39 @@ private void ComputeHash()
292315
/// </remarks>
293316
public sealed class GuardedString : IDisposable
294317
{
318+
295319
/// <summary>
296-
/// This method will be called with the clear text of the string.
320+
/// Callback interface for those times that it is necessary to access the
321+
/// clear text of the secure string.
297322
/// </summary>
298-
/// <remarks>
299-
/// After the call the clearChars array will be automatically zeroed
300-
/// out, thus keeping the window of potential exposure to a bare-minimum.
301-
/// </remarks>
302-
/// <param name="clearChars"></param>
303-
public delegate void Accessor(UnmanagedArray<char> clearChars);
323+
public interface Accessor
324+
{
325+
326+
/// <summary>
327+
/// This method will be called with the clear text of the string.
328+
/// </summary>
329+
/// <remarks>
330+
/// After the call the clearChars array will be automatically zeroed
331+
/// out, thus keeping the window of potential exposure to a bare-minimum.
332+
/// </remarks>
333+
/// <param name="clearChars"></param>
334+
void Access(UnmanagedArray<char> clearChars);
335+
}
336+
337+
public class LambdaAccessor : Accessor
338+
{
339+
private readonly Action<UnmanagedArray<char>> _accessor;
340+
341+
public LambdaAccessor(Action<UnmanagedArray<char>> accessor)
342+
{
343+
_accessor = accessor;
344+
}
304345

346+
public void Access(UnmanagedArray<char> clearBytes)
347+
{
348+
_accessor(clearBytes);
349+
}
350+
}
305351

306352
private SecureString _target;
307353
private String _base64SHA1Hash;
@@ -340,7 +386,7 @@ public void Access(Accessor accessor)
340386
{
341387
using (SecureStringAdapter adapter = new SecureStringAdapter(_target))
342388
{
343-
accessor(adapter);
389+
accessor.Access(adapter);
344390
}
345391
}
346392

@@ -459,10 +505,10 @@ public SecureString ToSecureString()
459505

460506
private void ComputeHash()
461507
{
462-
Access(array =>
508+
Access(new LambdaAccessor(array =>
463509
{
464510
_base64SHA1Hash = SecurityUtil.ComputeBase64SHA1Hash(array);
465-
});
511+
}));
466512
}
467513

468514
}
@@ -827,14 +873,14 @@ public static bool VerifyBase64SHA1Hash(UnmanagedArray<char> input, string hash)
827873
public static string Decrypt(GuardedString guardedString)
828874
{
829875
StringBuilder buf = new StringBuilder();
830-
guardedString.Access(
876+
guardedString.Access(new GuardedString.LambdaAccessor(
831877
array =>
832878
{
833879
for (int i = 0; i < array.Length; i++)
834880
{
835881
buf.Append(array[i]);
836882
}
837-
});
883+
}));
838884
return buf.ToString();
839885
}
840886

@@ -848,15 +894,15 @@ public static string Decrypt(GuardedString guardedString)
848894
public static byte[] Decrypt(GuardedByteArray guardedByteArray)
849895
{
850896
byte[] result = null;
851-
guardedByteArray.Access(
897+
guardedByteArray.Access(new GuardedByteArray.LambdaAccessor(
852898
array =>
853899
{
854900
result = new byte[array.Length];
855901
for (int i = 0; i < array.Length; i++)
856902
{
857903
result[i] = array[i];
858904
}
859-
});
905+
}));
860906
return result;
861907
}
862908
}

‎Framework/CommonObjects.cs

+76-6
Original file line numberDiff line numberDiff line change
@@ -4662,6 +4662,7 @@ public sealed class SyncDelta
46624662
private readonly SyncToken _token;
46634663
private readonly SyncDeltaType _deltaType;
46644664
private readonly Uid _previousUid;
4665+
private readonly ObjectClass _objectClass;
46654666
private readonly Uid _uid;
46664667
private readonly ConnectorObject _object;
46674668

@@ -4670,20 +4671,22 @@ public sealed class SyncDelta
46704671
/// </summary>
46714672
/// <param name="token">The token. Must not be null.</param>
46724673
/// <param name="deltaType">The delta. Must not be null.</param>
4674+
/// <param name="previousUid">The previousUid. Can be null.</param>
4675+
/// <param name="objectClass">The objectClass. Can be null.</param>
46734676
/// <param name="uid">The uid. Must not be null.</param>
4674-
/// <param name="object">The object that has changed. May be null for delete.</param>
4677+
/// <param name="obj">The object that has changed. May be null for delete.</param>
46754678
internal SyncDelta(SyncToken token, SyncDeltaType deltaType,
4676-
Uid previousUid, Uid uid,
4679+
Uid previousUid, ObjectClass objectClass, Uid uid,
46774680
ConnectorObject obj)
46784681
{
46794682
Assertions.NullCheck(token, "token");
46804683
Assertions.NullCheck(deltaType, "deltaType");
46814684
Assertions.NullCheck(uid, "uid");
46824685

46834686
//do not allow previous Uid for anything else than create or update
4684-
if (previousUid != null && deltaType == SyncDeltaType.DELETE)
4687+
if (previousUid != null && (deltaType == SyncDeltaType.DELETE || deltaType == SyncDeltaType.CREATE))
46854688
{
4686-
throw new ArgumentException("The previous Uid can only be specified for create or update.");
4689+
throw new ArgumentException("The previous Uid can only be specified for create_or_update or udate.");
46874690
}
46884691

46894692
//only allow null object for delete
@@ -4701,11 +4704,16 @@ internal SyncDelta(SyncToken token, SyncDeltaType deltaType,
47014704
{
47024705
throw new ArgumentException("Uid does not match that of the object.");
47034706
}
4707+
if (!objectClass.Equals(obj.ObjectClass))
4708+
{
4709+
throw new ArgumentException("ObjectClass does not match that of the object.");
4710+
}
47044711
}
47054712

47064713
_token = token;
47074714
_deltaType = deltaType;
47084715
_previousUid = previousUid;
4716+
_objectClass = objectClass;
47094717
_uid = uid;
47104718
_object = obj;
47114719

@@ -4730,6 +4738,22 @@ public Uid PreviousUid
47304738
}
47314739
}
47324740

4741+
/// <summary>
4742+
/// If the change described by this <code>SyncDelta.DELETE</code> and the
4743+
/// deleted object value is <code>null</code>, this method returns the
4744+
/// ObjectClass of the deleted object. If operation syncs
4745+
/// <seealso cref="Org.IdentityConnectors.Framework.Common.Objects.ObjectClass#ALL"/>
4746+
/// this must be set, otherwise this method can return <code>null</code>.
4747+
/// </summary>
4748+
/// <returns> the ObjectClass of the deleted object. </returns>
4749+
public ObjectClass ObjectClass
4750+
{
4751+
get
4752+
{
4753+
return _objectClass;
4754+
}
4755+
}
4756+
47334757
/// <summary>
47344758
/// Returns the <code>Uid</code> of the object that changed.
47354759
/// </summary>
@@ -4790,14 +4814,29 @@ public override String ToString()
47904814
values["Token"] = _token;
47914815
values["DeltaType"] = _deltaType;
47924816
values["PreviousUid"] = _previousUid;
4817+
values["ObjectClass"] = _objectClass;
47934818
values["Uid"] = _uid;
47944819
values["Object"] = _object;
47954820
return values.ToString();
47964821
}
47974822

47984823
public override int GetHashCode()
47994824
{
4800-
return _uid.GetHashCode();
4825+
unchecked
4826+
{
4827+
int hashCode = (_token != null ? _token.GetHashCode() : 0);
4828+
hashCode = (hashCode * 397) ^ (int)_deltaType;
4829+
hashCode = (hashCode * 397) ^ (_previousUid != null ? _previousUid.GetHashCode() : 0);
4830+
hashCode = (hashCode * 397) ^ (_objectClass != null ? _objectClass.GetHashCode() : 0);
4831+
hashCode = (hashCode * 397) ^ (_uid != null ? _uid.GetHashCode() : 0);
4832+
hashCode = (hashCode * 397) ^ (_object != null ? _object.GetHashCode() : 0);
4833+
return hashCode;
4834+
}
4835+
}
4836+
4837+
private bool Equals(SyncDelta other)
4838+
{
4839+
return Equals(_token, other._token) && _deltaType == other._deltaType && Equals(_previousUid, other._previousUid) && Equals(_objectClass, other._objectClass) && Equals(_uid, other._uid) && Equals(_object, other._object);
48014840
}
48024841

48034842
public override bool Equals(Object o)
@@ -4824,6 +4863,17 @@ public override bool Equals(Object o)
48244863
{
48254864
return false;
48264865
}
4866+
if (_objectClass == null)
4867+
{
4868+
if (other._objectClass != null)
4869+
{
4870+
return false;
4871+
}
4872+
}
4873+
else if (!_objectClass.Equals(other._objectClass))
4874+
{
4875+
return false;
4876+
}
48274877
if (!_uid.Equals(other._uid))
48284878
{
48294879
return false;
@@ -4855,6 +4905,7 @@ public sealed class SyncDeltaBuilder
48554905
private SyncToken _token;
48564906
private SyncDeltaType _deltaType;
48574907
private Uid _previousUid;
4908+
private ObjectClass _objectClass;
48584909
private Uid _uid;
48594910
private ConnectorObject _object;
48604911

@@ -4876,6 +4927,7 @@ public SyncDeltaBuilder(SyncDelta delta)
48764927
_token = delta.Token;
48774928
_deltaType = delta.DeltaType;
48784929
_previousUid = delta.PreviousUid;
4930+
_objectClass = delta.ObjectClass;
48794931
_uid = delta.Uid;
48804932
_object = delta.Object;
48814933
}
@@ -4928,6 +4980,23 @@ public Uid PreviousUid
49284980
}
49294981
}
49304982

4983+
/// <summary>
4984+
/// Returns the <code>ObjectClass</code> of Deleted object.
4985+
/// </summary>
4986+
/// <returns>the <code>ObjectClass</code> of Deleted object.</returns>
4987+
public ObjectClass ObjectClass
4988+
{
4989+
get
4990+
{
4991+
return _objectClass;
4992+
}
4993+
set
4994+
{
4995+
_objectClass = value;
4996+
}
4997+
}
4998+
4999+
49315000
/// <summary>
49325001
/// Returns the <code>Uid</code> of the object that changed.
49335002
/// </summary>
@@ -4969,6 +5038,7 @@ public ConnectorObject Object
49695038
if (value != null)
49705039
{
49715040
_uid = value.Uid;
5041+
_objectClass = value.ObjectClass;
49725042
}
49735043
}
49745044
}
@@ -4999,7 +5069,7 @@ public ConnectorObject Object
49995069
/// </remarks>
50005070
public SyncDelta Build()
50015071
{
5002-
return new SyncDelta(_token, _deltaType, _previousUid, _uid, _object);
5072+
return new SyncDelta(_token, _deltaType, _previousUid, _objectClass, _uid, _object);
50035073
}
50045074
}
50055075
#endregion

0 commit comments

Comments
 (0)
This repository has been archived.