Convert script policy to ObjC

This commit is contained in:
James Magahern
2021-10-21 11:05:40 -07:00
parent 31787f57ae
commit 70486c49de
11 changed files with 206 additions and 92 deletions

View File

@@ -30,6 +30,10 @@ class ResourcePolicyManager: NSObject, SBRResourceOriginPolicyDataSource
func allowedOriginsForScriptResources() -> Set<String> { allowedOriginSet }
func scriptPolicyTypeByOrigin() -> [String : NSNumber] {
return scriptPolicies.mapValues { NSNumber(integerLiteral: $0.rawValue) }
}
private lazy var scriptPolicies: Dictionary<String, ScriptPolicy.PolicyType> = {
if let existingDict = UserDefaults.standard.dictionary(forKey: Self.OriginPoliciesDefaultsKey) as? Dictionary<String, Int> {
return existingDict.mapValues { ScriptPolicy.PolicyType(rawValue: $0)! }
@@ -53,10 +57,10 @@ class ResourcePolicyManager: NSObject, SBRResourceOriginPolicyDataSource
func scriptPolicy(forOrigin origin: String) -> ScriptPolicy {
if let policyType = scriptPolicies[origin] {
return ScriptPolicy(policyType: policyType, securityOrigin: origin)
return ScriptPolicy(securityOrigin: origin, policyType: policyType)
}
return ScriptPolicy(policyType: .alpha, securityOrigin: origin)
return ScriptPolicy(securityOrigin: origin, policyType: .alpha)
}
func setScriptPolicyType(_ policyType: ScriptPolicy.PolicyType, forOrigin origin: String) {

View File

@@ -1,84 +0,0 @@
//
// ScriptPolicy.swift
// App
//
// Created by James Magahern on 9/29/21.
//
import UIKit
struct ScriptPolicy: Hashable {
enum PolicyType: Int, CaseIterable {
case alpha
case bravo
case charlie
case delta
case echo
}
public let policyType: PolicyType
public let securityOrigin: String
public static func title(forPolicyType type: PolicyType) -> String {
switch type {
case .alpha: return "Alpha"
case .bravo: return "Bravo"
case .charlie: return "Charlie"
case .delta: return "Delta"
case .echo: return "Echo"
}
}
public static func localizedDescription(forPolicyType type: PolicyType) -> String {
switch type {
case .alpha:
return "All scripts blocked."
case .bravo:
return "Scripts on page are allowed."
case .charlie:
return "Allow scripts from the same security origin."
case .delta:
return "Allow scripts from common and host CDNs."
case .echo:
return "All scripts are allowed."
}
}
public static func iconRepresentation(forPolicyType type: PolicyType, size: CGSize) -> UIImage? {
let font = UIFont.boldSystemFont(ofSize: size.height - 2)
let attrs: [NSAttributedString.Key : Any] = [
.font : font,
.foregroundColor: UIColor.white,
]
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
if let _ = UIGraphicsGetCurrentContext() {
let backgroundPath = UIBezierPath.init(roundedRect: rect, cornerRadius: 4.0)
// backgroundPath.usesEvenOddFillRule = true
backgroundPath.fill()
let character = NSString(string: { () -> String in
switch type {
case .alpha: return "𝝰"
case .bravo: return "𝝱"
case .charlie: return "𝝲"
case .delta: return "𝝳"
case .echo: return "𝝴"
}
}())
let charSize = character.size(withAttributes: attrs)
let charRect = CGRect(origin: .init(x: (size.width - charSize.width) / 2 ,
y: -(charSize.height - size.height) / 2),
size: charSize)
character.draw(in: charRect, withAttributes: attrs)
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}

View File

@@ -7,6 +7,16 @@
import UIKit
extension ScriptPolicy.PolicyType : CaseIterable {
public static var allCases: [ScriptPolicy.PolicyType] = [
.alpha,
.bravo,
.charlie,
.delta,
.echo
]
}
class ScriptPolicyViewController: UIViewController, UICollectionViewDelegate
{
var collectionView: UICollectionView?

View File

@@ -3,6 +3,7 @@
//
#import "SBRProcessBundleBridge.h"
#import "SBRScriptPolicy.h"
// SPI
#import <UIKit/UITextField_Private.h>

View File

@@ -15,6 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
/// Returns a list of origins (e.g., "buzzert.net") for which we are allowed to load script resources from
- (NSSet<NSString *> *)allowedOriginsForScriptResources;
/// Returns a mapping between origin and SBRScriptOriginPolicyType, encoded as an NSNumber.
- (NSDictionary<NSString *, NSNumber *> *)scriptPolicyTypeByOrigin;
@end
@class SBRProcessBundleBridge;

View File

@@ -161,6 +161,10 @@
NSArray<NSString *> *allowedOrigins = [[_policyDataSource allowedOriginsForScriptResources] allObjects];
[_processPool _setObject:allowedOrigins forBundleParameter:SBRGetAllowedOriginsKey()];
[_webProcessProxy syncAllowedResourceOrigins:allowedOrigins];
NSDictionary<NSString *, NSNumber *> *policyTypes = [_policyDataSource scriptPolicyTypeByOrigin];
[_processPool _setObject:policyTypes forBundleParameter:SBRGetPolicyTypeByOriginKey()];
[_webProcessProxy syncPolicyTypes:policyTypes];
}
- (void)setAllowAllScripts:(BOOL)allowAllScripts

View File

@@ -0,0 +1,41 @@
//
// SBRScriptPolicy.h
// App
//
// Created by James Magahern on 10/15/21.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class UIImage;
typedef NS_ENUM(NSInteger, SBRScriptOriginPolicyType) {
SBRScriptOriginPolicyTypeAlpha,
SBRScriptOriginPolicyTypeBravo,
SBRScriptOriginPolicyTypeCharlie,
SBRScriptOriginPolicyTypeDelta,
SBRScriptOriginPolicyTypeEcho,
} NS_SWIFT_NAME(ScriptPolicy.PolicyType);
NS_SWIFT_NAME(ScriptPolicy)
@interface SBRScriptPolicy : NSObject <NSSecureCoding>
@property (nonatomic, copy) NSString *origin;
@property (nonatomic, readwrite) SBRScriptOriginPolicyType policyType;
+ (NSString *)titleForPolicyType:(SBRScriptOriginPolicyType)policyType
NS_SWIFT_NAME(title(forPolicyType:));
+ (NSString *)localizedDescriptionForPolicyType:(SBRScriptOriginPolicyType)policyType
NS_SWIFT_NAME(localizedDescription(forPolicyType:));
+ (UIImage *)iconRepresentationForPolicyType:(SBRScriptOriginPolicyType)policyType withSize:(CGSize)size
NS_SWIFT_NAME(iconRepresentation(forPolicyType:size:));
- (instancetype)initWithSecurityOrigin:(NSString *)origin policyType:(SBRScriptOriginPolicyType)policyType;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,121 @@
//
// SBRScriptPolicy.m
// App
//
// Created by James Magahern on 10/15/21.
//
#import "SBRScriptPolicy.h"
// For icon drawing
#import <UIKit/UIKit.h>
@implementation SBRScriptPolicy
+ (NSString *)titleForPolicyType:(SBRScriptOriginPolicyType)policyType
{
switch (policyType) {
case SBRScriptOriginPolicyTypeAlpha:
return @"Alpha";
case SBRScriptOriginPolicyTypeBravo:
return @"Bravo";
case SBRScriptOriginPolicyTypeCharlie:
return @"Charlie";
case SBRScriptOriginPolicyTypeDelta:
return @"Delta";
case SBRScriptOriginPolicyTypeEcho:
return @"Echo";
}
}
+ (NSString *)localizedDescriptionForPolicyType:(SBRScriptOriginPolicyType)policyType
{
switch (policyType) {
case SBRScriptOriginPolicyTypeAlpha:
return @"All scripts blocked.";
case SBRScriptOriginPolicyTypeBravo:
return @"Scripts on page are allowed.";
case SBRScriptOriginPolicyTypeCharlie:
return @"Allow scripts from the same security origin.";
case SBRScriptOriginPolicyTypeDelta:
return @"Allow scripts from common and host CDNs.";
case SBRScriptOriginPolicyTypeEcho:
return @"All scripts are allowed.";
}
}
+ (UIImage *)iconRepresentationForPolicyType:(SBRScriptOriginPolicyType)policyType withSize:(CGSize)size
{
UIFont *font = [UIFont boldSystemFontOfSize:size.height - 2];
NSDictionary<NSAttributedStringKey, id> *attrs = @{
NSFontAttributeName : font,
NSForegroundColorAttributeName : [UIColor whiteColor]
};
const CGRect rect = (CGRect) { .origin = CGPointZero, .size = size };
UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
UIBezierPath *backgroundPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4.0];
[backgroundPath fill];
NSString *character = @"";
switch (policyType) {
case SBRScriptOriginPolicyTypeAlpha:
character = @"𝝰"; break;
case SBRScriptOriginPolicyTypeBravo:
character = @"𝝱"; break;
case SBRScriptOriginPolicyTypeCharlie:
character = @"𝝲"; break;
case SBRScriptOriginPolicyTypeDelta:
character = @"𝝳"; break;
case SBRScriptOriginPolicyTypeEcho:
character = @"𝝴"; break;
}
const CGSize charSize = [character sizeWithAttributes:attrs];
const CGRect charRect = (CGRect) {
.origin = (CGPoint) {
.x = (size.width - charSize.width) / 2,
.y = -(charSize.height - size.height) / 2,
},
.size = charSize
};
[character drawInRect:charRect withAttributes:attrs];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (instancetype)initWithSecurityOrigin:(NSString *)origin policyType:(SBRScriptOriginPolicyType)policyType
{
if (self = [super init]) {
_origin = [origin copy];
_policyType = policyType;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
NSString *origin = [coder decodeObjectForKey:@"origin"];
NSNumber *policyTypeNumber = [coder decodeObjectForKey:@"policyType"];
return [self initWithSecurityOrigin:origin policyType:[policyTypeNumber integerValue]];
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_origin forKey:@"origin"];
[coder encodeObject:[NSNumber numberWithInteger:_policyType] forKey:@"policyType"];
}
@end