123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2016-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // 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 Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- #import "WorkDataFetcher.h"
- #import "AppGroup.h"
- #import "ServerAPIRequest.h"
- #import "MyIdentityStore.h"
- #import "LicenseStore.h"
- #import "ContactStore.h"
- #import "Contact.h"
- #import "EntityManager.h"
- #import "MDMSetup.h"
- #import "UserSettings.h"
- #ifdef DEBUG
- static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
- #else
- static const DDLogLevel ddLogLevel = DDLogLevelWarning;
- #endif
- #define WORK_DEFAULT_CHECK_INTERVAL 86400
- @implementation WorkDataFetcher
- + (void)checkUpdateWorkDataForce:(BOOL)force onCompletion:(void(^)(void))onCompletion onError:(void(^)(NSError*))onError {
- if (![LicenseStore requiresLicenseKey]) {
- if (onCompletion != nil)
- onCompletion();
- return;
- }
-
- NSUserDefaults *defaults = [AppGroup userDefaults];
-
- NSDate *lastWorkSync = [defaults objectForKey:@"WorkDataLastSync"];
- NSInteger checkInterval = [defaults integerForKey:@"WorkDataCheckInterval"];
- if (checkInterval == 0)
- checkInterval = WORK_DEFAULT_CHECK_INTERVAL;
-
- /* check if we are within the minimum interval */
- if (!force) {
- if (lastWorkSync != nil && -[lastWorkSync timeIntervalSinceNow] < checkInterval) {
- DDLogInfo(@"Still within work check interval - not syncing");
- return;
- }
- }
-
- if ([LicenseStore sharedLicenseStore].licenseUsername == nil) {
- if (onCompletion != nil)
- onCompletion();
- return;
- }
-
- // Send Work fetch request with license username/password and list of identities in local contact list
- NSArray *contactIds = [[ContactStore sharedContactStore] allIdentities];
- NSDictionary *request = @{
- @"username": [LicenseStore sharedLicenseStore].licenseUsername,
- @"password": [LicenseStore sharedLicenseStore].licensePassword,
- @"contacts": contactIds
- };
-
- [ServerAPIRequest postJSONToWorkAPIPath:@"fetch2" data:request onCompletion:^(id jsonObject) {
- NSDictionary *workData = (NSDictionary*)jsonObject;
-
- DDLogVerbose(@"Work data: %@", workData);
-
- MDMSetup *mdmSetup = [[MDMSetup alloc] initWithSetup:NO];
- [mdmSetup applyThreemaMdm:workData];
-
- /* Extract logo URL, if supplied */
- if (workData[@"logo"] != nil && [workData isKindOfClass:[NSDictionary class]]) {
- NSDictionary *logo = workData[@"logo"];
- NSString *oldLogoLightUrl = [MyIdentityStore sharedMyIdentityStore].licenseLogoLightUrl;
- NSString *oldLogoDarkUrl = [MyIdentityStore sharedMyIdentityStore].licenseLogoDarkUrl;
-
- if (logo[@"light"] == [NSNull null])
- [MyIdentityStore sharedMyIdentityStore].licenseLogoLightUrl = nil;
- else
- [MyIdentityStore sharedMyIdentityStore].licenseLogoLightUrl = logo[@"light"];
-
- if (logo[@"dark"] == [NSNull null])
- [MyIdentityStore sharedMyIdentityStore].licenseLogoDarkUrl = nil;
- else
- [MyIdentityStore sharedMyIdentityStore].licenseLogoDarkUrl = logo[@"dark"];
-
- if (oldLogoLightUrl != [MyIdentityStore sharedMyIdentityStore].licenseLogoLightUrl ||
- oldLogoDarkUrl != [MyIdentityStore sharedMyIdentityStore].licenseLogoDarkUrl) {
- [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationColorThemeChanged object:nil];
- }
- }
-
- /* Extract support URL, if supplied */
- if (workData[@"support"] == [NSNull null])
- [MyIdentityStore sharedMyIdentityStore].licenseSupportUrl = nil;
- else
- [MyIdentityStore sharedMyIdentityStore].licenseSupportUrl = workData[@"support"];
-
- /* Process supplied contacts */
- NSArray *workContacts = workData[@"contacts"];
- NSMutableSet *workContactIds = [NSMutableSet set];
- if (workContacts != nil) {
- for (NSDictionary *workContact in workContacts) {
- Contact *contact = [[ContactStore sharedContactStore] addContactWithIdentity:workContact[@"id"] publicKey:[[NSData alloc] initWithBase64EncodedString:workContact[@"pk"] options:0] cnContactId:nil verificationLevel:kVerificationLevelUnverified state:nil type:@1 featureMask:nil alerts:NO];
- if ((contact.firstName == nil && contact.lastName == nil) || contact.cnContactId == nil) {
- if (workContact[@"first"] != nil && workContact[@"first"] != [NSNull null] && workContact[@"last"] != nil && workContact[@"last"] != [NSNull null]) {
- NSString *first = workContact[@"first"];
- NSString *last = workContact[@"last"];
- if (first.length > 0 || last.length > 0) {
- EntityManager *entityManager = [[EntityManager alloc] init];
- [entityManager performSyncBlockAndSafe:^{
- contact.firstName = first;
- contact.lastName = last;
- }];
- }
- }
- }
- [workContactIds addObject:workContact[@"id"]];
- }
- }
-
- [[ContactStore sharedContactStore] updateFeatureMasksForIdentities:[workContactIds allObjects] onCompletion:^{
- } onError:^(NSError *error) {
- }];
-
- /* Get all work verified contacts from DB and set those that have not been supplied in this sync back to non-work */
- NSArray *allContacts = [[ContactStore sharedContactStore] allContacts];
- for (Contact *contact in allContacts) {
- BOOL isWorkContact = [workContactIds containsObject:contact.identity];
- if (contact.workContact == nil || contact.workContact.boolValue != isWorkContact) {
- [[ContactStore sharedContactStore] setWorkContact:contact workContact:isWorkContact];
- }
- }
-
- /* Extract check interval, if supplied */
- NSInteger checkInterval = WORK_DEFAULT_CHECK_INTERVAL;
- if ([workData[@"checkInterval"] isKindOfClass:[NSNumber class]]) {
- NSInteger serverCheckInterval = [((NSNumber*)workData[@"checkInterval"]) integerValue];
- DDLogVerbose(@"Server supplied check interval is %ld", (long)serverCheckInterval);
- if (serverCheckInterval > 0)
- checkInterval = serverCheckInterval;
- }
-
- BOOL refreshWorkContactTableView = false;
-
- /* Check if there is a company directory */
- if (workData[@"directory"] != [NSNull null]) {
- if (workData[@"directory"] != nil) {
- NSDictionary *directory = workData[@"directory"];
- BOOL enableWorkDirectory = [directory[@"enabled"] boolValue];
- if (enableWorkDirectory != [UserSettings sharedUserSettings].companyDirectory) {
- [UserSettings sharedUserSettings].companyDirectory = [directory[@"enabled"] boolValue];
- refreshWorkContactTableView = true;
- }
- [MyIdentityStore sharedMyIdentityStore].directoryCategories = directory[@"cat"];
- } else {
- [UserSettings sharedUserSettings].companyDirectory = false;
- }
- } else {
- [UserSettings sharedUserSettings].companyDirectory = false;
- }
- if (workData[@"org"] != [NSNull null]) {
- NSDictionary *org = workData[@"org"];
- if (org[@"name"] != [NSNull null]) {
- NSString *name = org[@"name"];
- if (![name isEqualToString:[MyIdentityStore sharedMyIdentityStore].companyName]) {
- [MyIdentityStore sharedMyIdentityStore].companyName = name;
- refreshWorkContactTableView = true;
- }
- }
- }
-
- if (refreshWorkContactTableView == true) {
- [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationRefreshWorkContactTableView object:nil];
- }
-
- [defaults setObject:[NSDate date] forKey:@"WorkDataLastSync"];
- [defaults setInteger:checkInterval forKey:@"WorkDataCheckInterval"];
- [defaults synchronize];
- if (onCompletion != nil)
- onCompletion();
- } onError:^(NSError *error) {
- DDLogError(@"Work API fetch failed: %@", error);
- if (onError != nil)
- onError(error);
- }];
- }
- + (void)checkUpdateThreemaMDM:(void(^)(void))onCompletion onError:(void(^)(NSError*))onError {
- NSString *username = [LicenseStore sharedLicenseStore].licenseUsername;
- NSString *password = [LicenseStore sharedLicenseStore].licensePassword;
- if (username != nil && password != nil) {
- NSDictionary *request = @{
- @"username": username,
- @"password": password,
- @"contacts": @[],
- };
- [ServerAPIRequest postJSONToWorkAPIPath:@"fetch2" data:request onCompletion:^(id jsonObject) {
- NSDictionary *workData = (NSDictionary*)jsonObject;
-
- MDMSetup *mdmSetup = [[MDMSetup alloc] initWithSetup:YES];
- [mdmSetup applyThreemaMdm:workData];
-
- onCompletion();
- } onError:^(NSError *error) {
- DDLogError(@"Work API fetch failed: %@", error);
- onError(error);
- }];
- } else {
- onError(nil);
- }
- }
- @end
|