Skip to content

Commit

Permalink
Merge pull request #2 from Metaswitch/master
Browse files Browse the repository at this point in the history
catchup merge
  • Loading branch information
tca-ms authored Sep 27, 2018
2 parents 6324f2f + 855faac commit e35f90d
Show file tree
Hide file tree
Showing 16 changed files with 1,247 additions and 203 deletions.
12 changes: 8 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ matrix:
allow_failures:
- rust: nightly
include:
- rust: nightly-2018-03-07
- rust: nightly-2018-09-12
before_script:
- cargo install clippy --vers 0.0.187
- cargo install rustfmt --vers 0.9.0 --force
- rustup component add clippy-preview
script:
- cargo clippy -- -D warnings
- cargo fmt -- --write-mode diff
- rust: stable
env: RUSTFMT=1
before_script:
- rustup component add rustfmt-preview
script:
- cargo fmt -- --check
46 changes: 43 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,45 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Changed

## [0.10.0] - 2018-03-16
### Removed

## [1.0.2] - 2018-07-23
### Added
- Added (non-HTTPS) support for Windows/MacOS/iOS

## [1.0.1] - 2018-05-24
### Added
-- Stucts for combining multiple hyper services
- `SwaggerService` trait used by swagger-codegen middlewares.

## [1.0.0] - 2018-04-30
No changes. We now think we've got enough to declare this crate stable.

## [0.12.1] - 2018-04-27
### Added
- `RequestParser` trait for retrieving Swagger related info in middlewares.

### Changed
- Fixed `DropContext` to remove trait bounds on the type of context it can drop

## [0.12.0] - 2018-04-26
### Added
- `DropContext` to pass a raw (context-less) `hyper::Request` to a service.

## [0.11.0] - 2018-04-11
### Added
- `Has<T>`, `Pop<T>` and `Push<T>` traits for specifying requirements on context types in hyper services, and providing methods for manipulating them
- `new_context_type!` macro for defining structs that can be used to build concrete context types that implement `Has`, `Pop` and `Push`
- `make_context!` and `make_context_ty!` for conveniently creating contexts at value and type level

### Removed
- Old `Context` struct

### Changed
- Renamed `NoAuthentication` to `MiddlewareWrapper` and moved it to its own module.

## [0.10.0] - 2018-03-16
### Added
- Structs for combining multiple hyper services

## [0.9.0] - 2018-01-25
### Added
Expand Down Expand Up @@ -45,7 +79,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [0.5.0] - 2017-09-18
- Start of changelog.

[Unreleased]: https://github.com/Metaswitch/swagger-rs/compare/0.10.0...HEAD
[Unreleased]: https://github.com/Metaswitch/swagger-rs/compare/1.0.2...HEAD
[1.0.2]: https://github.com/Metaswitch/swagger-rs/compare/1.0.1...1.0.2
[1.0.1]: https://github.com/Metaswitch/swagger-rs/compare/1.0.0...1.0.1
[1.0.0]: https://github.com/Metaswitch/swagger-rs/compare/0.12.1...1.0.0
[0.12.1]: https://github.com/Metaswitch/swagger-rs/compare/0.12.0...0.12.1
[0.12.0]: https://github.com/Metaswitch/swagger-rs/compare/0.11.0...0.12.0
[0.11.0]: https://github.com/Metaswitch/swagger-rs/compare/0.10.0...0.11.0
[0.10.0]: https://github.com/Metaswitch/swagger-rs/compare/0.9.0...0.10.0
[0.9.0]: https://github.com/Metaswitch/swagger-rs/compare/0.8.1...0.9.0
[0.8.1]: https://github.com/Metaswitch/swagger-rs/compare/0.8.0...0.8.1
Expand Down
15 changes: 15 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Contributing to `swagger-rs`

Thanks for your interest - we gratefully welcome contributions.

