Commit Graph

89 Commits

Author SHA1 Message Date
Maxime Bedard
4026d92cf6 Bump to tokio 0.3 and hyper 0.14 2020-11-12 20:31:19 -05:00
Lewin Bormann
4660676073 Revert "Upgrade tokio -> 0.3: Bump version to v5.0.0"
This reverts commit e07bc6f471.

Hyper and tokio 0.3 don't work together yet.
2020-10-20 17:47:39 +02:00
Lewin Bormann
e07bc6f471 Upgrade tokio -> 0.3: Bump version to v5.0.0 2020-10-20 16:28:46 +02:00
Steven 'Steve' Kendall
76ecfea853 Merge remote-tracking branch 'upstream/master' into two-steps-docfix 2020-01-17 14:45:16 -05:00
Steven 'Steve' Kendall
aedac1b423 fixup // to /// for DeviceFlow doc 2020-01-14 15:05:26 -05:00
Glenn Griffin
9238153723 Move to hyper 0.13.1!!!! 2019-12-18 09:07:45 -08:00
Glenn Griffin
5c0334ee6f Add debug logging.
Could be helpful when troubleshooting issues with various providers if
the user is able to turn on debug logging. The most critical logging
provided is the request and responses sent and received from the oauth
servers.
2019-12-18 09:07:45 -08:00
Glenn Griffin
36d186deb4 Authenticator now returns an AccessToken.
What was previously called Token is now TokenInfo and is merely an
internal implementation detail. The publicly visible type is now called
AccessToken and differs from TokenInfo by not including the refresh
token. This makes it a smaller type for users to pass around as well as
reducing the ways that a refresh token may be leaked. Since the
Authenticator is responsible for refreshing the tokens there isn't any
reason users should need to concern themselves with refresh tokens.
2019-12-18 09:07:45 -08:00
Glenn Griffin
045c3e7735 Move all the end to end tests into an integration test
All the same functionality can be tested through the publicly exposed
API providing more extensive coverage.
2019-12-18 09:07:45 -08:00
Glenn Griffin
0a4c1e79d2 Make DeviceFlowDelegate::present_user_code return a Future.
This is to allow for implementations to use async code. The returned
Future will be awaited before polling for the token begins.
2019-12-18 09:07:45 -08:00
Glenn Griffin
4521e2f246 Rename PollInformation DeviceAuthResponse.
Have it correctly handle either verification_uri or verification_url and
deserialize into a struct that has the data types desired.
2019-12-18 09:07:45 -08:00
Glenn Griffin
0525926bb2 Improve Token
Remove expires_in in favor of only having an expires_at DateTime field.
Add a from_json method that deserializes from json data into the
appropriate Token (or Error) and use that consistently throughout the
codebase.
2019-12-18 09:07:45 -08:00
Glenn Griffin
d0880d07db Refactor error handling and as a consequence delegates.
This Removes RefreshError and PollError. Both those types can be fully
represented within Error and there seems little value in distinguishing
that they were resulting from device polling or refreshes. In either
case the user will need to handle the response from token() calls
similarly. This also removes the AuthenticatorDelegate since it only
served to notify users when refreshes failed, which can already be done
by looking at the return code from token. DeviceFlow no longer has the
ability to set a wait_timeout. This is trivial to do by wrapping the
token() call in a tokio::Timeout future so there's little benefit for
users specifying this value. The DeviceFlowDelegate also no longer has
the ability to specify when to abort, or alter the interval polling
happens on, but it does gain understanding of the 'slow_down' response
as documented in the oauth rfc. It seemed very unlikely the delegate was
going to do anything other that timeout after a given time and that's
already possible using tokio::Timeout so it needlessly complicated the
implementation.
2019-12-18 09:07:45 -08:00
Glenn Griffin
fe5ea9bdb2 Rename Error::ClientError and RefreshError::ConnectionError to HttpError.
PollError already contained an HttpError variant so this makes all
variants that contain a hyper::Error consistently named.
2019-12-18 09:07:45 -08:00
Glenn Griffin
d63396a740 Split FlowDelegate into DeviceFlowDelegate and InstalledFlowDelegate.
Each flow invokes a non-overlapping set of methods. There doesn't appear
to be any benefit in having both flows use a common trait. The benefit
of splitting the traits is that it makes it clear which methods need to
be updated for each flow type where previously comments were required to
communicate that information.
2019-12-18 09:07:45 -08:00
Glenn Griffin
5256f642d7 Tie ServiceAccount's into Authenticator.
Prior to this change DeviceFlow and InstalledFlow were used within
Authenticator, while ServiceAccountAccess was used on it's own. AFAICT
this was the case because ServiceAccountAccess never used refresh tokens
and Authenticator assumed all tokens contained refresh tokens.
Authenticator was recently modified to handle the case where a token
does not contain a refresh token so I don't see any reason to keep the
service account access separate anymore. Folding it into the
authenticator provides a nice consistent interface, and the service
account implementation no longer needs to provide it's own caching since
it is now handled by Authenticator.
2019-12-18 09:07:45 -08:00
Glenn Griffin
68a30ea0fe Tidy up tests. 2019-12-18 08:59:43 -08:00
Glenn Griffin
e5aa32b3cf Tidy up some imports.
No more need to macro_use serde. Order the imports consistently (albeit
somewhat arbitrary), starting with items from this crate, followed by
std, followed by external crates.
2019-12-18 08:59:43 -08:00
Glenn Griffin
ba0b8f366a Rename RequestError to Error
RequestError is the error value that encompasses all errors from the
authenticators. Their is an established convention of using Error as the
name for those types.
2019-12-18 08:57:24 -08:00
Glenn Griffin
0fe66619dd Minimize the number of items on the rustdoc landing page.
Restructure the modules and imports to increase the signal to noise
ration on the cargo doc landing page. This includes exposing some
modules as public so that they can contain things that need to be public
but that users will rarely need to interact with. Most items from
types.rs were moved into an error.rs module that is now exposed
publicly.
2019-12-18 08:57:24 -08:00
Glenn Griffin
3aadc6b0ef Major refactor of the public API.
1) Remove the GetToken trait. The trait seemed to be organically
designed. It appeared to be mostly tailored for simplifying the
implementation since there was no way for users to provide their own
implementation to Authenticator. It sadly seemed to get in the way of
implementations more than it helped. An enum representing the known
implementations is a more straightforward way to accomplish the goal and
also has the benefit of not requiring Boxing when returning features
(which admittedly is a minor concern for this use case).

