1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-12 06:13:21 +00:00

PM-2732 Changed to Delegate approach for the new iOS 17 credential provider methods

This commit is contained in:
Federico Maccaroni
2023-07-05 18:56:22 -03:00
parent 62f3fd5b5c
commit ea44a84596
3 changed files with 144 additions and 92 deletions

View File

@@ -5,6 +5,28 @@ using ObjCRuntime;
namespace XamariniOS17CredentialProviderBinding namespace XamariniOS17CredentialProviderBinding
{ {
interface IASCredentialProviderCompatDelegate { }
// @protocol ASCredentialProviderCompatDelegate
[Protocol, Model(AutoGeneratedName = true)]
interface ASCredentialProviderCompatDelegate
{
// @required -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest;
[Abstract]
[Export("prepareInterfaceToProvideCredentialCompatFor:")]
void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest);
// @required -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest;
[Abstract]
[Export("provideCredentialWithoutUserInteractionCompatFor:")]
void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest);
// @required -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest;
[Abstract]
[Export("prepareInterfaceCompatForPasskeyRegistration:")]
void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest);
}
// @interface ASCredentialRequestCompat : NSObject // @interface ASCredentialRequestCompat : NSObject
[BaseType (typeof(NSObject))] [BaseType (typeof(NSObject))]
[DisableDefaultCtor] [DisableDefaultCtor]
@@ -75,19 +97,22 @@ namespace XamariniOS17CredentialProviderBinding
//void PrepareInterfaceForPasskeyRegistration (ASCredentialRequest registrationRequest); //void PrepareInterfaceForPasskeyRegistration (ASCredentialRequest registrationRequest);
// -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; // -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest;
[Export ("prepareInterfaceToProvideCredentialCompatFor:")] //[Export ("prepareInterfaceToProvideCredentialCompatFor:")]
[Abstract] // [Abstract]
void PrepareInterfaceToProvideCredentialCompatFor (ASCredentialRequestCompat credentialRequest); // void PrepareInterfaceToProvideCredentialCompatFor (ASCredentialRequestCompat credentialRequest);
// -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; //// -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest;
[Export ("provideCredentialWithoutUserInteractionCompatFor:")] //[Export ("provideCredentialWithoutUserInteractionCompatFor:")]
[Abstract] // [Abstract]
void ProvideCredentialWithoutUserInteractionCompatFor (ASCredentialRequestCompat credentialRequest); // void ProvideCredentialWithoutUserInteractionCompatFor (ASCredentialRequestCompat credentialRequest);
// -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest; //// -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest;
[Export ("prepareInterfaceCompatForPasskeyRegistration:")] //[Export ("prepareInterfaceCompatForPasskeyRegistration:")]
[Abstract] // [Abstract]
void PrepareInterfaceCompatForPasskeyRegistration (ASCredentialRequestCompat registrationRequest); // void PrepareInterfaceCompatForPasskeyRegistration (ASCredentialRequestCompat registrationRequest);
[Export("SetCompatDelegate:")]
void SetCompatDelegate(IASCredentialProviderCompatDelegate @delegate);
// -(instancetype _Nonnull)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil __attribute__((objc_designated_initializer)); // -(instancetype _Nonnull)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil __attribute__((objc_designated_initializer));
[Export ("initWithNibName:bundle:")] [Export ("initWithNibName:bundle:")]

View File

@@ -115,29 +115,34 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
// MARK: iOS 17 new methods // MARK: iOS 17 new methods
override final public func prepareInterfaceToProvideCredential(for credentialRequest: ASCredentialRequest) { override final public func prepareInterfaceToProvideCredential(for credentialRequest: ASCredentialRequest) {
prepareInterfaceToProvideCredentialCompat(for: convertRequestToCompat(from: credentialRequest)) guard let compatDelegate = compatDelegate else {
return
}
compatDelegate.prepareInterfaceToProvideCredentialCompat(for: convertRequestToCompat(from: credentialRequest))
} }
override final public func provideCredentialWithoutUserInteraction(for credentialRequest: ASCredentialRequest) { override final public func provideCredentialWithoutUserInteraction(for credentialRequest: ASCredentialRequest) {
provideCredentialWithoutUserInteractionCompat(for: convertRequestToCompat(from: credentialRequest)) guard let compatDelegate = compatDelegate else {
return
}
compatDelegate.provideCredentialWithoutUserInteractionCompat(for: convertRequestToCompat(from: credentialRequest))
} }
override final public func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) { override final public func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) {
prepareInterfaceCompat(forPasskeyRegistration: convertRequestToCompat(from: registrationRequest)) guard let compatDelegate = compatDelegate else {
return
}
compatDelegate.prepareInterfaceCompat(forPasskeyRegistration: convertRequestToCompat(from: registrationRequest))
} }
// MARK: Compat methods // MARK: Compat
var compatDelegate: ASCredentialProviderCompatDelegate? = nil;
@objc @objc
open func prepareInterfaceToProvideCredentialCompat(for credentialRequest: ASCredentialRequestCompat){ public func SetCompatDelegate(_ delegate: ASCredentialProviderCompatDelegate)
} {
compatDelegate = delegate
@objc
open func provideCredentialWithoutUserInteractionCompat(for credentialRequest: ASCredentialRequestCompat) {
}
@objc
open func prepareInterfaceCompat(forPasskeyRegistration registrationRequest: ASCredentialRequestCompat) {
} }
func convertRequestToCompat(from credentialRequest: ASCredentialRequest) -> ASCredentialRequestCompat { func convertRequestToCompat(from credentialRequest: ASCredentialRequest) -> ASCredentialRequestCompat {
@@ -146,3 +151,16 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
credentialIdentity: credentialRequest.credentialIdentity) credentialIdentity: credentialRequest.credentialIdentity)
} }
} }
@objc(ASCredentialProviderCompatDelegate)
public protocol ASCredentialProviderCompatDelegate
{
@objc
func prepareInterfaceToProvideCredentialCompat(for credentialRequest: ASCredentialRequestCompat)
@objc
func provideCredentialWithoutUserInteractionCompat(for credentialRequest: ASCredentialRequestCompat)
@objc
func prepareInterfaceCompat(forPasskeyRegistration registrationRequest: ASCredentialRequestCompat)
}