Questions can be asked in [issues](https://github.com/Metaswitch/swagger-rs/issues).

To help us help you get pull requests merged quickly and smoothly, open an issue before submitted large changes. Please keep the contents of pull requests and commits short. Commit messages should include the intent of the commit. Pull requests should add an entry to [CHANGELOG.md].

Contributions that add/improve tests are awesome. Please add tests for every change.

`swagger-rs` uses [`rustfmt-nightly`](https://github.com/rust-lang-nursery/rustfmt) for formatting and [`clippy`](https://github.com/rust-lang-nursery/rust-clippy) for linting.

## Conduct

In all `swagger-rs`-related forums, we follow the [Swagger Codegen Code of Conduct](https://github.com/swagger-api/swagger-codegen/blob/master/CODE_OF_CONDUCT.md). For escalation or moderation issues please contact Benjamin (mailto:[email protected]) instead of the swagger-api moderation team.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "swagger"
version = "0.10.0"
version = "1.0.2"
authors = ["Metaswitch Networks Ltd"]
license = "Apache-2.0"
description = "A set of common utilities for Rust code generated by swagger-codegen"
Expand Down Expand Up @@ -29,4 +29,5 @@ openssl = "0.9.14"
slog = { version = "2", features = [ "max_level_trace", "release_max_level_debug"] }
tokio-core = "0.1.6"
futures = "0.1"
uuid = {version = "0.5", features = ["serde", "v4"]}

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@
[![crates.io](https://img.shields.io/crates/v/swagger.svg)](https://crates.io/crates/swagger)

A set of common utilities for crates generated by the `rust-server` [swagger-codegen](https://github.com/swagger-api/swagger-codegen) generator

# Releasing a new version

1. Run `./release-changelog.sh <version>` to update the changelog and `Cargo.toml`
2. Commit and push your changes.
3. Wait for a travis build to complete successfully.
4. Run `cargo publish`.
15 changes: 15 additions & 0 deletions release-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Updated the changelog for a new release
set -eou pipefail

version=$1
date=$(date +%Y-%m-%d)


sed -i "s/^version = \".\+\"$/version = \"$version\"/" Cargo.toml

sed -i "s/## \[Unreleased\]/## [Unreleased]\n### Added\n\n### Changed\n\n### Removed\n\n## [$version] - $date/" CHANGELOG.md

sed -i "s#\[Unreleased\]: https://github.com/Metaswitch/swagger-rs/compare/\(.*\)...HEAD#[Unreleased]: https://github.com/Metaswitch/swagger-rs/compare/$version...HEAD\n[$version]: https://github.com/Metaswitch/swagger-rs/compare/\1...$version#" CHANGELOG.md

echo "Now, delete any empty headers from $version in CHANGELOG.md"
69 changes: 69 additions & 0 deletions src/add_context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! Hyper service that adds a context to an incoming request and passes it on
//! to a wrapped service.
use super::{Push, XSpanIdString};
use hyper;
use hyper::{Error, Request, Response};
use std::io;
use std::marker::PhantomData;

/// Middleware wrapper service, that should be used as the outermost layer in a
/// stack of hyper services. Adds a context to a plain `hyper::Request` that can be
/// used by subsequent layers in the stack.
#[derive(Debug)]
pub struct AddContext<T, C>
where
C: Default + Push<XSpanIdString>,
{
inner: T,
marker: PhantomData<C>,
}

impl<T, C> AddContext<T, C>
where
C: Default + Push<XSpanIdString>,
{
/// Create a new AddContext struct wrapping a value
pub fn new(inner: T) -> Self {
AddContext {
inner,
marker: PhantomData,
}
}
}

impl<T, C> hyper::server::NewService for AddContext<T, C>
where
C: Default + Push<XSpanIdString>,
T: hyper::server::NewService<
Request = (Request, C::Result),
Response = Response,
Error = Error,
>,
{
type Request = Request;
type Response = Response;
type Error = Error;
type Instance = AddContext<T::Instance, C>;

fn new_service(&self) -> Result<Self::Instance, io::Error> {
self.inner.new_service().map(AddContext::new)
}
}

impl<T, C> hyper::server::Service for AddContext<T, C>
where
C: Default + Push<XSpanIdString>,
T: hyper::server::Service<Request = (Request, C::Result), Response = Response, Error = Error>,
{
type Request = Request;
type Response = Response;
type Error = Error;
type Future = T::Future;

fn call(&self, req: Self::Request) -> Self::Future {
let x_span_id = XSpanIdString::get_or_generate(&req);
let context = C::default().push(x_span_id);
self.inner.call((req, context))
}
}
109 changes: 54 additions & 55 deletions src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! Authentication and authorization data structures
use super::Push;
use hyper;
use hyper::{Error, Request, Response};
use std::collections::BTreeSet;
use std::io;
use hyper;
use hyper::{Request, Response, Error};
use super::Context;
use std::marker::PhantomData;

/// Authorization scopes.
#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -52,93 +53,91 @@ pub enum AuthData {
ApiKey(String),
}

/// No Authenticator, that does not insert any authorization data, denying all
/// access to endpoints that require authentication.
#[derive(Debug)]
pub struct NoAuthentication<T>(pub T);

impl<T> hyper::server::NewService for NoAuthentication<T>
where
T: hyper::server::NewService<
Request = (Request,
Context),
Response = Response,
Error = Error,
>,
{
type Request = Request;
type Response = Response;
type Error = Error;
type Instance = NoAuthentication<T::Instance>;

fn new_service(&self) -> Result<Self::Instance, io::Error> {
self.0.new_service().map(NoAuthentication)
impl AuthData {
/// Set Basic authentication
pub fn basic(username: &str, password: &str) -> Self {
AuthData::Basic(hyper::header::Basic {
username: username.to_owned(),
password: Some(password.to_owned()),
})
}
}

impl<T> hyper::server::Service for NoAuthentication<T>
where
T: hyper::server::Service<
Request = (Request,
Context),
Response = Response,
Error = Error,
>,
{
type Request = Request;
type Response = Response;
type Error = Error;
type Future = T::Future;
/// Set Bearer token authentication
pub fn bearer(token: &str) -> Self {
AuthData::Bearer(hyper::header::Bearer {
token: token.to_owned(),
})
}

fn call(&self, req: Self::Request) -> Self::Future {
self.0.call((req, Context::default()))
/// Set ApiKey authentication
pub fn apikey(apikey: &str) -> Self {
AuthData::ApiKey(apikey.to_owned())
}
}

/// Dummy Authenticator, that blindly inserts authorization data, allowing all
/// access to an endpoint with the specified subject.
#[derive(Debug)]
pub struct AllowAllAuthenticator<T> {
pub struct AllowAllAuthenticator<T, C>
where
C: Push<Option<Authorization>>,
{
inner: T,
subject: String,
marker: PhantomData<C>,
}

impl<T> AllowAllAuthenticator<T> {
impl<T, C> AllowAllAuthenticator<T, C>
where
C: Push<Option<Authorization>>,
{
/// Create a middleware that authorizes with the configured subject.
pub fn new<U: Into<String>>(inner: T, subject: U) -> AllowAllAuthenticator<T> {
pub fn new<U: Into<String>>(inner: T, subject: U) -> AllowAllAuthenticator<T, C> {
AllowAllAuthenticator {
inner,
subject: subject.into(),
marker: PhantomData,
}
}
}

impl<T> hyper::server::NewService for AllowAllAuthenticator<T>
where T: hyper::server::NewService<Request=(Request,Context), Response=Response, Error=Error> {
type Request = (Request, Option<AuthData>);
impl<T, C> hyper::server::NewService for AllowAllAuthenticator<T, C>
where
C: Push<Option<Authorization>>,
T: hyper::server::NewService<
Request = (Request, C::Result),
Response = Response,
Error = Error,
>,
{
type Request = (Request, C);
type Response = Response;
type Error = Error;
type Instance = AllowAllAuthenticator<T::Instance>;
type Instance = AllowAllAuthenticator<T::Instance, C>;

fn new_service(&self) -> Result<Self::Instance, io::Error> {
self.inner.new_service().map(|s| AllowAllAuthenticator::new(s, self.subject.clone()))
self.inner
.new_service()
.map(|s| AllowAllAuthenticator::new(s, self.subject.clone()))
}
}

impl<T> hyper::server::Service for AllowAllAuthenticator<T>
where T: hyper::server::Service<Request=(Request,Context), Response=Response, Error=Error> {
type Request = (Request, Option<AuthData>);
impl<T, C> hyper::server::Service for AllowAllAuthenticator<T, C>
where
C: Push<Option<Authorization>>,
T: hyper::server::Service<Request = (Request, C::Result), Response = Response, Error = Error>,
{
type Request = (Request, C);
type Response = Response;
type Error = Error;
type Future = T::Future;

fn call(&self, (req, _): Self::Request) -> Self::Future {
let mut context = Context::default();
context.authorization = Some(Authorization{
fn call(&self, (req, context): Self::Request) -> Self::Future {
let context = context.push(Some(Authorization {
subject: self.subject.clone(),
scopes: Scopes::All,
issuer: None,
});
}));
self.inner.call((req, context))
}
}
4 changes: 2 additions & 2 deletions src/base64_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// dead code.
#![allow(dead_code)]
#[cfg(feature = "serdejson")]
use serde::ser::{Serialize, Serializer};
use base64::{decode, encode};
#[cfg(feature = "serdejson")]
use serde::de::{Deserialize, Deserializer, Error};
#[cfg(feature = "serdejson")]
use base64::{encode, decode};
use serde::ser::{Serialize, Serializer};
use std::ops::{Deref, DerefMut};

#[derive(Debug, Clone, PartialEq, PartialOrd)]
Expand Down
Loading

0 comments on commit e35f90d

Please sign in to comment.