generated from bitwarden/template
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BIT-104: Accounts Register Request (#23)
- Loading branch information
1 parent
888dfd6
commit a1c85ff
Showing
12 changed files
with
323 additions
and
2 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
BitwardenShared/Core/Auth/Models/API/CreateAccount/CreateAccountRequestModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import Foundation | ||
import Networking | ||
|
||
// MARK: - CreateAccountRequestModel | ||
|
||
/// The data to include in the body of a `CreateAccountRequest`. | ||
/// | ||
struct CreateAccountRequestModel: Equatable { | ||
// MARK: Properties | ||
|
||
/// The captcha response used in validating a user for this request. | ||
let captchaResponse: String? = nil | ||
|
||
/// The user's email address. | ||
let email: String | ||
|
||
/// The type of kdf for this request. | ||
let kdf: KdfType? = nil | ||
|
||
/// The number of kdf iterations performed in this request. | ||
let kdfIterations: Int? = nil | ||
|
||
/// The kdf memory allocated for the computed password hash. | ||
let kdfMemory: Int? = nil | ||
|
||
/// The number of threads upon which the kdf iterations are performed. | ||
let kdfParallelism: Int? = nil | ||
|
||
/// The key used for this request. | ||
let key: String? = nil | ||
|
||
/// The keys used for this request. | ||
let keys: KeysRequestModel? = nil | ||
|
||
/// The master password hash used to authenticate a user. | ||
let masterPasswordHash: String // swiftlint:disable:this inclusive_language | ||
|
||
/// The master password hint. | ||
let masterPasswordHint: String? = nil // swiftlint:disable:this inclusive_language | ||
|
||
/// The user's name. | ||
let name: String? = nil | ||
|
||
/// The organization's user ID. | ||
let organizationUserId: String? = nil | ||
|
||
/// The token used when making this request. | ||
let token: String? = nil | ||
} | ||
|
||
// MARK: JSONRequestBody | ||
|
||
extension CreateAccountRequestModel: JSONRequestBody { | ||
static var encoder: JSONEncoder { | ||
JSONEncoder() | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
BitwardenShared/Core/Auth/Models/API/CreateAccount/CreateAccountResponseModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import Foundation | ||
import Networking | ||
|
||
// MARK: - CreateAccountResponseModel | ||
|
||
/// The response returned from the API upon creating an account. | ||
/// | ||
struct CreateAccountResponseModel: JSONResponse { | ||
static var decoder = JSONDecoder() | ||
|
||
// MARK: Properties | ||
|
||
/// The captcha bypass token returned in this response. | ||
var captchaBypassToken: String? | ||
} |
21 changes: 21 additions & 0 deletions
21
BitwardenShared/Core/Auth/Models/API/CreateAccount/CreateAccountResponseModelTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import XCTest | ||
|
||
@testable import BitwardenShared | ||
|
||
// MARK: - CreateAccountResponseModelTests | ||
|
||
class CreateAccountResponseModelTests: BitwardenTestCase { | ||
/// Tests that a response is initialized correctly. | ||
func test_init() { | ||
let subject = CreateAccountResponseModel(captchaBypassToken: "captchaBypassToken") | ||
XCTAssertEqual(subject.captchaBypassToken, "captchaBypassToken") | ||
} | ||
|
||
/// Tests the successful decoding of a JSON response. | ||
func test_decode_success() throws { | ||
let json = APITestData.createAccountResponse.data | ||
let decoder = JSONDecoder() | ||
let subject = try decoder.decode(CreateAccountResponseModel.self, from: json) | ||
XCTAssertEqual(subject.captchaBypassToken, "captchaBypassToken") | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
...Shared/Core/Auth/Models/API/CreateAccount/Fixtures/APITestData+CreateAccountRequest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
extension APITestData { | ||
static let createAccountRequest = loadFromBundle(resource: "Request", extension: "json") | ||
static let createAccountResponse = loadFromBundle(resource: "Success", extension: "json") | ||
} |
23 changes: 23 additions & 0 deletions
23
BitwardenShared/Core/Auth/Models/API/CreateAccount/Fixtures/Request.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "name", | ||
"email": "email", | ||
"masterPasswordHash": "masterPasswordHash", | ||
"masterPasswordHint": "masterPasswordHint", | ||
"captchaResponse": "captchaResponse", | ||
"key": "key", | ||
"keys": { | ||
"publicKey": "publicKey", | ||
"encryptedPrivateKey": "encryptedPrivateKey" | ||
}, | ||
"token": "token", | ||
"organizationUserId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", | ||
"kdf": 0, | ||
"kdfIterations": 0, | ||
"kdfMemory": 0, | ||
"kdfParallelism": 0, | ||
"referenceData": { | ||
"additionalProp1": "string", | ||
"additionalProp2": "string", | ||
"additionalProp3": "string" | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
BitwardenShared/Core/Auth/Models/API/CreateAccount/Fixtures/Success.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"object": "object", | ||
"captchaBypassToken": "captchaBypassToken" | ||
} |
11 changes: 11 additions & 0 deletions
11
BitwardenShared/Core/Auth/Models/API/CreateAccount/KdfType.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// MARK: - KdfType | ||
|
||
/// The type of key derivation function. | ||
/// | ||
enum KdfType: Int, Codable, Equatable { | ||
/// The PBKDF2 SHA256 type. | ||
case pbkdf2sha256 = 0 | ||
|
||
/// The Argon2id type. | ||
case argon2id = 1 | ||
} |
13 changes: 13 additions & 0 deletions
13
BitwardenShared/Core/Auth/Models/API/CreateAccount/KeysRequestModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// MARK: - KeysRequestModel | ||
|
||
/// A model for keys used in the `CreateAccountRequest`. | ||
/// | ||
struct KeysRequestModel: Codable, Equatable { | ||
// MARK: Properties | ||
|
||
/// The public key used in a `CreateAccountRequest`. | ||
var publicKey: String? | ||
|
||
/// The encrypted private key used in a `CreateAccountRequest`. | ||
let encryptedPrivateKey: String | ||
} |
21 changes: 19 additions & 2 deletions
21
BitwardenShared/Core/Auth/Services/API/AccountAPIService.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,22 @@ | ||
// MARK: - AccountAPIService | ||
|
||
/// A protocol for an API service used to make account requests. | ||
/// | ||
protocol AccountAPIService {} | ||
protocol AccountAPIService { | ||
/// Creates an API call for when the user submits an account creation form. | ||
/// | ||
/// - Parameter body: The body to be included in the request. | ||
/// | ||
/// - Returns data returned from the `CreateAccountRequest`. | ||
/// | ||
func createNewAccount(body: CreateAccountRequestModel) async throws -> CreateAccountResponseModel | ||
} | ||
|
||
// MARK: - APIService | ||
|
||
extension APIService: AccountAPIService {} | ||
extension APIService: AccountAPIService { | ||
func createNewAccount(body: CreateAccountRequestModel) async throws -> CreateAccountResponseModel { | ||
let request = CreateAccountRequest(body: body) | ||
return try await apiService.send(request) | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
BitwardenShared/Core/Auth/Services/API/AccountAPIServiceTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import XCTest | ||
|
||
@testable import BitwardenShared | ||
|
||
// MARK: - AccountAPIServiceTests | ||
|
||
class AccountAPIServiceTests: BitwardenTestCase { | ||
// MARK: Properties | ||
|
||
var client: MockHTTPClient! | ||
var subject: APIService! | ||
|
||
override func setUp() { | ||
super.setUp() | ||
client = MockHTTPClient() | ||
subject = APIService(client: client) | ||
} | ||
|
||
override func tearDown() { | ||
super.tearDown() | ||
client = nil | ||
subject = nil | ||
} | ||
|
||
// MARK: Account creation | ||
|
||
/// `createNewAccount(email:masterPasswordHash)` throws an error if the request fails. | ||
func test_create_account_httpFailure() async { | ||
client.result = .httpFailure() | ||
|
||
await assertAsyncThrows { | ||
_ = try await subject.createNewAccount( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
} | ||
} | ||
|
||
/// `createNewAccount(email:masterPasswordHash)` throws a decoding error if the response is not the expected type. | ||
func test_create_account_failure() async throws { | ||
let resultData = APITestData(data: Data("this should fail".utf8)) | ||
client.result = .httpSuccess(testData: resultData) | ||
|
||
await assertAsyncThrows { | ||
_ = try await subject.createNewAccount( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
} | ||
} | ||
|
||
/// `createNewAccount(email:masterPasswordHash)` returns the correct value from the API with a successful request. | ||
func test_create_account_success() async throws { | ||
let resultData = APITestData.createAccountResponse | ||
client.result = .httpSuccess(testData: resultData) | ||
|
||
let successfulResponse = try await subject.createNewAccount( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
|
||
let request = try XCTUnwrap(client.requests.first) | ||
XCTAssertEqual(request.method, .post) | ||
XCTAssertEqual(request.url.relativePath, "/api/accounts/register") | ||
XCTAssertEqual(successfulResponse.captchaBypassToken, "captchaBypassToken") | ||
XCTAssertNotNil(request.body) | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
BitwardenShared/Core/Auth/Services/API/CreateAccount/CreateAccountRequest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Foundation | ||
import Networking | ||
|
||
// MARK: - CreateAccountRequest | ||
|
||
/// The API request sent when submitting an account creation form. | ||
/// | ||
struct CreateAccountRequest: Request { | ||
typealias Response = CreateAccountResponseModel | ||
typealias Body = CreateAccountRequestModel | ||
|
||
/// The body of this request. | ||
var body: CreateAccountRequestModel? | ||
|
||
/// The HTTP method for this request. | ||
let method: HTTPMethod = .post | ||
|
||
/// The URL path for this request. | ||
var path: String = "/accounts/register" | ||
|
||
/// Creates a new `CreateAccountRequest` instance. | ||
/// | ||
/// - Parameter body: The body of the request. | ||
/// | ||
init(body: CreateAccountRequestModel) { | ||
self.body = body | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
BitwardenShared/Core/Auth/Services/API/CreateAccount/CreateAccountRequestTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import XCTest | ||
|
||
@testable import BitwardenShared | ||
|
||
// MARK: - CreateAccountRequestTests | ||
|
||
class CreateAccountRequestTests: BitwardenTestCase { | ||
/// Validate that the method is correct. | ||
func test_method() { | ||
let subject = CreateAccountRequest( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
XCTAssertEqual(subject.method, .post) | ||
} | ||
|
||
/// Validate that the path is correct. | ||
func test_path() { | ||
let subject = CreateAccountRequest( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
XCTAssertEqual(subject.path, "/accounts/register") | ||
} | ||
|
||
/// Validate that the body is not nil. | ||
func test_body() { | ||
let subject = CreateAccountRequest( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
XCTAssertNotNil(subject.body) | ||
} | ||
|
||
// MARK: Init | ||
|
||
/// Validate that the value provided to the init method is correct. | ||
func test_init_body() { | ||
let subject = CreateAccountRequest( | ||
body: CreateAccountRequestModel( | ||
email: "[email protected]", | ||
masterPasswordHash: "1234" | ||
) | ||
) | ||
XCTAssertEqual(subject.body?.email, "[email protected]") | ||
XCTAssertEqual(subject.body?.masterPasswordHash, "1234") | ||
} | ||
} |