Skip to content

Commit

Permalink
Cleanup (#47)
Browse files Browse the repository at this point in the history
* Update dependencies, remove chrono

* Update lints

* Update README

* Update CHANGELOG
  • Loading branch information
Jake-Shadle authored Feb 2, 2022
1 parent 014fe19 commit f9ef21f
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 46 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- markdownlint-disable blanks-around-headings blanks-around-lists no-duplicate-heading -->

# Changelog
All notable changes to this project will be documented in this file.

Expand All @@ -6,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## [Unreleased] - ReleaseDate
### Changed
- [PR#47](https://github.com/EmbarkStudios/tame-oauth/pull/47) removed the dependency upon `chrono` as it was overkill and brought in multiple security advisories and is only lightly maintained.

## [0.6.0] - 2021-08-07
### Added
- [PR#40](https://github.com/EmbarkStudios/tame-oauth/pull/40) added support for [`Metadata Server Auth`](https://cloud.google.com/compute/docs/instances/verifying-instance-identity) so that you can obtain oauth tokens when running inside GCP. Thanks [@boulos](https://github.com/boulos)!
Expand All @@ -17,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.5.1] - 2021-06-05
### Removed
- Removed unused depdendency on `lock_api`, which was lingering after [PR#21](https://github.com/EmbarkStudios/tame-oauth/pull/21).
- Removed unused dependency on `lock_api`, which was lingering after [PR#21](https://github.com/EmbarkStudios/tame-oauth/pull/21).

## [0.5.0] - 2021-06-05
### Added
Expand Down
14 changes: 9 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
[package]
name = "tame-oauth"
version = "0.6.0"
authors = ["Embark <[email protected]>", "Jake Shadle <[email protected]>"]
authors = [
"Embark <[email protected]>",
"Jake Shadle <[email protected]>",
]
edition = "2018"
description = "A (very) simple oauth 2.0 library"
license = "MIT OR Apache-2.0"
documentation = "https://docs.rs/tame-oauth"
homepage = "https://github.com/EmbarkStudios/tame-oauth"
repository = "https://github.com/EmbarkStudios/tame-oauth"
keywords = ["oauth", "tame", "sans-io", "gcp"]
categories = ["authentication"]
readme = "README.md"

[badges]
Expand All @@ -29,14 +33,14 @@ jwt = ["ring"]
# This enables features in chrono and ring that are necessary to use this library
# in a wasm32 web (browser) context. If you are using wasm outside the browser
# you will need to target wasm32-wasi for the requisite functionality (time and random)
wasm-web = ["chrono/wasmbind", "ring/wasm32_c"]
wasm-web = ["ring/wasm32_c"]

[dependencies]
base64 = "0.13" # Keep aligned with rustls
chrono = "0.4"
# Keep aligned with rustls
base64 = "0.13"
http = "0.2"
ring = { version = "0.16", optional = true }
serde = { version = "1.0", features = [ "derive" ] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
twox-hash = { version = "1.5.0", default-features = false }
url = { version = "2.2", optional = true }
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# 🔐 tame-oauth
<div align="center">

# `🔐 tame-oauth`

[![Embark](https://img.shields.io/badge/embark-open%20source-blueviolet.svg)](http://embark.games)
[![Embark](https://img.shields.io/badge/discord-ark-%237289da.svg?logo=discord)](https://discord.gg/dAuKfZS)
Expand All @@ -9,6 +11,8 @@

`tame-oauth` is a small oauth crate that follows the [sans-io](https://sans-io.readthedocs.io/) approach.

</div>

## Why?

* You want to control how you actually make oauth HTTP requests
Expand All @@ -22,7 +26,7 @@
## Features

* `gcp` (default) - Support for [GCP oauth2](https://developers.google.com/identity/protocols/oauth2)
* `wasm-web` - Enables wasm features in `chrono` and `ring` needed for `tame-oauth` to be used in a wasm browser context. Note this feature should not be used when targetting wasm outside the browser context, in which case you would likely need to target `wasm32-wasi`.
* `wasm-web` - Enables wasm features in `ring` needed for `tame-oauth` to be used in a wasm browser context. Note this feature should not be used when targeting wasm outside the browser context, in which case you would likely need to target `wasm32-wasi`.
* `jwt` (default) - Support for [JSON Web Tokens](https://jwt.io/), required for `gcp`
* `url` (default) - Url parsing, required for `gcp`

Expand Down
14 changes: 10 additions & 4 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ targets = [

[advisories]
unmaintained = "deny"
ignore = [
]
ignore = []

[bans]
multiple-versions = "deny"
Expand All @@ -17,9 +16,10 @@ deny = [
{ name = "openssl-sys" },
]
skip = [
# hyper uses this old version
{ name = "itoa", version = "=0.4.8" },
]
skip-tree = [
]
skip-tree = []

[licenses]
unlicensed = "deny"
Expand All @@ -28,6 +28,7 @@ confidence-threshold = 0.92
allow = [
"Apache-2.0",
"MIT",
"BSD-3-Clause",
]
exceptions = [
{ allow = ["MPL-2.0"], name = "webpki-roots" },
Expand All @@ -51,6 +52,11 @@ license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 },
]

[[licenses.clarify]]
name = "encoding_rs"
expression = "(Apache-2.0 OR MIT) AND BSD-3-Clause"
license-files = [{ path = "COPYRIGHT", hash = 0x39f8ad31 }]

[[licenses.clarify]]
name = "webpki"
expression = "ISC"
Expand Down
27 changes: 14 additions & 13 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub enum Error {
file: std::path::PathBuf,
error: Box<Error>,
},
/// An error occured due to [`SystemTime`](std::time::SystemTime)
SystemTime(std::time::SystemTimeError),
}

impl fmt::Display for Error {
Expand All @@ -60,31 +62,24 @@ impl fmt::Display for Error {
InvalidCredentials { file, error } => {
write!(f, "Invalid credentials in '{}': {}", file.display(), error)
}
SystemTime(te) => {
write!(f, "System Time error: {}", te)
}
}
}
}

impl std::error::Error for Error {
fn cause(&self) -> Option<&dyn Err> {
use Error::{Auth, Base64Decode, Http, Json};

match self {
Base64Decode(err) => Some(err as &dyn Err),
Http(err) => Some(err as &dyn Err),
Json(err) => Some(err as &dyn Err),
Auth(err) => Some(err as &dyn Err),
_ => None,
}
}

fn source(&self) -> Option<&(dyn Err + 'static)> {
use Error::{Auth, Base64Decode, Http, Json};
#![allow(clippy::enum_glob_use)]
use Error::*;

match self {
Base64Decode(err) => Some(err as &dyn Err),
Http(err) => Some(err as &dyn Err),
Json(err) => Some(err as &dyn Err),
Auth(err) => Some(err as &dyn Err),
SystemTime(err) => Some(err as &dyn Err),
_ => None,
}
}
Expand All @@ -108,6 +103,12 @@ impl From<serde_json::Error> for Error {
}
}

impl From<std::time::SystemTimeError> for Error {
fn from(e: std::time::SystemTimeError) -> Self {
Error::SystemTime(e)
}
}

#[derive(serde::Deserialize, Debug)]
pub struct AuthError {
/// Top level error type
Expand Down
5 changes: 2 additions & 3 deletions src/gcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,13 @@ impl TokenProvider for TokenProviderWrapper {

impl From<TokenResponse> for Token {
fn from(tr: TokenResponse) -> Self {
let expires_ts = chrono::Utc::now().timestamp() + tr.expires_in;

Self {
access_token: tr.access_token,
token_type: tr.token_type,
refresh_token: String::new(),
expires_in: Some(tr.expires_in),
expires_in_timestamp: Some(expires_ts),
expires_in_timestamp: std::time::SystemTime::now()
.checked_add(std::time::Duration::from_secs(tr.expires_in as u64)),
}
}
}
9 changes: 5 additions & 4 deletions src/gcp/service_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,16 @@ impl TokenProvider for ServiceAccountProvider {
}
};

let issued = chrono::Utc::now().timestamp();
let expiry = issued + 3600 - 5; // Give us some wiggle room near the hour mark
let issued_at = std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)?
.as_secs() as i64;

let claims = jwt::Claims {
issuer: self.info.client_email.clone(),
scope: scopes,
audience: self.info.token_uri.clone(),
expiration: expiry,
issued_at: issued,
expiration: issued_at + 3600 - 5, // Give us some wiggle room near the hour mark
issued_at,
subject: subject.map(|s| s.into()),
};

Expand Down
16 changes: 13 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![doc = include_str!("../README.md")]
// BEGIN - Embark standard lints v0.4
// BEGIN - Embark standard lints v5 for Rust 1.55+
// do not change or add/remove here, but one can add exceptions after this section
// for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59>
#![deny(unsafe_code)]
Expand All @@ -10,6 +10,8 @@
clippy::checked_conversions,
clippy::dbg_macro,
clippy::debug_assert_with_mut_call,
clippy::disallowed_method,
clippy::disallowed_type,
clippy::doc_markdown,
clippy::empty_enum,
clippy::enum_glob_use,
Expand All @@ -19,13 +21,17 @@
clippy::explicit_into_iter_loop,
clippy::fallible_impl_from,
clippy::filter_map_next,
clippy::flat_map_option,
clippy::float_cmp_const,
clippy::fn_params_excessive_bools,
clippy::from_iter_instead_of_collect,
clippy::if_let_mutex,
clippy::implicit_clone,
clippy::imprecise_flops,
clippy::inefficient_to_string,
clippy::invalid_upcast_comparisons,
clippy::large_digit_groups,
clippy::large_stack_arrays,
clippy::large_types_passed_by_value,
clippy::let_unit_value,
clippy::linkedlist,
Expand All @@ -37,20 +43,25 @@
clippy::map_unwrap_or,
clippy::match_on_vec_items,
clippy::match_same_arms,
clippy::match_wild_err_arm,
clippy::match_wildcard_for_single_variants,
clippy::mem_forget,
clippy::mismatched_target_os,
clippy::missing_enforced_import_renames,
clippy::mut_mut,
clippy::mutex_integer,
clippy::needless_borrow,
clippy::needless_continue,
clippy::needless_for_each,
clippy::option_option,
clippy::path_buf_push_overwrite,
clippy::ptr_as_ptr,
clippy::rc_mutex,
clippy::ref_option_ref,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_functions_in_if_condition,
clippy::semicolon_if_nothing_returned,
clippy::single_match_else,
clippy::string_add_assign,
clippy::string_add,
clippy::string_lit_as_bytes,
Expand All @@ -67,9 +78,8 @@
nonstandard_style,
rust_2018_idioms
)]
// END - Embark standard lints v0.4
// END - Embark standard lints v0.5 for Rust 1.55+
// crate-specific exceptions:
#![allow()]

#[cfg(feature = "gcp")]
pub mod gcp;
Expand Down
20 changes: 9 additions & 11 deletions src/token.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::Error;
use chrono::{offset::TimeZone, DateTime, Utc};
use std::time::SystemTime;

/// Represents a token as returned by `OAuth2` servers.
///
Expand All @@ -23,23 +23,21 @@ pub struct Token {
/// Prefer using expiry_date()
pub expires_in: Option<i64>,
/// timestamp is seconds since epoch indicating when the token will expire
/// in absolute terms. use [`Self::expiry_date`] to convert to DateTime.
pub expires_in_timestamp: Option<i64>,
/// in absolute terms.
pub expires_in_timestamp: Option<SystemTime>,
}

impl Token {
/// Returns true if we are expired.
#[inline]
pub fn has_expired(&self) -> bool {
self.access_token.is_empty() || self.expiry_date() <= Utc::now()
}

/// Returns a [`chrono::DateTime`] object representing our expiry date.
pub fn expiry_date(&self) -> DateTime<Utc> {
match self.expires_in_timestamp {
Some(ts) => Utc.timestamp(ts, 0),
None => Utc::now(),
if self.access_token.is_empty() {
return true;
}

let expiry = self.expires_in_timestamp.unwrap_or_else(SystemTime::now);

expiry <= SystemTime::now()
}
}

Expand Down

0 comments on commit f9ef21f

Please sign in to comment.