Commit 0de52659 authored by Silbino Goncalves Matado's avatar Silbino Goncalves Matado Committed by Silbino Goncalves Matado

Lookup and register name: add services and adapters

Add NameService and NameRegistrationAdapter to :

- Verify if the username is valid and available to create a new user
- Register a new username into the blockchain.

Add RegistrationState observation from the daemon to verify if the
account is properly created.

Change-Id: I5a66dde2576391b5ec2dc242fb544dc4fe680d9e
parent fd9f3ab1
......@@ -108,8 +108,13 @@
5557FD4E1E81B1F20043E394 /* AccountModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5516C29E1E71CEFF009D3D2D /* AccountModelHelper.swift */; };
5557FD4F1E81B2990043E394 /* AccountCredentialsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DD80C91E1EAF1A009A3510 /* AccountCredentialsModel.swift */; };
557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */; };
56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56308BA61EA00E5700660275 /* NameRegistrationResponse.m */; };
563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 563AEC761EA664C0003A5641 /* RegistrationResponse.m */; };
564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */; };
564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C445A1E8EA44E000F92B1 /* Durations.swift */; };
564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */; };
564C44621E943DE6000F92B1 /* NameService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44611E943DE6000F92B1 /* NameService.swift */; };
564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */; };
56AC64D51E7C7F4000EA1AA9 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64D41E7C7F4000EA1AA9 /* WelcomeViewController.swift */; };
56AC64D91E8012CA00EA1AA9 /* Walkthrough.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56AC64DB1E8012CA00EA1AA9 /* Walkthrough.strings */; };
56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64DE1E804ECC00EA1AA9 /* SwitchCell.swift */; };
......@@ -117,6 +122,7 @@
56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E21E805F0200EA1AA9 /* TextCell.swift */; };
56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */; };
56BBC9C51ED8BF3300CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9C41ED8BF3300CDAF8B /* libargon2.a */; };
56BBC9DA1EDDC0B400CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -248,8 +254,16 @@
5557FD491E81AE850043E394 /* AccountModelHelperTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountModelHelperTests.swift; sourceTree = "<group>"; };
557086501E8ADB9D001A7CE4 /* SystemAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SystemAdapter.h; path = Bridging/SystemAdapter.h; sourceTree = "<group>"; };
557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SystemAdapter.mm; path = Bridging/SystemAdapter.mm; sourceTree = "<group>"; };
56308BA51EA00E5700660275 /* NameRegistrationResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameRegistrationResponse.h; sourceTree = "<group>"; };
56308BA61EA00E5700660275 /* NameRegistrationResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NameRegistrationResponse.m; sourceTree = "<group>"; };
563AEC751EA664C0003A5641 /* RegistrationResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationResponse.h; sourceTree = "<group>"; };
563AEC761EA664C0003A5641 /* RegistrationResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationResponse.m; sourceTree = "<group>"; };
564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizedStringTableNames.swift; sourceTree = "<group>"; };
564C445A1E8EA44E000F92B1 /* Durations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Durations.swift; sourceTree = "<group>"; };
564C445E1E943C37000F92B1 /* NameRegistrationAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameRegistrationAdapter.h; sourceTree = "<group>"; };
564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NameRegistrationAdapter.mm; sourceTree = "<group>"; };
564C44611E943DE6000F92B1 /* NameService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NameService.swift; sourceTree = "<group>"; };
564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NameRegistrationAdapterDelegate.swift; sourceTree = "<group>"; };
56AC64D41E7C7F4000EA1AA9 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = "<group>"; };
56AC64DA1E8012CA00EA1AA9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Walkthrough.strings; sourceTree = "<group>"; };
56AC64DE1E804ECC00EA1AA9 /* SwitchCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchCell.swift; sourceTree = "<group>"; };
......@@ -257,6 +271,8 @@
56AC64E21E805F0200EA1AA9 /* TextCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextCell.swift; sourceTree = "<group>"; };
56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedTextField.swift; sourceTree = "<group>"; };
56BBC9C41ED8BF3300CDAF8B /* libargon2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libargon2.a; path = ../fat/lib/libargon2.a; sourceTree = "<group>"; };
56BBC9D81EDDC0B400CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LookupNameResponse.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -402,6 +418,8 @@
02B22DFE1DF755DB000358C9 /* AccountsService.swift */,
0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */,
02C9B63E1E1D4E8C00F82F0C /* ServiceEvent.swift */,
564C44611E943DE6000F92B1 /* NameService.swift */,
564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */,
);
name = Services;
sourceTree = "<group>";
......@@ -423,14 +441,14 @@
isa = PBXGroup;
children = (
04399AA91D1C304300E99CD9 /* Ring-Bridging-Header.h */,
04399AA51D1C304300E99CD9 /* AccountAdapter.h */,
04399AA61D1C304300E99CD9 /* AccountAdapter.mm */,
557086501E8ADB9D001A7CE4 /* SystemAdapter.h */,
557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */,
04399AA71D1C304300E99CD9 /* DRingAdapter.h */,
04399AA81D1C304300E99CD9 /* DRingAdapter.mm */,
04399AAA1D1C304300E99CD9 /* Utils.h */,
04399AAB1D1C304300E99CD9 /* Utils.mm */,
563AEC741EA66487003A5641 /* AccountCreation */,
563AEC731EA6627F003A5641 /* NameRegistration */,
);
name = Bridging;
sourceTree = "<group>";
......@@ -611,6 +629,30 @@
name = SYS_DEPS;
sourceTree = "<group>";
};
563AEC731EA6627F003A5641 /* NameRegistration */ = {
isa = PBXGroup;
children = (
56BBC9D81EDDC0B400CDAF8B /* LookupNameResponse.h */,
56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */,
564C445E1E943C37000F92B1 /* NameRegistrationAdapter.h */,
564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */,
56308BA51EA00E5700660275 /* NameRegistrationResponse.h */,
56308BA61EA00E5700660275 /* NameRegistrationResponse.m */,
);
name = NameRegistration;
sourceTree = "<group>";
};
563AEC741EA66487003A5641 /* AccountCreation */ = {
isa = PBXGroup;
children = (
04399AA51D1C304300E99CD9 /* AccountAdapter.h */,
04399AA61D1C304300E99CD9 /* AccountAdapter.mm */,
563AEC751EA664C0003A5641 /* RegistrationResponse.h */,
563AEC761EA664C0003A5641 /* RegistrationResponse.m */,
);
name = AccountCreation;
sourceTree = "<group>";
};
564C44571E8D7F68000F92B1 /* Constants */ = {
isa = PBXGroup;
children = (
......@@ -799,30 +841,36 @@
02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */,
04399AAC1D1C304300E99CD9 /* AccountAdapter.mm in Sources */,
02DD80C81E1EAD70009A3510 /* AccountConfigModel.swift in Sources */,
56BBC9DA1EDDC0B400CDAF8B /* LookupNameResponse.m in Sources */,
02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */,
02C9B63F1E1D4E8C00F82F0C /* ServiceEvent.swift in Sources */,
02DD80CD1E1EB2E4009A3510 /* ConfigKeyModel.swift in Sources */,
5516C29F1E71CEFF009D3D2D /* AccountModelHelper.swift in Sources */,
56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */,
56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */,
56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */,
56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */,
02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
043866331D22CE8C00E06CE2 /* MeViewController.swift in Sources */,
56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */,
04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */,
563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */,
02B22DFD1DF755BB000358C9 /* CreateRingAccountViewModel.swift in Sources */,
043999FA1D1C2D9D00E99CD9 /* Ring.xcdatamodeld in Sources */,
564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */,
0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */,
02DD80CA1E1EAF1A009A3510 /* AccountCredentialsModel.swift in Sources */,
0273C3081E0C68BF00CF00BA /* RoundedButton.swift in Sources */,
564C44621E943DE6000F92B1 /* NameService.swift in Sources */,
043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */,
02B22DFF1DF755DB000358C9 /* AccountsService.swift in Sources */,
564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */,
564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */,
56AC64D51E7C7F4000EA1AA9 /* WelcomeViewController.swift in Sources */,
);
......
......@@ -31,7 +31,7 @@ enum AccountModelError: Error {
/**
A class representing an account.
*/
class AccountModel {
class AccountModel : Equatable {
// MARK: Public members
let id: String
......@@ -49,25 +49,18 @@ class AccountModel {
}
init(withAccountId accountId: String,
details: Dictionary<String, String>,
volatileDetails: Dictionary<String, String>,
credentials: Array<Dictionary<String, String>>,
details: AccountConfigModel,
volatileDetails: AccountConfigModel,
credentials: [AccountCredentialsModel],
devices: Dictionary<String, String>) throws {
self.id = accountId
self.details = AccountConfigModel(withDetails: details)
self.volatileDetails = AccountConfigModel(withDetails: details)
for credential in credentials {
do {
let cred = try AccountCredentialsModel(withRawaData: credential)
credentialDetails.append(cred)
} catch CredentialsError.NotEnoughData {
print("Not enough data to build a credential object.")
throw CredentialsError.NotEnoughData
} catch {
print("Unexpected error.")
throw AccountModelError.UnexpectedError
}
}
self.details = details
self.volatileDetails = volatileDetails
self.devices = devices
}
public static func ==(lhs: AccountModel, rhs: AccountModel) -> Bool {
return lhs.id == rhs.id
}
}
......@@ -54,83 +54,50 @@ class CreateRingAccountViewModel {
var password = Variable<String>("")
var repeatPassword = Variable<String>("")
var usernameValid :Observable<Bool> {
return username.asObservable().map({ username in
return !username.isEmpty
})
}
var passwordValid :Observable<Bool> {
return Observable<Bool>.combineLatest(self.username.asObservable(),
self.password.asObservable(),
self.repeatPassword.asObservable())
{ (username, password, repeatPassword) in
return password.characters.count >= 6
}
}
var passwordsEqual :Observable<Bool> {
return Observable<Bool>.combineLatest(self.password.asObservable(),
self.repeatPassword.asObservable())
{ password, repeatPassword in
return password == repeatPassword
}
}
var passwordValid :Observable<Bool>!
var passwordsEqual :Observable<Bool>!
var canCreateAccount :Observable<Bool>!
var registerUsername = Variable<Bool>(true)
var canCreateAccount :Observable<Bool> {
return Observable<Bool>.combineLatest(self.registerUsername.asObservable(),
self.usernameValid,
self.passwordValid,
self.passwordsEqual)
{ registerUsername, usernameValid, passwordValid, passwordsEquals in
if registerUsername {
return usernameValid && passwordValid && passwordsEquals
} else {
return passwordValid && passwordsEquals
}
}
}
var hasNewPassword :Observable<Bool>!
var hidePasswordError :Observable<Bool>!
var hideRepeatPasswordError :Observable<Bool>!
var registerUsername = Variable<Bool>(true)
/**
The nameService instance injected in initializer.
*/
fileprivate var nameService: NameService
//Observes if the field is not empty
var hasNewPassword :Observable<Bool> {
return self.password.asObservable().map({ password in
return password.characters.count == 0
})
}
//MARK: - Rx Variables and Observers
//Observes if the password is valid and is not empty to show the error message
var hidePasswordError :Observable<Bool> {
return Observable<Bool>.combineLatest(self.passwordValid, hasNewPassword)
{ isPasswordValid, hasNewPassword in
return isPasswordValid || hasNewPassword
}
}
/**
Message presented to the user in function of the status of the current username lookup request
*/
var usernameValidationMessage :Observable<String>!
//Observes if the password is valid and is not empty to show the error message
var hideRepeatPasswordError :Observable<Bool> {
return Observable<Bool>.combineLatest(self.passwordValid, self.passwordsEqual) { isPasswordValid,
isPasswordsEquals in
return !isPasswordValid || isPasswordsEquals
}
}
//MARK: -
/**
Default constructor
*/
init(withAccountService accountService: AccountsService) {
init(withAccountService accountService: AccountsService, nameService: NameService) {
self.account = nil
self.accountService = accountService
self.nameService = nameService
self.initObservables()
self.initObservers()
}
/**
Constructor with AccountModel.
*/
init(withAccountService accountService: AccountsService,
accountModel account: AccountModel?) {
accountModel account: AccountModel?, nameService: NameService) {
self.account = account
self.accountService = accountService
self.nameService = nameService
self.initObservables()
self.initObservers()
}
/**
......@@ -163,9 +130,25 @@ class CreateRingAccountViewModel {
if event.eventType == ServiceEventType.AccountAdded {
print("Account added.")
}
if event.eventType == ServiceEventType.AccountsChanged {
onSuccessCallback?()
}
if event.eventType == ServiceEventType.RegistrationStateChanged {
if event.getEventInput(ServiceEventInput.RegistrationState) == Unregistered {
//Register username
if (self?.registerUsername.value)! {
self?.nameService
.registerName(withAccount: (self?.accountService.currentAccount?.id)!,
password: (self?.password.value)!,
name: (self?.username.value)!)
}
}
}
}, onError: { error in
onErrorCallback?(error)
})
......@@ -173,8 +156,9 @@ class CreateRingAccountViewModel {
//~ Launch the action.
do {
try self?.accountService.addRingAccount(withUsername: nil,
password: "coucou")
//Add account
try self?.accountService.addRingAccount(withUsername: self?.username.value,
password: (self?.password.value)!)
}
catch {
onErrorCallback?(error)
......@@ -186,4 +170,76 @@ class CreateRingAccountViewModel {
.addDisposableTo(disposeBag)
}
/**
Init obsevables needed to validate the user inputs for account creation
*/
func initObservables() {
self.passwordValid = password.asObservable().map { password in
return password.characters.count >= 6
}.shareReplay(1).observeOn(MainScheduler.instance)
self.passwordsEqual = Observable<Bool>.combineLatest(self.password.asObservable(),
self.repeatPassword.asObservable()) { password,repeatPassword in
return password == repeatPassword
}.shareReplay(1).observeOn(MainScheduler.instance)
self.canCreateAccount = Observable<Bool>.combineLatest(self.registerUsername.asObservable(),
self.nameService.usernameValidationStatus,
self.passwordValid,
self.passwordsEqual)
{ registerUsername, usernameValidationStatus, passwordValid, passwordsEquals in
if registerUsername {
return usernameValidationStatus == .valid && passwordValid && passwordsEquals
} else {
return passwordValid && passwordsEquals
}
}.shareReplay(1).observeOn(MainScheduler.instance)
self.usernameValidationMessage = self.nameService.usernameValidationStatus
.asObservable().map ({ status in
switch status {
case .lookingUp:
return NSLocalizedString("LookingForUsernameAvailability",
tableName: LocalizedStringTableNames.walkthrough,
comment: "")
case .invalid:
return NSLocalizedString("InvalidUsername",
tableName: LocalizedStringTableNames.walkthrough,
comment: "")
case .alreadyTaken:
return NSLocalizedString("UsernameAlreadyTaken",
tableName: LocalizedStringTableNames.walkthrough,
comment: "")
default:
return ""
}
}).shareReplay(1).observeOn(MainScheduler.instance)
hasNewPassword = self.password.asObservable().map({ password in
return password.characters.count > 0
})
hidePasswordError = Observable<Bool>.combineLatest(self.passwordValid, hasNewPassword) { isPasswordValid, hasNewPassword in
return isPasswordValid || !hasNewPassword
}
let hasRepeatPassword = self.repeatPassword.asObservable().map({ repeatPassword in
return repeatPassword.characters.count > 0
})
hideRepeatPasswordError = Observable<Bool>.combineLatest(self.passwordValid,self.passwordsEqual, hasRepeatPassword) { isPasswordValid, isPasswordsEquals, hasRepeatPassword in
return !isPasswordValid || isPasswordsEquals || !hasRepeatPassword
}
}
/**
Init observers needed to validate the user inputs for account creation
*/
func initObservers() {
self.username.asObservable().subscribe(onNext: { [unowned self] username in
self.nameService.lookupName(withAccount: "", nameserver: "", name: username)
}).addDisposableTo(disposeBag)
}
}
......@@ -28,6 +28,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
static let daemonService = DaemonService(dRingAdaptor: DRingAdapter())
static let accountService = AccountsService(withAccountAdapter: AccountAdapter())
static let nameService = NameService(withNameRegistrationAdapter: NameRegistrationAdapter())
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SystemAdapter().registerConfigurationHandler()
......@@ -123,8 +124,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// MARK: - Ring Daemon
fileprivate func startDaemon() {
do {
try AppDelegate.daemonService.startDaemon()
AppDelegate.accountService.loadAccounts()
} catch StartDaemonError.InitializationFailure {
print("Daemon failed to initialize.")
} catch StartDaemonError.StartFailure {
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1212" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
<device id="retina4_0" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
......
......@@ -36,3 +36,5 @@
"PasswordCharactersNumberError" = "6 characters minimum";
"PasswordNotMatchingError" = "Passwords do not match";
"LookingForUsernameAvailability" = "Looking for username availability...";
"InvalidUsername" = "Invalid username";
"UsernameAlreadyTaken" = "Username already taken";
......@@ -25,6 +25,7 @@
#import "Utils.h"
#import "dring/configurationmanager_interface.h"
#import "RegistrationResponse.h"
@implementation AccountAdapter
......@@ -51,6 +52,18 @@ static id <AccountAdapterDelegate> _delegate;
[AccountAdapter.delegate accountsChanged];
}
}));
confHandlers.insert(exportable_callback<ConfigurationSignal::RegistrationStateChanged>([&](const std::string& account_id, const std::string& state, int detailsCode, const std::string& detailsStr) {
if (AccountAdapter.delegate) {
RegistrationResponse* response = [RegistrationResponse new];
response.accountId = [NSString stringWithUTF8String:account_id.c_str()];
response.state = [NSString stringWithUTF8String:state.c_str()];
response.detailsCode = (RegistrationResponseDetailsCode)detailsCode;
response.details = [NSString stringWithUTF8String:detailsStr.c_str()];
[AccountAdapter.delegate registrationStateChangedWith:response];
}
}));
registerConfHandlers(confHandlers);
}
#pragma mark -
......
......@@ -25,3 +25,7 @@
#import "AccountAdapter.h"
#import "SystemAdapter.h"
#import "DRingAdapter.h"
#import "NameRegistrationAdapter.h"
#import "LookupNameResponse.h"
#import "RegistrationResponse.h"
#import "NameRegistrationResponse.h"
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import <Foundation/Foundation.h>
#import "NameRegistrationAdapter.h"
//Represents the status of the lookup response from to the daemon
typedef NS_ENUM(NSInteger, LookupNameState) {
LookupNameStateFound = 0,
LookupNameStateInvalidName,
LookupNameStateNotFound,
LookupNameStateError
};
@interface LookupNameResponse : NSObject
@property (nonatomic, retain) NSString* accountId;
@property (nonatomic) LookupNameState state;
@property (nonatomic, retain) NSString* address;
@property (nonatomic, retain) NSString* name;
@end
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import "LookupNameResponse.h"
@implementation LookupNameResponse
@end
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import <Foundation/Foundation.h>
@protocol NameRegistrationAdapterDelegate;
@interface NameRegistrationAdapter : NSObject
@property (class, nonatomic, weak) id <NameRegistrationAdapterDelegate> delegate;
- (void)lookupNameWithAccount:(NSString*)account nameserver:(NSString*)nameserver
name:(NSString*)name;
- (void)registerNameWithAccount:(NSString*)account password:(NSString*)password
name:(NSString*)name;
@end
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import "Ring-Swift.h"
#import "NameRegistrationAdapter.h"
#import "Utils.h"
#import "dring/configurationmanager_interface.h"
#import "LookupNameResponse.h"
#import "NameRegistrationResponse.h"
@implementation NameRegistrationAdapter
using namespace DRing;
/// Static delegate that will receive the propagated daemon events
static id <NameRegistrationAdapterDelegate> _delegate;
- (id)init {
if (self = [super init]) {
[self registerConfigurationHandler];
}
return self;
}
#pragma mark -
#pragma mark Callbacks registration
- (void)registerConfigurationHandler {
std::map<std::string, std::shared_ptr<CallbackWrapperBase>> confHandlers;
confHandlers.insert(exportable_callback<ConfigurationSignal::RegisteredNameFound>([&](const std::string&account_id,
int state,
const std::string address,
const std::string& name) {
if (NameRegistrationAdapter.delegate) {
LookupNameResponse* response = [LookupNameResponse new];
response.accountId = [NSString stringWithUTF8String:account_id.c_str()];
response.state = (LookupNameState)state;
response.address = [NSString stringWithUTF8String:address.c_str()];
response.name = [NSString stringWithUTF8String:name.c_str()];
[NameRegistrationAdapter.delegate registeredNameFoundWith:response];
}
}));
confHandlers.insert(exportable_callback<ConfigurationSignal::NameRegistrationEnded>([&](const std::string&account_id,
int state,
const std::string& name) {
if (NameRegistrationAdapter.delegate) {
NameRegistrationResponse* response = [NameRegistrationResponse new];
response.accountId = [NSString stringWithUTF8String:account_id.c_str()];
response.state = (NameRegistrationState)state;
response.name = [NSString stringWithUTF8String:name.c_str()];
[NameRegistrationAdapter.delegate nameRegistrationEndedWith:response];
}
}));
registerConfHandlers(confHandlers);
}
#pragma mark -
- (void)lookupNameWithAccount:(NSString*)account nameserver:(NSString*)nameserver name:(NSString*)name {
lookupName(std::string([account UTF8String]),std::string([nameserver UTF8String]),std::string([name UTF8String]));
}
- (void)registerNameWithAccount:(NSString*)account password:(NSString*)password name:(NSString*)name {
registerName(std::string([account UTF8String]), std::string([password UTF8String]), std::string([name UTF8String]));
}
#pragma mark NameRegistrationAdapterDelegate
+ (id <NameRegistrationAdapterDelegate>)delegate {
return _delegate;
}
+ (void) setDelegate:(id<NameRegistrationAdapterDelegate>)delegate {
_delegate = delegate;
}
#pragma mark -
@end
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*