cmacoscore-foundationcore-services

How to check if the current user is admin from macOS Xcode using swift?


I tried using identity services tool but seeing multiple errors

CSIdentityRef currentUserIdentity(CFErrorRef *error) {
    CSIdentityQueryRef const query = CSIdentityQueryCreateForCurrentUser(NULL);
    if (!CSIdentityQueryExecute(query, 0 /* flags, none needed */, error)) {
        return NULL;
    }

    CFArrayRef const users = CSIdentityQueryCopyResults(query);
    if (CFArrayGetCount(users) != 1) {
        // TODO: set `*error`
        return NULL;
    }

    return (CSIdentityRef)CFArrayGetValueAtIndex(users, 0);
}

CSIdentityRef adminGroupIdentity(CFErrorRef *error) {
    CSIdentityQueryRef const query = CSIdentityQueryCreateForName(NULL, CFSTR("admin"), kCSIdentityQueryStringEquals, kCSIdentityClassGroup, CSGetDefaultIdentityAuthority());
    if (!CSIdentityQueryExecute(query, 0 /* flags, none needed */, error)) {
        return NULL;
    }

    CFArrayRef const groups = CSIdentityQueryCopyResults(query);
    if (CFArrayGetCount(groups) != 1) {
        // TODO: Set `*error`
        return NULL;
    }

    return (CSIdentityRef)CFArrayGetValueAtIndex(groups, 0);
}

Is there any other way?


Solution

  • This is C code which cannot be executed literally in Swift.

    The translation is

    func currentUserIdentity() -> CSIdentity? {
        guard let query = CSIdentityQueryCreateForCurrentUser(nil) else { return nil }
        let queryRef = query.takeRetainedValue()
        defer { CSIdentityQueryStop(queryRef) }
        guard CSIdentityQueryExecute(queryRef, 0, nil) else { return nil }
        let users = CSIdentityQueryCopyResults(queryRef).takeRetainedValue() as! [CSIdentity]
        return users.first
    }
    
    func adminGroupIdentity() -> CSIdentity? {
        let authority = CSGetDefaultIdentityAuthority().takeUnretainedValue()
        guard let query = CSIdentityQueryCreateForName(nil, "admin" as CFString, kCSIdentityQueryStringEquals, kCSIdentityClassGroup, authority) else { return nil }
        let queryRef = query.takeRetainedValue()
        defer { CSIdentityQueryStop(queryRef) }
        guard CSIdentityQueryExecute(queryRef, 0, nil) else { return nil }
        let admins = CSIdentityQueryCopyResults(queryRef).takeRetainedValue() as! [CSIdentity]
        return admins.first
    }
    
    if let user = currentUserIdentity(),
       let adminGroup = adminGroupIdentity() {
        let memberIsAdmin = CSIdentityIsMemberOfGroup(user, adminGroup)
        let name = CSIdentityGetFullName(user).takeUnretainedValue() as String
        print("current user \(name) is admin:", memberIsAdmin)
    } else {
        print("current user cannot be determined")
    }