View File

@@ -50,6 +50,8 @@ namespace Bit.iOS.Autofill
{ {
ExtContext = ExtensionContext ExtContext = ExtensionContext
}; };
var del = new ASCredentialProviderDelegate(this);
SetCompatDelegate(del);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -164,60 +166,6 @@ namespace Bit.iOS.Autofill
} }
} }
#region iOS 17 Beta
public override async void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest)
{
try
{
InitAppIfNeeded();
if (!await IsAuthed())
{
await _accountsManager.NavigateOnAccountChangeAsync(false);
return;
}
_context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity;
await CheckLockAsync(async () => await ProvideCredentialAsync());
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
throw;
}
}
public override void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest)
{
Console.WriteLine("entered");
//try
//{
// InitAppIfNeeded();
// await _stateService.Value.SetPasswordRepromptAutofillAsync(false);
// await _stateService.Value.SetPasswordVerifiedAutofillAsync(false);
// if (!await IsAuthed() || await IsLocked())
// {
// var err = new NSError(new NSString("ASExtensionErrorDomain"),
// Convert.ToInt32(ASExtensionErrorCode.UserInteractionRequired), null);
// ExtensionContext.CancelRequest(err);
// return;
// }
// _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity;
// await ProvideCredentialAsync(false);
//}
//catch (Exception ex)
//{
// LoggerHelper.LogEvenIfCantBeResolved(ex);
// throw;
//}
}
public override void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest)
{
// DO STUFF
}
#endregion
public void CompleteRequest(string id = null, string username = null, public void CompleteRequest(string id = null, string username = null,
string password = null, string totp = null) string password = null, string totp = null)
{ {
@@ -706,4 +654,65 @@ namespace Bit.iOS.Autofill
} }
} }
} }
public class ASCredentialProviderDelegate : NSObject, IASCredentialProviderCompatDelegate
{
public ASCredentialProviderDelegate(CredentialProviderViewController controller)
{
CredentialProviderViewController = controller;
}
public CredentialProviderViewController CredentialProviderViewController { get; }
public void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest)
{
CredentialProviderViewController?.CompleteRequest(null, "lala", "qerqrw");
//try
//{
// InitAppIfNeeded();
// if (!await IsAuthed())
// {
// await _accountsManager.NavigateOnAccountChangeAsync(false);
// return;
// }
// _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity;
// await CheckLockAsync(async () => await ProvideCredentialAsync());
//}
//catch (Exception ex)
//{
// LoggerHelper.LogEvenIfCantBeResolved(ex);
// throw;
//}
}
public void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest)
{
CredentialProviderViewController?.CompleteRequest(null, "nouserinteraction", "qerqrw");
//try
//{
// InitAppIfNeeded();
// await _stateService.Value.SetPasswordRepromptAutofillAsync(false);
// await _stateService.Value.SetPasswordVerifiedAutofillAsync(false);
// if (!await IsAuthed() || await IsLocked())
// {
// var err = new NSError(new NSString("ASExtensionErrorDomain"),
// Convert.ToInt32(ASExtensionErrorCode.UserInteractionRequired), null);
// ExtensionContext.CancelRequest(err);
// return;
// }
// _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity;
// await ProvideCredentialAsync(false);
//}
//catch (Exception ex)
//{
// LoggerHelper.LogEvenIfCantBeResolved(ex);
// throw;
//}
}
public void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest)
{
CredentialProviderViewController?.CompleteRequest(null, "passkey", "qerqrw");
}
}
} }