-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CommunicationIdentifier] Introduce new rawId and creation of identifer #1255
Changes from all commits
37c84ff
4fb093f
974a42d
d3105c1
1b77645
2709ce7
dc47ec4
fef42ff
dc60280
e85f9e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// -------------------------------------------------------------------------- | ||
// | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// | ||
// The MIT License (MIT) | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the ""Software""), to | ||
// deal in the Software without restriction, including without limitation the | ||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
// sell copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
// IN THE SOFTWARE. | ||
// | ||
// -------------------------------------------------------------------------- | ||
|
||
import Foundation | ||
/** | ||
Helper class to easily create CommunicationIdentifiers | ||
*/ | ||
@objcMembers | ||
public class CommunicationIdentifierHelper: NSObject { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm never a fan of anything that ends in @tjprescott Any suggestions for good Swift-idiomatic naming? Ideally we would have liked a static factory method on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not add a required init to the protocol that takes a rawId and then provide the contents of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But I agree you don't really want this helper thingy as part of the public API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was something I was trying. I initially was thinking something like this
But because the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tjprescott @DominikMe Had a discussion about this implementation. I think in terms of functionality this approah that we have with the helper most closely aligns with the other platforms. |
||
private static let phoneNumberPrefix = "4:" | ||
private static let teamUserAnonymousPrefix = "8:teamsvisitor:" | ||
private static let teamUserPublicCloudPrefix = "8:orgid:" | ||
private static let teamUserDODCloudPrefix = "8:dod:" | ||
private static let teamUserGCCHCloudPrefix = "8:gcch:" | ||
private static let acsUser = "8:acs:" | ||
private static let spoolUser = "8:spool:" | ||
private static let dodAcsUser = "8:dod-acs:" | ||
private static let gcchAcsUser = "8:gcch-acs:" | ||
/** | ||
Creates a CommunicationIdentifier from a given rawId. When storing rawIds use this function to restore the identifier that was encoded in the rawId. | ||
Parameters: rawId The rawId to be translated to its identifier representation. | ||
Returns: Type safe CommunicationIdentifier created. Use the `isKind(of:)` to verify identifier type | ||
SeeAlso: ` CommunicationIdentifier` | ||
*/ | ||
public static func createCommunicationIdentifier(from rawId: String) -> CommunicationIdentifier { | ||
if rawId.hasPrefix(phoneNumberPrefix) { | ||
let phoneNumber = "+" + rawId.dropFirst(phoneNumberPrefix.count) | ||
return PhoneNumberIdentifier(phoneNumber: phoneNumber, rawId: rawId) | ||
} | ||
let segments = rawId.split(separator: ":") | ||
if segments.count < 3 { | ||
return UnknownIdentifier(rawId) | ||
} | ||
let scope = segments[0] + ":" + segments[1] + ":" | ||
let suffix = String(rawId.dropFirst(scope.count)) | ||
switch scope { | ||
case teamUserAnonymousPrefix: | ||
return MicrosoftTeamsUserIdentifier(userId: suffix, isAnonymous: true) | ||
case teamUserPublicCloudPrefix: | ||
return MicrosoftTeamsUserIdentifier( | ||
userId: suffix, | ||
isAnonymous: false, | ||
rawId: rawId, | ||
cloudEnvironment: .Public | ||
) | ||
case teamUserDODCloudPrefix: | ||
return MicrosoftTeamsUserIdentifier( | ||
userId: suffix, | ||
isAnonymous: false, | ||
rawId: rawId, | ||
cloudEnvironment: .Dod | ||
) | ||
case teamUserGCCHCloudPrefix: | ||
return MicrosoftTeamsUserIdentifier( | ||
userId: suffix, | ||
isAnonymous: false, | ||
rawId: rawId, | ||
cloudEnvironment: .Gcch | ||
) | ||
case acsUser, spoolUser, dodAcsUser, gcchAcsUser: | ||
return CommunicationUserIdentifier(rawId) | ||
default: | ||
return UnknownIdentifier(rawId) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,11 +30,15 @@ import Foundation | |
Common Communication Identifier protocol for all Azure Communication Services. | ||
All Communication Identifiers conform to this protocol. | ||
*/ | ||
@objc public protocol CommunicationIdentifier: NSObjectProtocol {} | ||
@objc public protocol CommunicationIdentifier: NSObjectProtocol { | ||
var rawId: String { get } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to require: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another suggestion that was brought up by @tjprescott that I really like is including a new enum or string to represent the |
||
} | ||
|
||
/** | ||
Communication identifier for Communication Services Users | ||
*/ | ||
@objcMembers public class CommunicationUserIdentifier: NSObject, CommunicationIdentifier { | ||
public var rawId: String { return identifier } | ||
public let identifier: String | ||
/** | ||
Creates a CommunicationUserIdentifier object | ||
|
@@ -50,6 +54,7 @@ import Foundation | |
Catch-all for all other Communication identifiers for Communication Services | ||
*/ | ||
@objcMembers public class UnknownIdentifier: NSObject, CommunicationIdentifier { | ||
public var rawId: String { return identifier } | ||
public let identifier: String | ||
/** | ||
Creates a UnknownIdentifier object | ||
|
@@ -66,7 +71,7 @@ import Foundation | |
*/ | ||
@objcMembers public class PhoneNumberIdentifier: NSObject, CommunicationIdentifier { | ||
public let phoneNumber: String | ||
public let rawId: String? | ||
public private(set) var rawId: String | ||
|
||
/** | ||
Creates a PhoneNumberIdentifier object | ||
|
@@ -75,17 +80,36 @@ import Foundation | |
*/ | ||
public init(phoneNumber: String, rawId: String? = nil) { | ||
self.phoneNumber = phoneNumber | ||
self.rawId = rawId | ||
if let rawId = rawId { | ||
self.rawId = rawId | ||
} else { | ||
let strippedPhoneNumber = phoneNumber.replacingOccurrences(of: "+", with: "") | ||
self.rawId = "4:" + strippedPhoneNumber | ||
} | ||
JoshuaLai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
Returns a Boolean value indicating whether two values are equal. | ||
Note: In Objective-C favor isEqual() method | ||
- Parameter lhs PhoneNumberIdentifier to compare. | ||
- Parameter rhs Another PhoneNumberIdentifier to compare. | ||
*/ | ||
// swiftlint:disable nsobject_prefer_isequal | ||
public static func == (lhs: PhoneNumberIdentifier, rhs: PhoneNumberIdentifier) -> Bool { | ||
if lhs.phoneNumber != rhs.phoneNumber { | ||
return lhs.rawId == rhs.rawId | ||
JoshuaLai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
Returns a Boolean value that indicates whether the receiver is equal to another given object. | ||
This will automatically return false if object being compared to is not a PhoneNumberIdentifier. | ||
- Parameter object The object with which to compare the receiver. | ||
*/ | ||
override public func isEqual(_ object: Any?) -> Bool { | ||
guard let object = object as? PhoneNumberIdentifier else { | ||
return false | ||
} | ||
|
||
return lhs.rawId == nil | ||
|| rhs.rawId == nil | ||
|| lhs.rawId == rhs.rawId | ||
return rawId == object.rawId | ||
} | ||
} | ||
|
||
|
@@ -95,7 +119,7 @@ import Foundation | |
@objcMembers public class MicrosoftTeamsUserIdentifier: NSObject, CommunicationIdentifier { | ||
public let userId: String | ||
public let isAnonymous: Bool | ||
public let rawId: String? | ||
public private(set) var rawId: String | ||
public let cloudEnviroment: CommunicationCloudEnvironment | ||
|
||
/** | ||
|
@@ -114,31 +138,62 @@ import Foundation | |
rawId: String? = nil, | ||
cloudEnvironment: CommunicationCloudEnvironment = .Public | ||
) { | ||
self.rawId = rawId | ||
JoshuaLai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.userId = userId | ||
self.isAnonymous = isAnonymous | ||
self.cloudEnviroment = cloudEnvironment | ||
|
||
if let rawId = rawId { | ||
self.rawId = rawId | ||
} else { | ||
if isAnonymous { | ||
self.rawId = "8:teamsvisitor:" + userId | ||
} else { | ||
switch cloudEnvironment { | ||
case .Dod: | ||
self.rawId = "8:dod:" + userId | ||
case .Gcch: | ||
self.rawId = "8:gcch:" + userId | ||
case .Public: | ||
self.rawId = "8:orgid:" + userId | ||
default: | ||
self.rawId = "8:orgid:" + userId | ||
} | ||
} | ||
} | ||
} | ||
|
||
public init(userId: String, isAnonymous: Bool) { | ||
self.cloudEnviroment = .Public | ||
self.rawId = nil | ||
self.userId = userId | ||
self.isAnonymous = isAnonymous | ||
/** | ||
Creates a MicrosoftTeamsUserIdentifier object. cloudEnvironment is defaulted to Public cloud. | ||
- Parameter userId: Id of the Microsoft Teams user. If the user isn't anonymous, | ||
the id is the AAD object id of the user. | ||
- Parameter isAnonymous: Set this to true if the user is anonymous: | ||
for example when joining a meeting with a share link. | ||
*/ | ||
convenience init(userId: String, isAnonymous: Bool) { | ||
self.init(userId: userId, isAnonymous: isAnonymous, rawId: nil, cloudEnvironment: .Public) | ||
} | ||
|
||
/** | ||
Returns a Boolean value indicating whether two values are equal. | ||
Note: In Objective-C favor isEqual() method | ||
- Parameter lhs MicrosoftTeamsUserIdentifier to compare. | ||
- Parameter rhs Another MicrosoftTeamsUserIdentifier to compare. | ||
*/ | ||
// swiftlint:disable nsobject_prefer_isequal | ||
public static func == (lhs: MicrosoftTeamsUserIdentifier, rhs: MicrosoftTeamsUserIdentifier) -> Bool { | ||
if lhs.userId != rhs.userId || | ||
lhs.isAnonymous != rhs.isAnonymous { | ||
return false | ||
} | ||
return lhs.rawId == rhs.rawId | ||
} | ||
|
||
if lhs.cloudEnviroment != rhs.cloudEnviroment { | ||
/** | ||
Returns a Boolean value that indicates whether the receiver is equal to another given object. | ||
This will automatically return false if object being compared to is not a MicrosoftTeamsUserIdentifier. | ||
- Parameter object The object with which to compare the receiver. | ||
*/ | ||
override public func isEqual(_ object: Any?) -> Bool { | ||
guard let object = object as? MicrosoftTeamsUserIdentifier else { | ||
return false | ||
} | ||
|
||
return lhs.rawId == nil | ||
|| rhs.rawId == nil | ||
|| lhs.rawId == rhs.rawId | ||
return rawId == object.rawId | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to have a more detailed explanation of the change, similar to https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/communication/communication-common/CHANGELOG.md#features-added