Skip to content

Commit

Permalink
Merge pull request #65 from ibm-cloud-security/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
odedBetzalel committed Feb 23, 2017
2 parents faf224f + c3821b5 commit 453d11b
Show file tree
Hide file tree
Showing 21 changed files with 150 additions and 33 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.4.0
6 changes: 6 additions & 0 deletions .slather.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage_service: coveralls
workspace: BluemixAppID
xcodeproj: BluemixAppID.xcodeproj
scheme: BluemixAppIDTests
ignore:
- BluemixAppIDTests/*
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ matrix:
- osx_image: xcode8.1
install:
- gem install jazzy
- gem install slather
before_script:
- rm -rf ~/Library/Developer/Xcode/DerivedData
script:
# Test that the framework can be installed and built, and passes all unit tests
- travis_wait pod update
- pod lib lint --allow-warnings
- xcodebuild -workspace 'BluemixAppID.xcworkspace' -scheme 'BluemixAppID' clean build CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO
- xcodebuild -workspace 'BluemixAppID.xcworkspace' -list
- travis_retry xcodebuild -workspace 'BluemixAppID.xcworkspace' test -scheme 'BluemixAppIDTests' -destination 'platform=iOS Simulator,name=iPhone 6' CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
- travis_retry xcodebuild -workspace 'BluemixAppID.xcworkspace' test -scheme 'BluemixAppIDTests' -destination 'platform=iOS Simulator,name=iPhone 6' CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -enableCodeCoverage YES
- slather coverage --coveralls --binary-basename BluemixAppID.framework -v
# When merging or pushing to the master branch, release a new version and publish the API documentation
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ] ; then
bash scripts/release.sh;
Expand Down
2 changes: 1 addition & 1 deletion BluemixAppID.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "BluemixAppID"
s.version = '0.0.2'
s.version = '0.0.3'
s.summary = "AppID Swift SDK"
s.homepage = "https://github.com/ibm-bluemix-mobile-services/appid-clientsdk-swift"
s.license = 'Apache License, Version 2.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
Expand Down
2 changes: 1 addition & 1 deletion BluemixAppIDTests/AuthorizationUIManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class AuthorizationUIManagerTests: XCTestCase {
self.exp = exp
super.init(oAuthManager: oAuthManager)
}

override func obtainTokens(code:String, authorizationDelegate:AuthorizationDelegate) {
self.exp.fulfill()
}
Expand Down
5 changes: 1 addition & 4 deletions BluemixAppIDTests/SecurityUtilsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ class SecurityUtilsTest: XCTestCase {
var keySize = 512
var publicKeyTag = AppIDConstants.publicKeyIdentifier
var privateKeyTag = AppIDConstants.privateKeyIdentifier





override func setUp() {
super.setUp()
TestHelpers.clearDictValuesFromKeyChain([publicKeyTag : kSecClassKey, privateKeyTag : kSecClassKey])
Expand Down
4 changes: 2 additions & 2 deletions BluemixAppIDTests/TokenTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class TokenTests: XCTestCase {
XCTAssertEqual(token?.audience, "26cb012eb327c612d90a6819163b6bcbd4849cbb")
XCTAssertTrue(token?.issuedAt == Date(timeIntervalSince1970: 1487081278 as Double))
XCTAssertEqual(token?.tenant, "4dba9430-54e6-4cf2-a516-6f73feb702bb")
XCTAssertEqual(token?.authBy, "facebook")
XCTAssertEqual(token?.authenticationMethods?[0], nil)
XCTAssertTrue(token!.isExpired)
XCTAssertTrue(token?.expiration == Date(timeIntervalSince1970: 1487084878 as Double))

Expand All @@ -55,7 +55,7 @@ class TokenTests: XCTestCase {
XCTAssertEqual(token?.audience, "26cb012eb327c612d90a6819163b6bcbd4849cbb")
XCTAssertTrue(token?.issuedAt == Date(timeIntervalSince1970: 1487081278 as Double))
XCTAssertEqual(token?.tenant, "4dba9430-54e6-4cf2-a516-6f73feb702bb")
XCTAssertEqual(token?.authBy, "facebook")
XCTAssertEqual(token?.authenticationMethods?[0], nil)
XCTAssertTrue(token!.isExpired)
XCTAssertTrue(token?.expiration == Date(timeIntervalSince1970: 1487084878 as Double))

Expand Down
1 change: 1 addition & 0 deletions BluemixAppIDTests/UtilsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class UtilsTest: XCTestCase {
XCTAssertNotNil(appInfo.name)
XCTAssertNotNil(appInfo.version)
}

// func testGetDeviceDictionary() {
// let deviceIdentity = AppIDDeviceIdentity()
// let appIdentity = AppIDAppIdentity()
Expand Down
4 changes: 2 additions & 2 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use_frameworks!

target ‘BluemixAppID' do
platform :ios, '9.0'
pod ‘BMSCore’
pod ‘BMSCore’, '~> 2.3.1
end

target 'BluemixAppIDTests' do
platform :ios, '9.0'
pod ‘BMSCore’
pod ‘BMSCore’, '~> 2.3.1
end

110 changes: 109 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,109 @@
# appid-clientsdk-swift
# Bluemix AppID
Swift SDK for the Bluemix AppID service

[![Bluemix powered][img-bluemix-powered]][url-bluemix]
[![Travis][img-travis-master]][url-travis-master]
[![Coveralls][img-coveralls-master]][url-coveralls-master]
[![Codacy][img-codacy]][url-codacy]
[![Version][img-version]][url-bintray]
[![License][img-license]][url-bintray]

[![GithubWatch][img-github-watchers]][url-github-watchers]
[![GithubStars][img-github-stars]][url-github-stars]
[![GithubForks][img-github-forks]][url-github-forks]

## Requirements
Xcode 8.1 or above, CocoaPods 1.1.0 or higher, MacOS 10.11.5 or higher, iOS 9 or higher.

## Installing the SDK:

1. Add the 'BluemixAppID' dependency to your Podfile, for example:

```swift
target <yourTarget> do
use_frameworks!
pod 'BluemixAppID'
end
```
2. From the terminal, run:
```swift
pod install --repo-update
```

## Using the SDK:

### Initializing the AppId client SDK
1. Open your Xcode project and enable Keychain Sharing (Under project settings --> Capabilities --> Keychain sharing)
2. Under project setting --> info --> Url Types, Add $(PRODUCT_BUNDLE_IDENTIFIER) as a URL Scheme
3. Initialize the client SDK by passing the tenantId and region parameters to the initialize method. A common, though not mandatory, place to put the initialization code is in the application:didFinishLaunchingWithOptions: method of the AppDelegate in your Swift application.
```swift
AppID.sharedInstance.initialize(tenantId: <tenantId>, bluemixRegion: AppID.<region>)
```
4. Add the following code to you AppDelegate file
```swift
func application(_ application: UIApplication, open url: URL, options :[UIApplicationOpenURLOptionsKey : Any]) -> Bool {
return AppID.sharedInstance.application(application, open: url, options: options)
}
```
* Replace ״tenantId״ with the App ID service tenantId.
* Replace ״region״ with the App ID region.

For more information on obtaining these values see Before you begin.

### Using Login Widget
After the App ID client SDK is initialized, you can start authenticate users by launching the Login Widget.
```swift
class delegate : AuthorizationDelegate {
public func onAuthorizationSuccess(accessToken: AccessToken, identityToken: IdentityToken, response:Response?) {
//User authenticated
}

public func onAuthorizationCanceled() {
//Authentication canceled by the user
}

public func onAuthorizationFailure(error: AuthorizationError) {
//Exception occurred
}
}

AppID.sharedInstance.loginWidget?.launch(delegate: delegate())
```
**Note**: The Login widget default configuration use Facebook and Google as authentication options.
If you configure only one of them the login widget will NOT launch and the user will be redirect to the configured idp authentication screen.

### Invoking protected resources

```swift
BMSClient.sharedInstance.initialize(bluemixRegion: AppID.<region>)
BMSClient.sharedInstance.authorizationManager = AppIDAuthorizationManager(appid:AppID.sharedInstance)
var request:Request = Request(url: "<your protected resource url>")
r.send(completionHandler: {(response:Response?, error:Error?) in
//code handling the response here
})
```

### License
This package contains code licensed under the Apache License, Version 2.0 (the "License"). You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 and may also view the License in the LICENSE file within this package.

[img-bluemix-powered]: https://img.shields.io/badge/bluemix-powered-blue.svg
[url-bluemix]: http://bluemix.net
[url-bintray]: https://bintray.com/ibmcloudsecurity/appid-clientsdk-swift
[img-license]: https://img.shields.io/github/license/ibm-cloud-security/appid-clientsdk-swift.svg
[img-version]: https://img.shields.io/bintray/v/ibmcloudsecurity/maven/appid-clientsdk-swift.svg

[img-github-watchers]: https://img.shields.io/github/watchers/ibm-cloud-security/appid-clientsdk-swift.svg?style=social&label=Watch
[url-github-watchers]: https://github.com/ibm-cloud-security/appid-clientsdk-swift/watchers
[img-github-stars]: https://img.shields.io/github/stars/ibm-cloud-security/appid-clientsdk-swift.svg?style=social&label=Star
[url-github-stars]: https://github.com/ibm-cloud-security/appid-clientsdk-swift/stargazers
[img-github-forks]: https://img.shields.io/github/forks/ibm-cloud-security/appid-clientsdk-swift.svg?style=social&label=Fork
[url-github-forks]: https://github.com/ibm-cloud-security/appid-clientsdk-swift/network

[img-travis-master]: https://travis-ci.org/ibm-cloud-security/appid-clientsdk-swift.svg
[url-travis-master]: https://travis-ci.org/ibm-cloud-security/appid-clientsdk-swift

[img-coveralls-master]: https://coveralls.io/repos/github/ibm-cloud-security/appid-clientsdk-swift/badge.svg
[url-coveralls-master]: https://coveralls.io/github/ibm-cloud-security/appid-clientsdk-swift

[img-codacy]: https://api.codacy.com/project/badge/Grade/d41f8f069dd343769fcbdb55089561fc?branch=master
[url-codacy]: https://www.codacy.com/app/ibm-cloud-security/appid-clientsdk-swift
4 changes: 4 additions & 0 deletions Source/BluemixAppID/api/AppID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public class AppID {
public static var sharedInstance = AppID()
internal static let logger = Logger.logger(name: AppIDConstants.AppIDLoggerName)

static public let REGION_US_SOUTH = ".ng.bluemix.net"
static public let REGION_UK = ".eu-gb.bluemix.net"
static public let REGION_SYDNEY = ".au-syd.bluemix.net"

internal init() {}


Expand Down
8 changes: 3 additions & 5 deletions Source/BluemixAppID/api/AppIDAuthorizationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ public class AppIDAuthorizationManager: BMSCore.AuthorizationManager {

internal var oAuthManager:OAuthManager
private static let logger = Logger.logger(name: Logger.bmsLoggerPrefix + "AppIDAuthorizationManager")



public init(appid:AppID) {
self.oAuthManager = appid.oauthManager!
}
Expand Down Expand Up @@ -112,10 +111,9 @@ public class AppIDAuthorizationManager: BMSCore.AuthorizationManager {
public var userIdentity:UserIdentity? {
let idToken = self.identityToken
let identity:[String:Any] = [
BaseUserIdentity.Key.authorizedBy : idToken?.authBy ?? "",
BaseUserIdentity.Key.authorizedBy : idToken?.authenticationMethods ?? "",
BaseUserIdentity.Key.displayName : idToken?.name ?? "",
// TODO: what should be this value? - not implemted in android
BaseUserIdentity.Key.ID : idToken?.name ?? ""
BaseUserIdentity.Key.ID : idToken?.subject ?? ""
]
return BaseUserIdentity(map: identity)

Expand Down
2 changes: 1 addition & 1 deletion Source/BluemixAppID/api/UserAttributeDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public protocol UserAttributeDelegate {

func onSuccess(var1: [String:Any])
func onFailure(var1: UserAttributeError)

}
4 changes: 2 additions & 2 deletions Source/BluemixAppID/internal/AppIDConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ internal class AppIDConstants {
internal static var OPEN_ID_VALUE = "openid"
internal static var TRUE_VALUE = "true"

//label names
// label names
internal static let KEY_CHAIN_PREFIX = "com.ibm.mobilefirstplatform.clientsdk.swift.bmssecurity"
internal static let OAUTH_CERT_LABEL = "\(KEY_CHAIN_PREFIX).certificate"
internal static let _PUBLIC_KEY_LABEL = "\(KEY_CHAIN_PREFIX).publickey"
Expand All @@ -176,7 +176,7 @@ internal class AppIDConstants {
internal static let APP_IDENTITY_LABEL = "appIdentity"
internal static let DEVICE_IDENTITY_LABEL = "deviceIdentity"
internal static let USER_IDENTITY_LABEL = "userIdentity"
//labels
// labels

internal static let BMSSecurityErrorDomain = "com.ibm.mobilefirstplatform.clientsdk.swift.bmssecurity"
internal static let privateKeyIdentifier = "\(_PRIVATE_KEY_LABEL):\(nameAndVer.name):\(nameAndVer.version)"
Expand Down
2 changes: 1 addition & 1 deletion Source/BluemixAppID/internal/AuthorizationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class AuthorizationManager {
}
return url
}

public func launchAuthorizationUI(authorizationDelegate:AuthorizationDelegate) {

self.registrationManager.ensureRegistered(callback: {(error:AppIDError?) in
Expand Down
1 change: 1 addition & 0 deletions Source/BluemixAppID/internal/LoginWidgetImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ public class LoginWidgetImpl: LoginWidget {
public func launch(delegate: AuthorizationDelegate) {
self.oauthManager.authorizationManager?.launchAuthorizationUI(authorizationDelegate: delegate)
}

}
2 changes: 1 addition & 1 deletion Source/BluemixAppID/internal/PreferenceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal class PreferenceManager {

private(set) final var sharedPreferences:UserDefaults = UserDefaults.standard
private static let logger = Logger.logger(name: Logger.bmsLoggerPrefix + "PreferenceManager")

public func getStringPreference(name:String) -> StringPreference {
return StringPreference(name: name, sharedPreferences: sharedPreferences)
}
Expand Down
6 changes: 3 additions & 3 deletions Source/BluemixAppID/internal/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Utils {


if JSONSerialization.isValidJSONObject(value) {
do{
do {
let data = try JSONSerialization.data(withJSONObject: value, options: options)
guard let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as? String else {
throw AppIDError.jsonUtilsError(msg: "Json is malformed")
Expand Down Expand Up @@ -139,7 +139,7 @@ public class Utils {

// mop things up if we ended on a boundary
k = j
if (current == "=") {
if current == "=" {
switch (i % 4) {
case 1:
// Invalid state
Expand Down Expand Up @@ -189,7 +189,7 @@ public class Utils {
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6)
output[3] = input[2] & 0x3F
ctcopy = 4
switch (ctremaining) {
switch ctremaining {
case 1:
ctcopy = 2
case 2:
Expand Down
10 changes: 5 additions & 5 deletions Source/BluemixAppID/internal/tokens/AbstractToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public protocol Token {
var expiration: Date? {get}
var issuedAt: Date? {get}
var tenant: String? {get}
var authBy: String? {get}
var authenticationMethods: [String]? {get}
var isExpired: Bool {get}
var isAnonymous: Bool {get}
}
Expand All @@ -26,7 +26,7 @@ internal class AbstractToken: Token {
private static let EXPIRATION = "exp"
private static let ISSUED_AT = "iat"
private static let TENANT = "tenant"
private static let AUTH_BY = "auth_by"
private static let AUTH_METHODS = "amr"

var raw: String
var header: Dictionary<String, Any>
Expand Down Expand Up @@ -98,9 +98,9 @@ internal class AbstractToken: Token {
return payload[AbstractToken.TENANT] as? String
}

var authBy: String? {
return payload[AbstractToken.AUTH_BY] as? String
}
var authenticationMethods: [String]? {
return payload[AbstractToken.AUTH_METHODS] as? [String]
}

var isExpired: Bool {
guard let exp = self.expiration else {
Expand Down
1 change: 0 additions & 1 deletion dummyAppForKeyChain/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,3 @@ class AppDelegate: UIResponder, UIApplicationDelegate {


}

0 comments on commit 453d11b

Please sign in to comment.