l402_middleware 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/l402_middleware.rb +145 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 70f9855a816d04309f2ec16eb94b5f0385a17c8a4ca6588716f4a136ee29bbc5
|
4
|
+
data.tar.gz: f8185f1bb22374bbf2f5f541569fec57b508d2761082b8d070b9dcd97d555f5f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a2e01af0cac5c6db1ad99f1cff29bfcacd13ec99ee9f96e3f00ac51f066a9f0a4021cabfb4cf50f5be2dfcd1092b3f719d3c92227bd95dd5c391b946a8e2bbab
|
7
|
+
data.tar.gz: c91b2f77ea8ac6322d7236039c15a90e73dd9848a64f1212e054102b1bac806d0a5eb4d636ca3677b25c806a541579cd30ba4b652c7d235dc73b859998ee523d
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require 'l402'
|
5
|
+
require 'l402_logger'
|
6
|
+
require 'l402_config'
|
7
|
+
require 'utils'
|
8
|
+
require 'constants'
|
9
|
+
|
10
|
+
module L402Middleware
|
11
|
+
class << self
|
12
|
+
attr_accessor :configuration
|
13
|
+
end
|
14
|
+
|
15
|
+
class Middleware
|
16
|
+
def initialize(app, config = nil)
|
17
|
+
@app = app
|
18
|
+
@config = L402Middleware::Configuration.new(config || default_config)
|
19
|
+
|
20
|
+
@config.validate!
|
21
|
+
|
22
|
+
verify_connect
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(env)
|
26
|
+
token = extract_auth_token(env)
|
27
|
+
is_valid_l402_token, err = valid_l402_token?(token)
|
28
|
+
|
29
|
+
if free?(env['REQUEST_PATH'].to_s) || (is_valid_l402_token.to_s == "true" && err.nil?)
|
30
|
+
return allow_request(env)
|
31
|
+
end
|
32
|
+
|
33
|
+
invoke_payment(env[L402_AUTHORIZATION_HEADER].present?)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def default_config
|
39
|
+
if defined?(Rails)
|
40
|
+
config = Rails.configuration.try(:l402_middleware)
|
41
|
+
unless config
|
42
|
+
raise 'Rails configuration for L402Middleware is missing. Please pass config along with the L402Middleware'
|
43
|
+
end
|
44
|
+
|
45
|
+
config
|
46
|
+
else
|
47
|
+
unless L402Middleware.configuration
|
48
|
+
raise 'Configuration required for standalone mode. Use L402Middleware.configuration to set it.'
|
49
|
+
end
|
50
|
+
|
51
|
+
L402Middleware.configuration
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def extract_auth_token(env)
|
56
|
+
auth_header = env[L402_AUTHORIZATION_HEADER]
|
57
|
+
auth_header&.strip
|
58
|
+
end
|
59
|
+
|
60
|
+
# Example token: L402 AGIAJEemVQUTEyNCR0exk7ek90Cg==:1234abcd1234abcd1234abcd
|
61
|
+
def valid_l402_token?(token)
|
62
|
+
return [false, 'missing L02 header'] unless token.to_s.downcase.start_with?("#{L402_HEADER} ")
|
63
|
+
|
64
|
+
token = token.sub(sub_l402_header_regex, "")
|
65
|
+
|
66
|
+
macaroon_part, preimage = token.split(':', 2)
|
67
|
+
|
68
|
+
return [false, 'missing macaroon or primage'] if macaroon_part.blank? || preimage.blank?
|
69
|
+
|
70
|
+
macaroons = macaroon_part.split(',').map(&:strip)
|
71
|
+
|
72
|
+
macaroons.each do |macaroon|
|
73
|
+
decoded_macaroon = Base64.strict_decode64(macaroon)
|
74
|
+
result, err = L402.verify_l402(decoded_macaroon, preimage, @config)
|
75
|
+
|
76
|
+
return [true, nil] if result.to_s == "true" && err.nil?
|
77
|
+
rescue StandardError => e
|
78
|
+
L402Logger.error("Error verifying macaroon: #{e.message}")
|
79
|
+
return [false, "error verifying macaroon: #{e.message}"]
|
80
|
+
end
|
81
|
+
|
82
|
+
return [false, 'unauthorized']
|
83
|
+
end
|
84
|
+
|
85
|
+
def allow_request(env)
|
86
|
+
@status, @headers, @response = @app.call(env)
|
87
|
+
[@status, @headers, @response]
|
88
|
+
end
|
89
|
+
|
90
|
+
def invoke_payment(is_unauthorized = false)
|
91
|
+
macaroon, invoice = L402.get_payment_request_details(@config)
|
92
|
+
|
93
|
+
status = 402
|
94
|
+
header = {
|
95
|
+
'Content-Type' => 'application/json',
|
96
|
+
L402_CHALLENGE_HEADER => get_payment_header(macaroon, invoice)
|
97
|
+
}
|
98
|
+
response = is_unauthorized ? unauthorized_response : request_payment_response(macaroon, invoice)
|
99
|
+
|
100
|
+
[status, header, [response]]
|
101
|
+
end
|
102
|
+
|
103
|
+
def verify_connect
|
104
|
+
case @config.network_type
|
105
|
+
when :lnd
|
106
|
+
connect_to_lnd
|
107
|
+
when :lnurl
|
108
|
+
connect_to_lnurl
|
109
|
+
else
|
110
|
+
raise "Unsupported network type: #{@config.network_type}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def connect_to_lnd
|
115
|
+
lnd_config = @config.lnd
|
116
|
+
|
117
|
+
begin
|
118
|
+
Lighstorm.connect!(
|
119
|
+
address: lnd_config[:address],
|
120
|
+
certificate_path: lnd_config[:tls_certificate_path],
|
121
|
+
macaroon_path: lnd_config[:macaroon_path]
|
122
|
+
)
|
123
|
+
L402Logger.info('Successfully connected to LND network')
|
124
|
+
rescue StandardError => e
|
125
|
+
L402Logger.error("Failed to connect to LND: #{e.message}\n#{e.backtrace.join("\n")}")
|
126
|
+
raise "Unable to establish connection with Lightning network: #{e.message}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Placeholder method
|
131
|
+
def connect_to_lnurl
|
132
|
+
@config.lnurl
|
133
|
+
raise 'integration with lnurl is WIP'
|
134
|
+
end
|
135
|
+
|
136
|
+
def free?(request)
|
137
|
+
@config.endpoints.each do |endpoint|
|
138
|
+
L402Logger.info("ENDPOINT: #{endpoint}, request :#{request}, regex: #{@config.endpoints}")
|
139
|
+
return false unless Regexp.new(endpoint).match(request).nil?
|
140
|
+
end
|
141
|
+
|
142
|
+
true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: l402_middleware
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ritik Jain
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: google-protobuf
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.25.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.25.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: lighstorm
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: macaroons
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: A Ruby middleware implementation for the L402 protocol, leveraging macaroons
|
70
|
+
and the Lightning Network for secure authentication and payments.
|
71
|
+
email: ritikjain1272@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/l402_middleware.rb
|
77
|
+
homepage: https://rubygems.org/gems/l402_middleware
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata:
|
81
|
+
source_code_uri: https://github.com/rits1272/l402_middleware
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubygems_version: 3.2.3
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: L402 middleware for authentication and payment handling
|
101
|
+
test_files: []
|