Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring cleaning #138

Merged
merged 23 commits into from Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
162 changes: 162 additions & 0 deletions .credo.exs
@@ -0,0 +1,162 @@
# 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 exec using `mix credo -C <name>`. If no exec 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/"],
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: true,
#
# 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: [
#
## 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.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, []},
# TODO: enable by default in Credo 1.1
{Credo.Check.Readability.UnnecessaryAliasExpansion, false},
{Credo.Check.Readability.VariableNames, []},

#
## Refactoring Opportunities
#
{Credo.Check.Refactor.CondStatements, []},
{Credo.Check.Refactor.CyclomaticComplexity, []},
{Credo.Check.Refactor.FunctionArity, []},
{Credo.Check.Refactor.LongQuoteBlocks, []},
{Credo.Check.Refactor.MapInto, false},
{Credo.Check.Refactor.MatchInCondition, []},
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
{Credo.Check.Refactor.Nesting, []},
{Credo.Check.Refactor.UnlessWithElse, []},
{Credo.Check.Refactor.WithClauses, []},

#
## Warnings
#
{Credo.Check.Warning.BoolOperationOnSameValues, []},
{Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
{Credo.Check.Warning.IExPry, []},
{Credo.Check.Warning.IoInspect, []},
{Credo.Check.Warning.LazyLogging, false},
{Credo.Check.Warning.OperationOnSameValues, []},
{Credo.Check.Warning.OperationWithConstantResult, []},
{Credo.Check.Warning.RaiseInsideRescue, []},
{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, []},

#
# Controversial and experimental checks (opt-in, just replace `false` with `[]`)
#
{Credo.Check.Consistency.MultiAliasImportRequireUse, false},
{Credo.Check.Design.DuplicatedCode, false},
{Credo.Check.Readability.MultiAlias, false},
{Credo.Check.Readability.Specs, false},
{Credo.Check.Readability.SinglePipe, false},
{Credo.Check.Refactor.ABCSize, false},
{Credo.Check.Refactor.AppendSingleItem, false},
{Credo.Check.Refactor.DoubleBooleanNegation, false},
{Credo.Check.Refactor.ModuleDependencies, false},
{Credo.Check.Refactor.PipeChainStart, false},
{Credo.Check.Refactor.VariableRebinding, false},
{Credo.Check.Warning.MapGetUnsafePass, false},
{Credo.Check.Warning.UnsafeToAtom, false}

#
# Custom checks can be created using `mix credo.gen.check`.
#
]
}
]
}
3 changes: 3 additions & 0 deletions .formatter.exs
@@ -0,0 +1,3 @@
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
4 changes: 4 additions & 0 deletions .travis.yml
Expand Up @@ -20,6 +20,8 @@ matrix:
elixir: 1.6
- otp_release: 21.0
elixir: 1.7
- otp_release: 21.0
elixir: 1.8

env:
GLOBAL:
Expand All @@ -28,4 +30,6 @@ env:
sudo: false

after_script:
- mix format --check-formatted
- mix credo
- mix coveralls.travis
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -48,7 +48,7 @@ for more details.

## Debug mode

Some times its handy to see what's coming back from the response when getting
Sometimes it's handy to see what's coming back from the response when getting
a token. You can configure OAuth2 to output the response like so:

```elixir
Expand Down
6 changes: 4 additions & 2 deletions config/config.exs
Expand Up @@ -3,7 +3,9 @@ use Mix.Config
config :logger, level: :debug

config :oauth2,
client_id: "0bee1126b1a1381d9cab60bcd52349484451808a", # first commit sha of this library
client_secret: "f715d64092fe81c396ac383e97f8a7eca40e7c89", #second commit sha
# first commit sha of this library
client_id: "0bee1126b1a1381d9cab60bcd52349484451808a",
# second commit sha
client_secret: "f715d64092fe81c396ac383e97f8a7eca40e7c89",
redirect_uri: "http://example.com/auth/callback",
request_opts: []
6 changes: 3 additions & 3 deletions lib/oauth2.ex
Expand Up @@ -2,7 +2,7 @@ defmodule OAuth2 do
@moduledoc """
The OAuth2 specification

http://tools.ietf.org/html/rfc6749
[RFC6749](http://tools.ietf.org/html/rfc6749)

The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
Expand All @@ -12,13 +12,13 @@ defmodule OAuth2 do

## API

Current implemented strategies:
Currently implemented strategies:

- Authorization Code
- Password
- Client Credentials

#### Authorization Code Flow (AuthCode Strategy)
### Authorization Code Flow (AuthCode Strategy)

Initialize a client with your `client_id`, `client_secret`, and `site`.

Expand Down
39 changes: 21 additions & 18 deletions lib/oauth2/access_token.ex
Expand Up @@ -14,19 +14,20 @@ defmodule OAuth2.AccessToken do

@standard ["access_token", "refresh_token", "expires_in", "token_type"]

@type access_token :: binary
@type access_token :: binary
@type refresh_token :: binary | nil
@type expires_at :: integer
@type token_type :: binary
@type other_params :: %{binary => binary}
@type body :: binary | map
@type expires_at :: integer
@type token_type :: binary
@type other_params :: %{binary => binary}
@type body :: binary | map | list

@type t :: %__MODULE__{
access_token: access_token,
refresh_token: refresh_token,
expires_at: expires_at,
token_type: token_type,
other_params: other_params}
access_token: access_token,
refresh_token: refresh_token,
expires_at: expires_at,
token_type: token_type,
other_params: other_params
}

defstruct access_token: "",
refresh_token: nil,
Expand Down Expand Up @@ -58,21 +59,21 @@ defmodule OAuth2.AccessToken do
def new(response) when is_map(response) do
{std, other} = Map.split(response, @standard)

struct(AccessToken, [
access_token: std["access_token"],
struct(AccessToken,
access_token: std["access_token"],
refresh_token: std["refresh_token"],
expires_at: (std["expires_in"] || other["expires"]) |> expires_at,
token_type: std["token_type"] |> normalize_token_type(),
other_params: other
])
expires_at: (std["expires_in"] || other["expires"]) |> expires_at,
token_type: std["token_type"] |> normalize_token_type(),
other_params: other
)
end

@doc """
Determines if the access token will expire or not.

Returns `true` unless `expires_at` is `nil`.
"""
@spec expires?(AccessToken.t) :: boolean
@spec expires?(AccessToken.t()) :: boolean
def expires?(%AccessToken{expires_at: nil} = _token), do: false
def expires?(_), do: true

Expand All @@ -87,12 +88,14 @@ defmodule OAuth2.AccessToken do
Returns a unix timestamp based on now + expires_at (in seconds).
"""
def expires_at(nil), do: nil

def expires_at(val) when is_binary(val) do
val
|> Integer.parse
|> Integer.parse()
|> elem(0)
|> expires_at
end

def expires_at(int), do: unix_now() + int

defp normalize_token_type(nil), do: "Bearer"
Expand Down