Skip to content

Commit

Permalink
optional configuration without environment variables
Browse files Browse the repository at this point in the history
  • Loading branch information
trusche committed Aug 8, 2024
1 parent 83c9c8d commit b0ce8f8
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 23 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ If you followed the installation steps, you already saw that Passkit provides
you the tables and ActiveRecord models, and also an engine with the necessary APIs already implemented.

Now is your turn. Before proceeding, you need to set these ENV variables:

* `PASSKIT_WEB_SERVICE_HOST`
* `PASSKIT_CERTIFICATE_KEY`
* `PASSKIT_PRIVATE_P12_CERTIFICATE`
Expand All @@ -68,6 +69,26 @@ Now is your turn. Before proceeding, you need to set these ENV variables:
We have a [specific guide on how to get all these](docs/passkit_environment_variables.md), please follow it.
You cannot start using this library without these variables set, and we cannot do the work for you.

Alternatively, you can configure passkit with an initializer, where you can use environment variables, Rails secrets,
or any other source for the required credentials:

```ruby
Passkit.configure do |config|
# Required, no defaults
config.apple_team_identifier = "dummy ID"
config.certificate_key = "dummy key"
config.private_p12_certificate = "path/to/file"
config.apple_intermediate_certificate = "path/to/file"
config.pass_type_identifier = "pass.com.some.id"

# Optional, defaults shown
config.dashboard_username = nil
config.dashboard_password = nil
config.skip_verification = false # Unless true, throws exceptions on startup when a required configuration is missing
config.web_service_host = "https://localhost:3000"
config.available_passes = { "Passkit::ExampleStoreCard" => -> {} }
end

## Usage

If you followed the installation steps and you have the ENV variables set, we can start looking at what is provided for you.
Expand Down
58 changes: 48 additions & 10 deletions lib/passkit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ class << self
def self.configure
self.configuration ||= Configuration.new
yield(configuration) if block_given?
configuration.verify!
end

def self.configured?
self.configuration&.configured?
end

class Configuration
Expand All @@ -27,11 +32,24 @@ class Configuration
:private_p12_certificate,
:apple_intermediate_certificate,
:apple_team_identifier,
:pass_type_identifier
:pass_type_identifier,
:dashboard_username,
:dashboard_password,
:format_version,
:skip_verification

REQUIRED_ATTRIBUTES = %i[
web_service_host
certificate_key
private_p12_certificate
apple_intermediate_certificate
apple_team_identifier
pass_type_identifier
]

DEFAULT_AUTHENTICATION = proc do
authenticate_or_request_with_http_basic("Passkit Dashboard. Login required") do |username, password|
username == ENV["PASSKIT_DASHBOARD_USERNAME"] && password == ENV["PASSKIT_DASHBOARD_PASSWORD"]
username == Passkit.configuration.dashboard_username && password == Passkit.configuration.dashboard_password
end
end
def authenticate_dashboard_with(&block)
Expand All @@ -40,14 +58,34 @@ def authenticate_dashboard_with(&block)
end

def initialize
@available_passes = {"Passkit::ExampleStoreCard" => -> {}}
@web_service_host = ENV["PASSKIT_WEB_SERVICE_HOST"] || (raise "Please set PASSKIT_WEB_SERVICE_HOST")
raise("PASSKIT_WEB_SERVICE_HOST must start with https://") unless @web_service_host.start_with?("https://")
@certificate_key = ENV["PASSKIT_CERTIFICATE_KEY"] || (raise "Please set PASSKIT_CERTIFICATE_KEY")
@private_p12_certificate = ENV["PASSKIT_PRIVATE_P12_CERTIFICATE"] || (raise "Please set PASSKIT_PRIVATE_P12_CERTIFICATE")
@apple_intermediate_certificate = ENV["PASSKIT_APPLE_INTERMEDIATE_CERTIFICATE"] || (raise "Please set PASSKIT_APPLE_INTERMEDIATE_CERTIFICATE")
@apple_team_identifier = ENV["PASSKIT_APPLE_TEAM_IDENTIFIER"] || (raise "Please set PASSKIT_APPLE_TEAM_IDENTIFIER")
@pass_type_identifier = ENV["PASSKIT_PASS_TYPE_IDENTIFIER"] || (raise "Please set PASSKIT_PASS_TYPE_IDENTIFIER")
# Required
@certificate_key = ENV["PASSKIT_CERTIFICATE_KEY"]
@private_p12_certificate = ENV["PASSKIT_PRIVATE_P12_CERTIFICATE"]
@apple_intermediate_certificate = ENV["PASSKIT_APPLE_INTERMEDIATE_CERTIFICATE"]
@apple_team_identifier = ENV["PASSKIT_APPLE_TEAM_IDENTIFIER"]
@pass_type_identifier = ENV["PASSKIT_PASS_TYPE_IDENTIFIER"]

# Optional
@skip_verification = false
@web_service_host = ENV["PASSKIT_WEB_SERVICE_HOST"] || "https://localhost:3000"
@available_passes = { "Passkit::ExampleStoreCard" => -> {} }
@format_version = ENV["PASSKIT_FORMAT_VERSION"] || 1
@dashboard_username = ENV["PASSKIT_DASHBOARD_USERNAME"]
@dashboard_password = ENV["PASSKIT_DASHBOARD_PASSWORD"]
end

def configured?
REQUIRED_ATTRIBUTES.all? { |attr| send(attr).present? }
end

def verify!
return if skip_verification

REQUIRED_ATTRIBUTES.each do |attr|
raise Error, "Please set #{attr.upcase}" unless send(attr).present?
end

raise Error, "PASSKIT_WEB_SERVICE_HOST must start with https://" unless web_service_host.start_with?("https://")
end
end
end
9 changes: 4 additions & 5 deletions lib/passkit/base_pass.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ def initialize(generator = nil)
end

def format_version
ENV["PASSKIT_FORMAT_VERSION"] || 1
Passkit.configuration.format_version
end

def apple_team_identifier
ENV["PASSKIT_APPLE_TEAM_IDENTIFIER"] || raise(Error.new("Missing environment variable: PASSKIT_APPLE_TEAM_IDENTIFIER"))
Passkit.configuration.apple_team_identifier
end

def pass_type_identifier
ENV["PASSKIT_PASS_TYPE_IDENTIFIER"] || raise(Error.new("Missing environment variable: PASSKIT_PASS_TYPE_IDENTIFIER"))
Passkit.configuration.pass_type_identifier
end

def language
Expand Down Expand Up @@ -43,8 +43,7 @@ def pass_type
end

def web_service_url
raise Error.new("Missing environment variable: PASSKIT_WEB_SERVICE_HOST") unless ENV["PASSKIT_WEB_SERVICE_HOST"]
"#{ENV["PASSKIT_WEB_SERVICE_HOST"]}/passkit/api"
"#{Passkit.configuration.web_service_host}/passkit/api"
end

# The foreground color, used for the values of fields shown on the front of the pass.
Expand Down
16 changes: 9 additions & 7 deletions lib/passkit/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ def generate_json_pass
File.write(@temporary_path.join("pass.json"), pass.to_json)
end

# rubocop:enable Metrics/AbcSize

def generate_json_manifest
manifest = {}
Dir.glob(@temporary_path.join("**")).each do |file|
Expand All @@ -123,14 +121,18 @@ def generate_json_manifest
File.write(@manifest_url, manifest.to_json)
end

CERTIFICATE = Rails.root.join(ENV["PASSKIT_PRIVATE_P12_CERTIFICATE"])
INTERMEDIATE_CERTIFICATE = Rails.root.join(ENV["PASSKIT_APPLE_INTERMEDIATE_CERTIFICATE"])
CERTIFICATE_PASSWORD = ENV["PASSKIT_CERTIFICATE_KEY"]
def certificate_path
Rails.root.join(Passkit.configuration.private_p12_certificate)
end

def intermediate_certificate_path
Rails.root.join(Passkit.configuration.apple_intermediate_certificate)
end

# :nocov:
def sign_manifest
p12_certificate = OpenSSL::PKCS12.new(File.read(CERTIFICATE), CERTIFICATE_PASSWORD)
intermediate_certificate = OpenSSL::X509::Certificate.new(File.read(INTERMEDIATE_CERTIFICATE))
p12_certificate = OpenSSL::PKCS12.new(File.read(certificate_path), Passkit.configuration.certificate_key)
intermediate_certificate = OpenSSL::X509::Certificate.new(File.read(intermediate_certificate_path))

flag = OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY
signed = OpenSSL::PKCS7.sign(p12_certificate.certificate,
Expand Down
2 changes: 1 addition & 1 deletion lib/passkit/url_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class UrlGenerator
include Passkit::Engine.routes.url_helpers

def initialize(pass_class, generator = nil, collection_name = nil)
@url = passes_api_url(host: ENV["PASSKIT_WEB_SERVICE_HOST"],
@url = passes_api_url(host: Passkit.configuration.web_service_host,
payload: PayloadGenerator.encrypted(pass_class, generator, collection_name))
end

Expand Down

0 comments on commit b0ce8f8

Please sign in to comment.