VLCNetworkServerLoginInformation+Keychain.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*****************************************************************************
  2. * VLC for iOS
  3. *****************************************************************************
  4. * Copyright (c) 2016 VideoLAN. All rights reserved.
  5. * $Id$
  6. *
  7. * Authors: Vincent L. Cone <vincent.l.cone # tuta.io>
  8. *
  9. * Refer to the COPYING file of the official project for license.
  10. *****************************************************************************/
  11. #import "VLCNetworkServerLoginInformation+Keychain.h"
  12. #import <XKKeychain/XKKeychainGenericPasswordItem.h>
  13. @implementation VLCNetworkServerLoginInformation (Keychain)
  14. + (instancetype)loginInformationWithKeychainIdentifier:(NSString *)keychainIdentifier
  15. {
  16. NSURLComponents *components = [NSURLComponents componentsWithString:keychainIdentifier];
  17. VLCNetworkServerLoginInformation *login = [VLCNetworkServerLoginInformation newLoginInformationForProtocol:components.scheme];
  18. login.address = components.host;
  19. login.port = components.port;
  20. return login;
  21. }
  22. - (NSString *)keychainServiceIdentifier
  23. {
  24. NSURLComponents *components = [[NSURLComponents alloc] init];
  25. components.scheme = self.protocolIdentifier;
  26. components.host = self.address;
  27. components.port = self.port;
  28. NSString *serviceIdentifier = components.URL.absoluteString;
  29. return serviceIdentifier;
  30. }
  31. - (BOOL)loadLoginInformationFromKeychainWithError:(NSError *__autoreleasing _Nullable *)error
  32. {
  33. NSError *localError = nil;
  34. XKKeychainGenericPasswordItem *keychainItem = [XKKeychainGenericPasswordItem itemsForService:self.keychainServiceIdentifier error:&localError].firstObject;
  35. if (localError) {
  36. if (error) {
  37. *error = localError;
  38. }
  39. return NO;
  40. }
  41. if (!keychainItem) {
  42. return YES;
  43. }
  44. self.username = keychainItem.account;
  45. self.password = keychainItem.secret.stringValue;
  46. NSDictionary *genericAttributes = keychainItem.generic.dictionaryValue;
  47. for (VLCNetworkServerLoginInformationField *field in self.additionalFields) {
  48. id value = genericAttributes[field.identifier];
  49. if ([value isKindOfClass:[NSString class]]) {
  50. field.textValue = value;
  51. }
  52. }
  53. return YES;
  54. }
  55. - (BOOL)saveLoginInformationToKeychainWithError:(NSError *__autoreleasing _Nullable *)error
  56. {
  57. XKKeychainGenericPasswordItem *keychainItem = [XKKeychainGenericPasswordItem itemForService:self.keychainServiceIdentifier account:self.username error:nil];
  58. if (!keychainItem) {
  59. keychainItem = [[XKKeychainGenericPasswordItem alloc] init];
  60. keychainItem.service = self.keychainServiceIdentifier;
  61. keychainItem.account = self.username;
  62. }
  63. keychainItem.secret.stringValue = self.password;
  64. NSArray<VLCNetworkServerLoginInformationField *> *fields = self.additionalFields;
  65. NSUInteger fieldsCount = fields.count;
  66. if (fieldsCount) {
  67. NSMutableDictionary *genericAttributes = [NSMutableDictionary dictionaryWithCapacity:fieldsCount];
  68. for (VLCNetworkServerLoginInformationField *field in fields) {
  69. NSString *textValue = field.textValue;
  70. if (textValue) {
  71. genericAttributes[field.identifier] = textValue;
  72. }
  73. }
  74. keychainItem.generic.dictionaryValue = genericAttributes;
  75. }
  76. return [keychainItem saveWithError:error];
  77. }
  78. - (BOOL)deleteFromKeychainWithError:(NSError *__autoreleasing _Nullable *)error
  79. {
  80. XKKeychainGenericPasswordItem *keychainItem = [[XKKeychainGenericPasswordItem alloc] init];
  81. keychainItem.service = self.keychainServiceIdentifier;
  82. keychainItem.account = self.username;
  83. return [keychainItem deleteWithError:error];
  84. }
  85. @end