Authorization and Access Control

Authorization and Access Control

Proper authorization ensures authenticated users can only access appropriate resources.

// iOS - Role-based access control implementation
class AuthorizationManager {
    
    enum Role: String, CaseIterable {
        case guest = "guest"
        case user = "user"
        case premium = "premium"
        case admin = "admin"
        
        var level: Int {
            switch self {
            case .guest: return 0
            case .user: return 1
            case .premium: return 2
            case .admin: return 3
            }
        }
    }
    
    enum Permission: String {
        case readPublicContent = "read:public"
        case readPrivateContent = "read:private"
        case writeContent = "write:content"
        case deleteContent = "delete:content"
        case manageUsers = "manage:users"
        case viewAnalytics = "view:analytics"
        case manageBilling = "manage:billing"
    }
    
    struct UserContext {
        let userId: String
        let roles: Set<Role>
        let permissions: Set<Permission>
        let attributes: [String: Any]
        
        func hasRole(_ role: Role) -> Bool {
            return roles.contains(role) || roles.contains(where: { $0.level > role.level })
        }
        
        func hasPermission(_ permission: Permission) -> Bool {
            return permissions.contains(permission)
        }
        
        func hasAnyPermission(_ permissions: Permission...) -> Bool {
            return permissions.contains(where: { hasPermission($0) })
        }
        
        func hasAllPermissions(_ permissions: Permission...) -> Bool {
            return permissions.allSatisfy { hasPermission($0) }
        }
    }
    
    // Attribute-based access control
    func evaluatePolicy(
        user: UserContext,
        resource: Resource,
        action: Action
    ) -> AuthorizationDecision {
        
        // Check basic role requirements
        if let requiredRole = resource.requiredRole {
            guard user.hasRole(requiredRole) else {
                return .deny(reason: "Insufficient role")
            }
        }
        
        // Check specific permissions
        if let requiredPermissions = resource.requiredPermissions {
            guard user.hasAllPermissions(requiredPermissions) else {
                return .deny(reason: "Missing required permissions")
            }
        }
        
        // Evaluate attribute-based policies
        if let policy = resource.policy {
            let decision = evaluateABACPolicy(
                user: user,
                resource: resource,
                action: action,
                policy: policy
            )
            
            if case .deny = decision {
                return decision
            }
        }
        
        // Check time-based restrictions
        if let timeRestriction = resource.timeRestriction {
            guard isWithinTimeRestriction(timeRestriction) else {
                return .deny(reason: "Outside allowed time window")
            }
        }
        
        // Check rate limiting
        if let rateLimit = resource.rateLimit {
            guard checkRateLimit(user: user, resource: resource, limit: rateLimit) else {
                return .deny(reason: "Rate limit exceeded")
            }
        }
        
        return .allow
    }
    
    private func evaluateABACPolicy(
        user: UserContext,
        resource: Resource,
        action: Action,
        policy: ABACPolicy
    ) -> AuthorizationDecision {
        
        // Example: Check if user owns the resource
        if policy.requiresOwnership {
            guard let resourceOwner = resource.attributes["owner"] as? String,
                  resourceOwner == user.userId else {
                return .deny(reason: "Not resource owner")
            }
        }
        
        // Example: Check department match
        if let requiredDepartment = policy.requiredDepartment {
            guard let userDepartment = user.attributes["department"] as? String,
                  userDepartment == requiredDepartment else {
                return .deny(reason: "Department mismatch")
            }
        }
        
        // Example: Check security clearance
        if let requiredClearance = policy.requiredSecurityClearance {
            guard let userClearance = user.attributes["clearance"] as? Int,
                  userClearance >= requiredClearance else {
                return .deny(reason: "Insufficient security clearance")
            }
        }
        
        return .allow
    }
}

enum AuthorizationDecision {
    case allow
    case deny(reason: String)
}

struct Resource {
    let id: String
    let type: String
    let requiredRole: AuthorizationManager.Role?
    let requiredPermissions: [AuthorizationManager.Permission]?
    let policy: ABACPolicy?
    let timeRestriction: TimeRestriction?
    let rateLimit: RateLimit?
    let attributes: [String: Any]
}