A library for handling DID identifiers used in Bluesky AT Protocol

improved PLCOperation validation

+22 -19
+22 -19
lib/didkit/plc_operation.rb
··· 5 class FormatError < StandardError 6 end 7 8 - attr_reader :did, :created_at, :type, :pds_endpoint, :handles 9 10 def initialize(json) 11 @did = json['did'] 12 - raise FormatError, "Missing DID" if @did.nil? 13 - raise FormatError, "Invalid DID" unless @did.is_a?(String) && @did.start_with?('did:') 14 15 timestamp = json['createdAt'] 16 - raise FormatError, "Missing createdAt" if timestamp.nil? 17 - raise FormatError, "Invalid createdAt" unless timestamp.is_a?(String) 18 19 @created_at = Time.parse(timestamp) 20 21 operation = json['operation'] 22 - raise FormatError, "Missing operation key" if operation.nil? 23 - raise FormatError, "Invalid operation data" unless operation.is_a?(Hash) 24 25 type = operation['type'] 26 - raise FormatError, "Missing type" if type.nil? 27 28 @type = type.to_sym 29 return unless @type == :plc_operation 30 31 services = operation['services'] 32 - raise FormatError, "Missing services key" if services.nil? 33 - raise FormatError, "Invalid services data" unless services.is_a?(Hash) 34 35 if pds = services['atproto_pds'] 36 - raise FormatError, "Invalid PDS data" unless pds.is_a?(Hash) 37 - raise FormatError, "Missing PDS type" unless pds['type'] 38 - raise FormatError, "Invalid PDS type" unless pds['type'] == 'AtprotoPersonalDataServer' 39 - raise FormatError, "Missing PDS endpoint" unless pds['endpoint'] 40 - raise FormatError, "Invalid PDS endpoint" unless pds['endpoint'].is_a?(String) && pds['endpoint'] =~ %r(://) 41 42 - @pds_endpoint = pds['endpoint'] 43 end 44 45 if aka = operation['alsoKnownAs'] 46 - raise FormatError, "Invalid alsoKnownAs" unless aka.is_a?(Array) 47 - raise FormatError, "Invalid alsoKnownAs" unless aka.all? { |x| x.is_a?(String) } 48 - raise FormatError, "Invalid alsoKnownAs" unless aka.all? { |x| x =~ %r(\Aat://[^/]+\z) } 49 50 @handles = aka.map { |x| x.gsub('at://', '') } 51 else
··· 5 class FormatError < StandardError 6 end 7 8 + attr_reader :json, :did, :created_at, :type, :pds_endpoint, :handles 9 10 def initialize(json) 11 + @json = json 12 @did = json['did'] 13 + raise FormatError, "Missing DID: #{json}" if @did.nil? 14 + raise FormatError, "Invalid DID: #{@did}" unless @did.is_a?(String) && @did.start_with?('did:') 15 16 timestamp = json['createdAt'] 17 + raise FormatError, "Missing createdAt: #{json}" if timestamp.nil? 18 + raise FormatError, "Invalid createdAt: #{timestamp.inspect}" unless timestamp.is_a?(String) 19 20 @created_at = Time.parse(timestamp) 21 22 operation = json['operation'] 23 + raise FormatError, "Missing operation key: #{json}" if operation.nil? 24 + raise FormatError, "Invalid operation data: #{operation.inspect}" unless operation.is_a?(Hash) 25 26 type = operation['type'] 27 + raise FormatError, "Missing operation type: #{json}" if type.nil? 28 29 @type = type.to_sym 30 return unless @type == :plc_operation 31 32 services = operation['services'] 33 + raise FormatError, "Missing services key: #{json}" if services.nil? 34 + raise FormatError, "Invalid services data: #{services}" unless services.is_a?(Hash) 35 36 if pds = services['atproto_pds'] 37 + raise FormatError, "Invalid PDS data: #{pds.inspect}" unless pds.is_a?(Hash) 38 + raise FormatError, "Missing PDS type: #{pds.inspect}" unless pds['type'] 39 + raise FormatError, "Invalid PDS type: #{pds['type']}" unless pds['type'] == 'AtprotoPersonalDataServer' 40 41 + endpoint = pds['endpoint'] 42 + raise FormatError, "Missing PDS endpoint: #{pds.inspect}" unless endpoint 43 + raise FormatError, "Invalid PDS endpoint: #{endpoint}" unless endpoint.is_a?(String) && endpoint =~ %r(://) 44 + 45 + @pds_endpoint = endpoint 46 end 47 48 if aka = operation['alsoKnownAs'] 49 + raise FormatError, "Invalid alsoKnownAs: #{aka.inspect}" unless aka.is_a?(Array) 50 + raise FormatError, "Invalid alsoKnownAs: #{aka.inspect}" unless aka.all? { |x| x.is_a?(String) } 51 + raise FormatError, "Invalid alsoKnownAs: #{aka.inspect}" unless aka.all? { |x| x =~ %r(\Aat://[^/]+\z) } 52 53 @handles = aka.map { |x| x.gsub('at://', '') } 54 else