1/*
2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25#include <stdio.h>
26#include "SOSAccountPriv.h"
27#include <SecureObjectSync/SOSPeerInfoCollections.h>
28
29
30bool SOSAccountDestroyCirclePeerInfoNamed(SOSAccountRef account, CFStringRef name, CFErrorRef* error) {
31    if (CFDictionaryGetValue(account->circles, name) == NULL) {
32        SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("No circle named '%@'"), name);
33        return false;
34    }
35
36    SOSFullPeerInfoRef circle_full_peer_info = (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, name);
37
38    if (circle_full_peer_info) {
39        SOSFullPeerInfoPurgePersistentKey(circle_full_peer_info, NULL);
40    }
41
42    CFDictionaryRemoveValue(account->circle_identities, name);
43
44    return true;
45}
46
47bool SOSAccountDestroyCirclePeerInfo(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
48    return SOSAccountDestroyCirclePeerInfoNamed(account, SOSCircleGetName(circle), error);
49}
50
51SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
52    SOSFullPeerInfoRef fpi =  SOSAccountGetMyFullPeerInCircleNamed(account, SOSCircleGetName(circle), error);
53
54    return fpi ? SOSFullPeerInfoGetPeerInfo(fpi) : NULL;
55}
56
57SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error)
58{
59    SOSFullPeerInfoRef fpi =  SOSAccountGetMyFullPeerInCircleNamed(account, name, error);
60
61    return fpi ? SOSFullPeerInfoGetPeerInfo(fpi) : NULL;
62}
63
64
65bool SOSAccountIsActivePeerInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFStringRef peerid, CFErrorRef* error) {
66    SOSCircleRef circle = SOSAccountFindCircle(account, circle_name, error);
67    if(!circle) return false;
68    return SOSCircleHasActivePeerWithID(circle, peerid, error);
69}
70
71bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
72    SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, SOSCircleGetName(circle), NULL);
73    if(!fpi) return false;
74    return SOSCircleHasActivePeer(circle, SOSFullPeerInfoGetPeerInfo(fpi), error);
75}
76
77bool SOSAccountIsMyPeerActiveInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFErrorRef* error) {
78    SOSFullPeerInfoRef myfpi = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, circle_name, NULL);
79    if(!myfpi) return false;
80    SOSPeerInfoRef mypi = SOSFullPeerInfoGetPeerInfo(myfpi);
81    if(!mypi) return false;
82    CFStringRef peerid = SOSPeerInfoGetPeerID(mypi);
83    if (!peerid) return false;
84    return SOSAccountIsActivePeerInCircleNamed(account, circle_name, peerid, error);
85}
86
87
88//
89// MARK: Peer Querying
90//
91static CFArrayRef SOSAccountCopySortedPeerArray(SOSAccountRef account,
92                                                CFErrorRef *error,
93                                                void (^action)(SOSCircleRef circle, CFMutableArrayRef appendPeersTo)) {
94    if (!SOSAccountHasPublicKey(account, error))
95        return NULL;
96
97    CFMutableArrayRef peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
98
99    SOSAccountForEachCircle(account, ^(SOSCircleRef circle) {
100        action(circle, peers);
101    });
102
103    CFArrayOfSOSPeerInfosSortByID(peers);
104
105    return peers;
106}
107
108
109CFArrayRef SOSAccountCopyNotValidPeers(SOSAccountRef account, CFErrorRef *error) {
110    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
111        SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
112            if(!SOSPeerInfoApplicationVerify(peer, account->user_public, NULL)) {
113                CFArrayAppendValue(appendPeersTo, peer);
114            }
115        });
116    });
117}
118
119
120CFArrayRef SOSAccountCopyValidPeers(SOSAccountRef account, CFErrorRef *error) {
121    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
122        SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
123            if(SOSPeerInfoApplicationVerify(peer, account->user_public, NULL)) {
124                CFArrayAppendValue(appendPeersTo, peer);
125            }
126        });
127    });
128}
129
130
131CFArrayRef SOSAccountCopyRetired(SOSAccountRef account, CFErrorRef *error) {
132    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
133        SOSCircleForEachRetiredPeer(circle, ^(SOSPeerInfoRef peer) {
134            CFArrayAppendValue(appendPeersTo, peer);
135        });
136    });
137}
138
139CFArrayRef SOSAccountCopyApplicants(SOSAccountRef account, CFErrorRef *error) {
140    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
141        SOSCircleForEachApplicant(circle, ^(SOSPeerInfoRef peer) {
142            CFArrayAppendValue(appendPeersTo, peer);
143        });
144    });
145}
146
147CFArrayRef SOSAccountCopyPeers(SOSAccountRef account, CFErrorRef *error) {
148    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
149        SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
150            CFArrayAppendValue(appendPeersTo, peer);
151        });
152    });
153}
154
155CFArrayRef SOSAccountCopyActivePeers(SOSAccountRef account, CFErrorRef *error) {
156    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
157        SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
158            CFArrayAppendValue(appendPeersTo, peer);
159        });
160    });
161}
162
163CFArrayRef SOSAccountCopyActiveValidPeers(SOSAccountRef account, CFErrorRef *error) {
164    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
165        SOSCircleForEachActiveValidPeer(circle, account->user_public, ^(SOSPeerInfoRef peer) {
166            CFArrayAppendValue(appendPeersTo, peer);
167        });
168    });
169}
170
171CFArrayRef SOSAccountCopyConcurringPeers(SOSAccountRef account, CFErrorRef *error)
172{
173    return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
174        SOSCircleAppendConcurringPeers(circle, appendPeersTo, NULL);
175    });
176}
177