Class: OmniAuth::Strategies::Atproto

Inherits:
OAuth2
  • Object
show all
Defined in:
lib/omniauth/strategies/atproto.rb

Class Method Summary collapse

Class Method Details

.get_authorization_data(issuer) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/omniauth/strategies/atproto.rb', line 88

def self.get_authorization_data(issuer)
  response = Faraday.get("#{issuer}/.well-known/oauth-authorization-server")

  unless response.success?
    fail!(:invalid_metadata,
          OmniAuth::Error.new(
            "Failed to get authorization server metadata: #{response.status}"
          ))
  end
  result = JSON.parse(response.body)

  unless result['issuer'] == issuer
    fail!(:invalid_metadata,
          OmniAuth::Error.new('Invalid metadata - issuer mismatch'))
  end
  # we cannot keep everything in session (cookie overflow error)
  fields = %w[issuer authorization_endpoint token_endpoint]
  result.select { |k, _v| fields.include?(k) }
end

.get_authorization_server(pds_endpoint) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/omniauth/strategies/atproto.rb', line 68

def self.get_authorization_server(pds_endpoint)
  response = Faraday.get("#{pds_endpoint}/.well-known/oauth-protected-resource")

  unless response.success?
    fail!(:invalid_auth_server,
          OmniAuth::Error.new(
            "Failed to get PDS authorization server: #{response.status}"
          ))
  end

  result = JSON.parse(response.body)

  auth_server = result.dig('authorization_servers', 0)
  unless auth_server
    fail!(:invalid_auth_server,
          OmniAuth::Error.new('No authorization server found in response'))
  end
  auth_server
end

.setupObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/omniauth/strategies/atproto.rb', line 22

def self.setup
  lambda do |env|
    session = env["rack.session"]

    if env["rack.request.form_hash"] && handle = env["rack.request.form_hash"]["handle"]
      resolver = DIDKit::Resolver.new
      did = resolver.resolve_handle(handle)

      unless did
        env['omniauth.strategy'].fail!(:unknown_handle,
          OmniAuth::Error.new(
            'Handle parameter did not resolve to a did'
          ))
      end

      endpoint = resolver.resolve_did(did).pds_endpoint
      auth_server = get_authorization_server(endpoint)
      session["authorization_info"] = authorization_info = get_authorization_data(auth_server)
    end
    
    if authorization_info ||= session.delete("authorization_info")
      env['omniauth.strategy'].options["client_options"]["site"] = authorization_info["issuer"]
      env['omniauth.strategy'].options["client_options"]["authorize_url"] = authorization_info['authorization_endpoint']
      env['omniauth.strategy'].options["client_options"]["token_url"] = authorization_info['token_endpoint']
    end
  end
end