Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140623
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/.credo.exs b/.credo.exs
new file mode 100644
index 0000000..b074009
--- /dev/null
+++ b/.credo.exs
@@ -0,0 +1,210 @@
+# This file contains the configuration for Credo and you are probably reading
+# this after creating it with `mix credo.gen.config`.
+#
+# If you find anything wrong or unclear in this file, please report an
+# issue on GitHub: https://github.com/rrrene/credo/issues
+#
+%{
+ #
+ # You can have as many configs as you like in the `configs:` field.
+ configs: [
+ %{
+ #
+ # Run any config using `mix credo -C <name>`. If no config name is given
+ # "default" is used.
+ #
+ name: "default",
+ #
+ # These are the files included in the analysis:
+ files: %{
+ #
+ # You can give explicit globs or simply directories.
+ # In the latter case `**/*.{ex,exs}` will be used.
+ #
+ included: [
+ "lib/",
+ "src/",
+ "test/",
+ "web/",
+ "apps/*/lib/",
+ "apps/*/src/",
+ "apps/*/test/",
+ "apps/*/web/"
+ ],
+ excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
+ },
+ #
+ # Load and configure plugins here:
+ #
+ plugins: [],
+ #
+ # If you create your own checks, you must specify the source files for
+ # them here, so they can be loaded by Credo before running the analysis.
+ #
+ requires: [],
+ #
+ # If you want to enforce a style guide and need a more traditional linting
+ # experience, you can change `strict` to `true` below:
+ #
+ strict: false,
+ #
+ # To modify the timeout for parsing files, change this value:
+ #
+ parse_timeout: 5000,
+ #
+ # If you want to use uncolored output by default, you can change `color`
+ # to `false` below:
+ #
+ color: true,
+ #
+ # You can customize the parameters of any check by adding a second element
+ # to the tuple.
+ #
+ # To disable a check put `false` as second element:
+ #
+ # {Credo.Check.Design.DuplicatedCode, false}
+ #
+ checks: %{
+ enabled: [
+ #
+ ## Consistency Checks
+ #
+ {Credo.Check.Consistency.ExceptionNames, []},
+ {Credo.Check.Consistency.LineEndings, []},
+ {Credo.Check.Consistency.ParameterPatternMatching, []},
+ {Credo.Check.Consistency.SpaceAroundOperators, []},
+ {Credo.Check.Consistency.SpaceInParentheses, []},
+ {Credo.Check.Consistency.TabsOrSpaces, []},
+
+ #
+ ## Design Checks
+ #
+ # You can customize the priority of any check
+ # Priority values are: `low, normal, high, higher`
+ #
+ {Credo.Check.Design.AliasUsage,
+ [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
+ # You can also customize the exit_status of each check.
+ # If you don't want TODO comments to cause `mix credo` to fail, just
+ # set this value to 0 (zero).
+ #
+ {Credo.Check.Design.TagTODO, [exit_status: 2]},
+ {Credo.Check.Design.TagFIXME, []},
+
+ #
+ ## Readability Checks
+ #
+ {Credo.Check.Readability.AliasOrder, []},
+ {Credo.Check.Readability.FunctionNames, []},
+ {Credo.Check.Readability.LargeNumbers, []},
+ {Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]},
+ {Credo.Check.Readability.ModuleAttributeNames, []},
+ {Credo.Check.Readability.ModuleDoc, []},
+ {Credo.Check.Readability.ModuleNames, []},
+ {Credo.Check.Readability.ParenthesesInCondition, []},
+ {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
+ {Credo.Check.Readability.PipeIntoAnonymousFunctions, []},
+ {Credo.Check.Readability.PredicateFunctionNames, []},
+ {Credo.Check.Readability.PreferImplicitTry, []},
+ {Credo.Check.Readability.RedundantBlankLines, []},
+ {Credo.Check.Readability.Semicolons, []},
+ {Credo.Check.Readability.SpaceAfterCommas, []},
+ {Credo.Check.Readability.StringSigils, []},
+ {Credo.Check.Readability.TrailingBlankLine, []},
+ {Credo.Check.Readability.TrailingWhiteSpace, []},
+ {Credo.Check.Readability.UnnecessaryAliasExpansion, []},
+ {Credo.Check.Readability.VariableNames, []},
+ {Credo.Check.Readability.WithSingleClause, false},
+
+ #
+ ## Refactoring Opportunities
+ #
+ {Credo.Check.Refactor.Apply, []},
+ {Credo.Check.Refactor.CondStatements, []},
+ {Credo.Check.Refactor.CyclomaticComplexity, []},
+ {Credo.Check.Refactor.FunctionArity, []},
+ {Credo.Check.Refactor.LongQuoteBlocks, []},
+ {Credo.Check.Refactor.MatchInCondition, []},
+ {Credo.Check.Refactor.MapJoin, []},
+ {Credo.Check.Refactor.NegatedConditionsInUnless, []},
+ {Credo.Check.Refactor.NegatedConditionsWithElse, []},
+ {Credo.Check.Refactor.Nesting, []},
+ {Credo.Check.Refactor.UnlessWithElse, []},
+ {Credo.Check.Refactor.WithClauses, []},
+ {Credo.Check.Refactor.FilterFilter, []},
+ {Credo.Check.Refactor.RejectReject, []},
+ {Credo.Check.Refactor.RedundantWithClauseResult, []},
+
+ #
+ ## Warnings
+ #
+ {Credo.Check.Warning.ApplicationConfigInModuleAttribute, []},
+ {Credo.Check.Warning.BoolOperationOnSameValues, []},
+ {Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
+ {Credo.Check.Warning.IExPry, []},
+ {Credo.Check.Warning.IoInspect, []},
+ {Credo.Check.Warning.OperationOnSameValues, []},
+ {Credo.Check.Warning.OperationWithConstantResult, []},
+ {Credo.Check.Warning.RaiseInsideRescue, []},
+ {Credo.Check.Warning.SpecWithStruct, []},
+ {Credo.Check.Warning.WrongTestFileExtension, []},
+ {Credo.Check.Warning.UnusedEnumOperation, []},
+ {Credo.Check.Warning.UnusedFileOperation, []},
+ {Credo.Check.Warning.UnusedKeywordOperation, []},
+ {Credo.Check.Warning.UnusedListOperation, []},
+ {Credo.Check.Warning.UnusedPathOperation, []},
+ {Credo.Check.Warning.UnusedRegexOperation, []},
+ {Credo.Check.Warning.UnusedStringOperation, []},
+ {Credo.Check.Warning.UnusedTupleOperation, []},
+ {Credo.Check.Warning.UnsafeExec, []}
+ ],
+ disabled: [
+ #
+ # Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`)
+
+ #
+ # Controversial and experimental checks (opt-in, just move the check to `:enabled`
+ # and be sure to use `mix credo --strict` to see low priority checks)
+ #
+ {Credo.Check.Consistency.MultiAliasImportRequireUse, []},
+ {Credo.Check.Consistency.UnusedVariableNames, []},
+ {Credo.Check.Design.DuplicatedCode, []},
+ {Credo.Check.Design.SkipTestWithoutComment, []},
+ {Credo.Check.Readability.AliasAs, []},
+ {Credo.Check.Readability.BlockPipe, []},
+ {Credo.Check.Readability.ImplTrue, []},
+ {Credo.Check.Readability.MultiAlias, []},
+ {Credo.Check.Readability.NestedFunctionCalls, []},
+ {Credo.Check.Readability.SeparateAliasRequire, []},
+ {Credo.Check.Readability.SingleFunctionToBlockPipe, []},
+ {Credo.Check.Readability.SinglePipe, []},
+ {Credo.Check.Readability.Specs, []},
+ {Credo.Check.Readability.StrictModuleLayout, []},
+ {Credo.Check.Readability.WithCustomTaggedTuple, []},
+ {Credo.Check.Refactor.ABCSize, []},
+ {Credo.Check.Refactor.AppendSingleItem, []},
+ {Credo.Check.Refactor.DoubleBooleanNegation, []},
+ {Credo.Check.Refactor.FilterReject, []},
+ {Credo.Check.Refactor.IoPuts, []},
+ {Credo.Check.Refactor.MapMap, []},
+ {Credo.Check.Refactor.ModuleDependencies, []},
+ {Credo.Check.Refactor.NegatedIsNil, []},
+ {Credo.Check.Refactor.PipeChainStart, []},
+ {Credo.Check.Refactor.RejectFilter, []},
+ {Credo.Check.Refactor.VariableRebinding, []},
+ {Credo.Check.Warning.LazyLogging, []},
+ {Credo.Check.Warning.LeakyEnvironment, []},
+ {Credo.Check.Warning.MapGetUnsafePass, []},
+ {Credo.Check.Warning.MixEnv, []},
+ {Credo.Check.Warning.UnsafeToAtom, []}
+
+ # {Credo.Check.Refactor.MapInto, []},
+
+ #
+ # Custom checks can be created using `mix credo.gen.check`.
+ #
+ ]
+ }
+ }
+ ]
+}
diff --git a/lib/http_signatures/http_signatures.ex b/lib/http_signatures/http_signatures.ex
index c486727..2006378 100644
--- a/lib/http_signatures/http_signatures.ex
+++ b/lib/http_signatures/http_signatures.ex
@@ -1,96 +1,94 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: LGPL-3.0-only
# https://tools.ietf.org/html/draft-cavage-http-signatures-08
defmodule HTTPSignatures do
@moduledoc """
HTTP Signatures library.
"""
require Logger
def split_signature(sig) do
default = %{"headers" => "date"}
sig =
sig
|> String.trim()
|> String.split(",")
|> Enum.reduce(default, fn part, acc ->
[key | rest] = String.split(part, "=")
value = Enum.join(rest, "=")
Map.put(acc, key, String.trim(value, "\""))
end)
Map.put(sig, "headers", String.split(sig["headers"], ~r/\s/))
end
def validate(headers, signature, public_key) do
sigstring = build_signing_string(headers, signature["headers"])
Logger.debug("Signature: #{signature["signature"]}")
Logger.debug("Sigstring: #{sigstring}")
{:ok, sig} = Base.decode64(signature["signature"])
:public_key.verify(sigstring, :sha256, sig, public_key)
end
def validate_conn(conn) do
adapter = Application.get_env(:http_signatures, :adapter)
with {:ok, public_key} <- adapter.fetch_public_key(conn) do
if validate_conn(conn, public_key) do
true
else
Logger.debug("Could not validate, trying to refetch any relevant keys")
with {:ok, public_key} <- adapter.refetch_public_key(conn) do
validate_conn(conn, public_key)
end
end
else
e ->
Logger.debug("Could not validate against known public keys: #{inspect(e)}")
false
end
end
def validate_conn(conn, public_key) do
headers = Enum.into(conn.req_headers, %{})
signature = split_signature(headers["signature"])
validate(headers, signature, public_key)
end
@doc "Get signature for conn in split form."
def signature_for_conn(conn) do
with headers <- Enum.into(conn.req_headers, %{}),
signature when is_binary(signature) <- headers["signature"] do
split_signature(signature)
else
_ ->
%{}
end
end
def build_signing_string(headers, used_headers) do
used_headers
- |> Enum.map(fn header -> "#{header}: #{headers[header]}" end)
- |> Enum.join("\n")
+ |> Enum.map_join("\n", fn header -> "#{header}: #{headers[header]}" end)
end
def sign(private_key, key_id, headers) do
sigstring = build_signing_string(headers, Map.keys(headers))
signature =
:public_key.sign(sigstring, :sha256, private_key)
|> Base.encode64()
[
keyId: key_id,
algorithm: "rsa-sha256",
headers: Map.keys(headers) |> Enum.join(" "),
signature: signature
]
- |> Enum.map(fn {k, v} -> "#{k}=\"#{v}\"" end)
- |> Enum.join(",")
+ |> Enum.map_join(",", fn {k, v} -> "#{k}=\"#{v}\"" end)
end
end
diff --git a/mix.exs b/mix.exs
index d61175a..09b1abe 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,43 +1,43 @@
defmodule HttpSignatures.MixProject do
use Mix.Project
def project do
[
app: :http_signatures,
description: "Library for manipulating and validating HTTP signatures",
version: "0.1.1",
elixir: "~> 1.7",
elixirc_options: [warnings_as_errors: true],
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps(),
package: package()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger, :public_key]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
- {:credo, "~> 1.0.0", only: [:dev, :test], runtime: false},
+ {:credo, "~> 1.0", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.19", only: :dev, runtime: false},
- {:dialyxir, "~> 1.0.0-rc.5", only: [:dev], runtime: false}
+ {:dialyxir, "~> 1.1.0", only: [:dev], runtime: false}
]
end
defp package do
[
licenses: ["LGPL-3.0-only"],
links: %{"GitLab" => "https://git.pleroma.social/pleroma/elixir-libraries/http_signatures"}
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jan 20, 7:03 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55591
Default Alt Text
(13 KB)
Attached To
Mode
R18 http_signatures
Attached
Detach File
Event Timeline
Log In to Comment