2) Reduce the number of type parameters by using trait object for
delegates. This simplifies the code considerably and the performance
impact of virtual dispatch for the delegate calls is a non-factor.

3) With the above two simplifications it became easier to unify the
public interface for building an authenticator. See the examples for how
InstalledFlow, DeviceFlow, and ServiceAccount authenticators are now created.
2019-12-18 08:57:24 -08:00
Glenn Griffin
c0919bee86 allow setting grant_type for device code 2019-12-18 08:57:24 -08:00
Glenn Griffin
88a8f74406 Refactor token storage.
The current code uses standard blocking i/o operations (std::fs::*) this
is problematic as it would block the entire futures executor waiting for
i/o.

This change is a major refactoring to make the token storage mechansim
async i/o friendly. The first major decision was to abandon the GetToken
trait. The trait is only implemented internally and there was no
mechanism for users to provide their own, but async fn's are not
currently supported in trait impls so keeping the trait would have
required Boxing futures. This probably would have been fine, but seemed
unnecessary. Instead of a trait the storage mechanism is just an enum
with a choice between Memory and Disk storage.

The DiskStorage works primarily as it did before, rewriting the entire
contents of the file on every set() invocation. The only difference is
that we now defer the actual writing to a separate task so that it does
not block the return of the Token to the user. If disk i/o is too slow
to keep up with the rate of incoming writes it will push back and
will eventually block the return of tokens, this is to prevent a buildup
of in-flight requests. One major drawback to this approach is that any
errors that happen on write are simply logged and no delegate function
is invoked on error because the delegate no longer has the ability to
say to sleep, retry, etc.
2019-12-18 08:57:24 -08:00
Glenn Griffin
05f7c10533 Remove unnecessary 'static bounds 2019-12-18 08:53:22 -08:00
Glenn Griffin
e8675fa1da Refactor retrieve_device_token.
wait_for_device_token polls indefinitely at the specified intervals.
Use tokio::timer::Timeout to bound the time it will poll for.
2019-12-18 08:53:22 -08:00
Glenn Griffin
ef23eef31d Remove more unnecessary clones. 2019-12-18 08:53:22 -08:00
Glenn Griffin
fa121d41b2 Delegates no longer need to implement Clone. 2019-12-18 08:53:22 -08:00
Glenn Griffin
8489f470a4 cargo clippy fixes 2019-12-18 08:53:22 -08:00
Glenn Griffin
4bd81c3263 cargo fmt 2019-12-18 08:53:22 -08:00
Glenn Griffin
2cf2e465d1 Add JsonErrorOr enum to make json error handling more concise/consistent.
JsonErrorOr is an untagged enum that is generic over arbitrary data.
This means that when deserializing JsonErrorOr<T> it will first check
the json field for an 'error' attribute. If one exists it will
deserialize into the JsonErrorOr::Err variant that contains a JsonError.
If the message doesn't contain an 'error' field it will attempt to
deserialize T into he JsonErrorOr::Data variant.
2019-12-18 08:53:22 -08:00
Glenn Griffin
29f800ba7f Some more improvements to reduce unnecessary allocations. 2019-12-18 08:53:22 -08:00
Glenn Griffin
9542e3a9f1 Remove instances of cloning ApplicationSecret
ApplicationSecret is not a small struct. This removes the instances
where it's cloned in favor of passing a shared reference.
2019-12-18 08:53:22 -08:00
Glenn Griffin
696577aa01 Accept scopes as a slice of anything that can produce a &str.
Along with the public facing change the implementation has been modified
to no longer clone the scopes instead using the pointer to the scopes
the user provided. This greatly reduces the number of allocations on
each token() call.

