Skip to content

Instantly share code, notes, and snippets.

View AndrewDryga's full-sized avatar

Andrew Dryga AndrewDryga

View GitHub Profile
defmodule OpenIDConnect do
@moduledoc """
Handles a majority of the life-cycle concerns with [OpenID Connect](http://openid.net/connect/)
"""
alias OpenIDConnect.Document
@typedoc """
URL to a [OpenID Discovery Document](https://openid.net/specs/openid-connect-discovery-1_0.html) endpoint.
"""
@type discovery_document_uri :: String.t()
defmodule Firezone.OpenAPIDocsWriter do
@keep_req_headers []
@keep_resp_headers ["content-type", "location"]
def write(conns, path) do
file = File.open!(path, [:write, :utf8])
open_api_spec = %{
openapi: "3.0.0",
info: %{
@AndrewDryga
AndrewDryga / config.ex
Last active December 12, 2022 16:10
Overriding Elixir application configuration in test env by using process dictionary
defmodule MyApp.Config do
@moduledoc """
This module provides set of helper functions that are useful when reading application runtime configuration overrides
in test environment.
"""
if Mix.env() != :test do
def maybe_put_env_override(_key, _value), do: :ok
def fetch_env!(app, key), do: Application.fetch_env!(app, key)
else
@AndrewDryga
AndrewDryga / twiml.xml
Created July 6, 2020 18:44
TwiML experiments
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Number>+15671112233</Number>
<Number>+15671112234</Number>
</Dial>
</Response>
@AndrewDryga
AndrewDryga / dynamic_changeset.ex
Last active November 6, 2022 11:20
Dynamic embeds with Ecto
defmodule DynamicChangeset do
@moduledoc """
This module provides helper functions to extend `Ecto.Changeset` to support
dynamic embeds.
"""
alias Ecto.Changeset
@doc """
Casts the given embed with the embedded changeset and field which is used to define it's type.
@AndrewDryga
AndrewDryga / signed_request.ex
Created July 14, 2018 15:11
Deciding Facebook signed request in Elixir
app_secret = Keyword.fetch!(config, :app_secret)
with [encoded_signature, encoded_payload] <- String.split(signed_request, "."),
{:ok, signature} <- Base.url_decode64(encoded_signature, padding: false),
{:ok, payload} <- Base.url_decode64(encoded_payload, padding: false),
{:ok, payload} <- Jason.decode(payload),
%{"algorithm" => "HMAC-SHA256"} <- payload,
payload_signature = :crypto.hmac(:sha256, app_secret, encoded_payload),
true <- Plug.Crypto.secure_compare(signature, payload_signature) do
{:ok, payload}
else
@AndrewDryga
AndrewDryga / sage_booking_timeout.ex
Created June 3, 2018 17:23
Sage: Booking with handling timeout errors
def book_trip(attrs) do
with {:ok, exchange_rates} <- BillingAPI.fetch_currency_exchange_rates(attrs),
{:ok, card_authorization} <- BillingAPI.authorize_card(exchange_rates, attrs),
{:hotel_booking, {:ok, hotel_booking}, _} <- {:hotel_booking, HotelsBookingAPI.book_hotel(attrs), []},
{:car_booking, {:ok, car_booking}, _} <- {:car_booking, CarsBookingAPI.book_hotel(attrs), [hotel_booking]},
{:flight_booking, {:ok, flight_booking}, _} <- {:flight_booking, FlightsBookingAPI.book_hotel(attrs), [hotel_booking, car_booking]},
:ok <- Mailer.send_email_confirmation(card_authorization, hotel_booking, attrs),
{:charge, {:ok, charge}, _} <- {:charge, BillingAPI.charge_card(card_authorization), [...]} do
{:ok, %{charge: charge, bookings: [hotel_booking, car_booking, flight_booking]}}
else
@AndrewDryga
AndrewDryga / booking_sage_multiple.ex
Last active December 1, 2018 17:47
Sage: Make multiple bookings
def book_trip(attrs) do
with {:ok, exchange_rates} <- BillingAPI.fetch_currency_exchange_rates(attrs),
{:ok, card_authorization} <- BillingAPI.authorize_card(exchange_rates, attrs),
{:booking, {:ok, hotel_booking}, _} <- {:booking, HotelsBookingAPI.book_hotel(attrs), []},
{:booking, {:ok, car_booking}, _} <- {:booking, CarsBookingAPI.book_hotel(attrs), [hotel_booking]},
{:booking, {:ok, flight_booking}, _} <- {:booking, FlightsBookingAPI.book_hotel(attrs), [hotel_booking, car_booking]},
:ok <- Mailer.send_email_confirmation(card_authorization, hotel_booking, attrs),
{:charge, {:ok, charge}, _} <- {:charge, BillingAPI.charge_card(card_authorization), [...]} do
{:ok, %{charge: charge, bookings: [hotel_booking, car_booking, flight_booking]}}
else
@AndrewDryga
AndrewDryga / booking_sage_handle_charge_failure.ex
Created June 3, 2018 17:18
Sage: Handle charge failure when we are booking a trip
def book_trip(attrs) do
with {:ok, exchange_rates} <- BillingAPI.fetch_currency_exchange_rates(attrs),
{:ok, card_authorization} <- BillingAPI.authorize_card(exchange_rates, attrs),
{:ok, hotel_booking} <- HotelsBookingAPI.book_hotel(attrs),
:ok <- Mailer.send_email_confirmation(card_authorization, hotel_booking, attrs),
{:charge, {:ok, charge}, _} <- {:charge, BillingAPI.charge_card(card_authorization), [hotel_booking]} do
{:ok, %{charge: charge, bookings: [hotel_booking]}}
else
{:charge, {:error, reason], [hotel_booking]} ->
:ok = send_excuse_email(authorization)
@AndrewDryga
AndrewDryga / booking_sage.ex
Created June 3, 2018 17:16
Sage: Booking Happy-Case
def book_trip(attrs) do
with {:ok, exchange_rates} <- BillingAPI.fetch_currency_exchange_rates(attrs),
{:ok, card_authorization} <- BillingAPI.authorize_card(exchange_rates, attrs),
{:ok, hotel_booking} <- HotelBookingAPI.book_hotel(attrs),
:ok <- Mailer.send_email_confirmation(card_authorization, hotel_booking, attrs),
{:ok, charge} <- BillingAPI.charge_card(card_authorization) do
{:ok, %{charge: charge, bookings: [hotel_booking]}}
end
end