Note that this also changes the hashing method used for token storage in
an incompatible way with the previous implementation. The previous
implementation pre-sorted the vector and hashed the contents to make the
result independent of the ordering of the scopes. Instead we now combine
the hash values of each scope together with XOR, thus producing a hash
value that does not depend on order without needing to allocate another
vector and sort.
2019-12-18 08:53:22 -08:00
Glenn Griffin
0f29c258c6 FlowType isn't used for anything. Remove it. 2019-12-18 08:53:22 -08:00
Glenn Griffin
a4c9b6034e Require trait implementations to be Send + Sync.
Tidy up some of the trait bounds on types and methods.
2019-12-18 08:53:22 -08:00
Glenn Griffin
93cbd91341 Move to std::futures to support async/await. 2019-12-18 08:53:22 -08:00
Glenn Griffin
fbb8c69efb Change the name of TokenGetterBuilder to AuthFlow.
I believe AuthFlow more succinctly describes the purpose of the type to
users reading documentation.
2019-08-29 11:48:29 -07:00
Glenn Griffin
ccc6601ff3 Use the builder pattern to create authenticators.
Beyond simply moving to the builder pattern for intialization this has a
few other effects.

The DeviceFlow and InstalledFlow can no longer be used without an
associated Authenticator. This is becaus they no longer have any
publicly accessible constructor. All initialization goes through the
Authenticator. This also means that the flows are always initialized
with a clone of the hyper client used by the Authenticator.

The authenticator uses the builder pattern which allows omitting
optional fields. This means that if users simply want a default hyper
client, they don't need to create one explicitly. One will be created
automatically. If users want to specify a hyper client (maybe to allow
sharing a single client between different libraries) they can still do so
by using the hyper_client method on the builder. Additionally for both
AuthenticatorDelegate's and FlowDelegate's if the user does not specify
an override the default ones will be used.

The builders are now exposed publicly with the names of Authenicator,
InstalledFlow, and DeviceFlow. The structs that actually implement those
behaviors are now hidden and only expose the GetToken trait. This means
some methods that were previously publicly accessible are no longer
available, but the methods appeared to be implementation details that
probably shouldn't have been exposed anyway.
2019-08-29 11:47:15 -07:00
Glenn Griffin
2b18f3679e Modify GetToken::token.
Change it to accept an iterator of items that can be converted to
`String`s rather than an iterator of items that can be referenced as
`&str`s.

Primarily this allows it to be called with a larger variety of inputs.
For example ::std::env::args().skip(1) can now be passed directly to
token, where before it would first need to be collected into a vector.

Since all implementations unconditionally collected the iterator into a
vector this shouldn't have any negative impact on performance and should
actually reduce the number of allocations in some uses.

It simplifies the signature since the lifetime bounds are no longer
required.
2019-08-08 14:32:24 -07:00
Lewin Bormann
58af9fc36b refactor(deps): Remove dependency on openssl. 2019-08-01 21:32:22 +02:00
Lewin Bormann
ac08ac2da2 chore(fmt): rustfmt 2019-07-10 14:06:30 +02:00
Mark Catley
2ee218be55 Adding error logging to the Device Flow. 2019-06-28 09:49:56 +12:00
Mark Catley
ff8b3ede30 Updates to allow retrieving a token using the device flow on Salesforce. 2019-06-28 09:49:52 +12:00
Lewin Bormann
602ea1565d refactor(errors): Move almost everything to RequestError.
This is nicer than stupid Box<dyn Error+Send> everywhere.
2019-06-22 21:53:55 +02:00
Lewin Bormann
45431d83ff test(Device): Add tests for Device flow 2019-06-22 12:17:23 +02:00
Lewin Bormann
4cfbc6e5fc imp(Device): Honor FlowDelegate's opinion on pending authorization. 2019-06-13 16:07:32 +02:00
Lewin Bormann
a656df6b74 feat(GetToken): Add application_secret method to GetToken trait.
This makes decoupling Authenticator and individual flows easier while
allowing for refreshing tokens.
2019-06-13 15:29:18 +02:00
Lewin Bormann
71a45f059e refactor(delegate): Split AuthenticatorDelegate to have FlowDelegate 2019-06-12 21:16:28 +02:00
Lewin Bormann
46e1f1b880 feat(DeviceFlow): Proper timeout handling for the DeviceFlow. 2019-06-12 19:28:37 +02:00
Lewin Bormann
e7a89fae07 refactor(cleanup): Remove obsolete tests.
DeviceFlow now works in a different way, so remove old test.
2019-06-12 18:49:14 +02:00