-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
390 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
{ | ||
"stac_version": "1.0.0", | ||
"stac_extensions": [ | ||
"https://stac-extensions.github.io/item-assets/v1.0.0/schema.json", | ||
"https://stac-extensions.github.io/authentication/v1.1.0/schema.json" | ||
], | ||
"type": "Collection", | ||
"id": "collection", | ||
"title": "A title", | ||
"description": "A description", | ||
"license": "Apache-2.0", | ||
"extent": { | ||
"spatial": { | ||
"bbox": [ | ||
[ | ||
172.9, | ||
1.3, | ||
173, | ||
1.4 | ||
] | ||
] | ||
}, | ||
"temporal": { | ||
"interval": [ | ||
[ | ||
"2015-06-23T00:00:00Z", | ||
null | ||
] | ||
] | ||
} | ||
}, | ||
"auth:schemes": { | ||
"oauth": { | ||
"type": "oauth2", | ||
"description": "requires a login and user token", | ||
"flows": { | ||
"authorizationCode": { | ||
"authorizationUrl": "https://example.com/oauth/authorize", | ||
"tokenUrl": "https://example.com/oauth/token", | ||
"scopes": { | ||
"read:example": "Read the example data", | ||
"write:example": "Write the example data", | ||
"admin:example": "Read/write/delete the example data" | ||
} | ||
} | ||
} | ||
}, | ||
"signed_url_auth": { | ||
"type": "signedUrl", | ||
"description": "Requires an authentication API", | ||
"flows": { | ||
"auth": { | ||
"authorizationApi": "https://example.com/signed_url/authorize", | ||
"method": "POST", | ||
"parameters": { | ||
"bucket": { | ||
"in": "body", | ||
"required": true, | ||
"description": "asset-bucket", | ||
"schema": { | ||
"type": "string", | ||
"examples": [ | ||
"example-bucket" | ||
] | ||
} | ||
}, | ||
"key": { | ||
"in": "body", | ||
"required": true, | ||
"description": "asset key", | ||
"schema": { | ||
"type": "string", | ||
"examples": [ | ||
"path/to/example/asset.xyz" | ||
] | ||
} | ||
} | ||
}, | ||
"responseField": "signed_url" | ||
} | ||
} | ||
} | ||
}, | ||
"assets": { | ||
"example": { | ||
"href": "https://example.com/examples/file.xyz", | ||
"title": "Secure Collection Asset Example", | ||
"type": "application/vnd.example", | ||
"roles": [ | ||
"data" | ||
], | ||
"auth:refs": [ | ||
"signed_url_auth" | ||
] | ||
} | ||
}, | ||
"item_assets": { | ||
"data": { | ||
"title": "Secure Collection Asset Example", | ||
"type": "application/vnd.example", | ||
"roles": [ | ||
"data" | ||
], | ||
"auth:refs": [ | ||
"oauth" | ||
] | ||
} | ||
}, | ||
"summaries": { | ||
"datetime": { | ||
"minimum": "2015-06-23T00:00:00Z", | ||
"maximum": "2019-07-10T13:44:56Z" | ||
} | ||
}, | ||
"links": [ | ||
{ | ||
"href": "https://example.com/examples/collection.json", | ||
"rel": "self" | ||
}, | ||
{ | ||
"href": "https://example.com/examples/item.json", | ||
"rel": "item", | ||
"auth:refs": [ | ||
"oauth" | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
{ | ||
"stac_version": "1.0.0", | ||
"stac_extensions": [ | ||
"https://stac-extensions.github.io/authentication/v1.1.0/schema.json" | ||
], | ||
"type": "Feature", | ||
"id": "item", | ||
"bbox": [ | ||
172.9, | ||
1.3, | ||
173, | ||
1.4 | ||
], | ||
"geometry": { | ||
"type": "Polygon", | ||
"coordinates": [ | ||
[ | ||
[ | ||
172.9, | ||
1.3 | ||
], | ||
[ | ||
173, | ||
1.3 | ||
], | ||
[ | ||
173, | ||
1.4 | ||
], | ||
[ | ||
172.9, | ||
1.4 | ||
], | ||
[ | ||
172.9, | ||
1.3 | ||
] | ||
] | ||
] | ||
}, | ||
"properties": { | ||
"datetime": "2020-12-11T22:38:32Z", | ||
"auth:schemes": { | ||
"oauth": { | ||
"type": "oauth2", | ||
"description": "requires a login and user token", | ||
"flows": { | ||
"authorizationCode": { | ||
"authorizationUrl": "https://example.com/oauth/authorize", | ||
"tokenUrl": "https://example.com/oauth/token", | ||
"scopes": { | ||
"read:example": "Read the example data", | ||
"write:example": "Write the example data", | ||
"admin:example": "Read/write/delete the example data" | ||
} | ||
} | ||
} | ||
}, | ||
"none": { | ||
"type": "http", | ||
"scheme": "basic", | ||
"description": "Free access without restrictions" | ||
} | ||
} | ||
}, | ||
"links": [ | ||
{ | ||
"href": "https://example.com/examples/item.json", | ||
"rel": "self" | ||
} | ||
], | ||
"assets": { | ||
"data": { | ||
"href": "https://example.com/examples/file.xyz", | ||
"title": "Secure Asset Example", | ||
"type": "application/vnd.example", | ||
"roles": [ | ||
"data" | ||
], | ||
"auth:refs": [ | ||
"oauth" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
//! The Authentication extension to the STAC specification provides a standard | ||
//! set of fields to describe authentication and authorization schemes, flows, | ||
//! and scopes required to access [Assets](crate::Asset) and | ||
//! [Links](crate::Link) that align with the [OpenAPI security | ||
//! spec](https://swagger.io/docs/specification/authentication/). | ||
use std::collections::HashMap; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_json::Value; | ||
|
||
use crate::Extension; | ||
|
||
/// The authentication extension fields. | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct Authentication { | ||
/// A property that contains all of the [scheme definitions](Scheme) used by | ||
/// [Assets](crate::Asset) and [Links](crate::Link) in the STAC [Item](crate::Item) or [Collection](crate::Collection). | ||
#[serde(default, skip_serializing_if = "HashMap::is_empty")] | ||
pub schemes: HashMap<String, Scheme>, | ||
|
||
/// A property that specifies which schemes may be used to access an [Asset](crate::Asset) | ||
/// or [Link](crate::Link). | ||
#[serde(default, skip_serializing_if = "Vec::is_empty")] | ||
pub refs: Vec<String>, | ||
} | ||
|
||
/// The Authentication Scheme extends the [OpenAPI security | ||
/// spec](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-scheme-object) | ||
/// for support of OAuth2.0, API Key, and OpenID Connect authentication. | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct Scheme { | ||
/// The authentication scheme type used to access the data (`http` | `s3` | | ||
/// `signedUrl` | `oauth2` | `apiKey` | `openIdConnect` | a custom scheme type ). | ||
pub r#type: String, | ||
|
||
/// Additional instructions for authentication. | ||
/// | ||
/// [CommonMark 0.29](https://commonmark.org/) syntax MAY be used for rich text representation. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub description: Option<String>, | ||
|
||
/// The name of the header, query, or cookie parameter to be used. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub name: Option<String>, | ||
|
||
/// The location of the API key (`query` | `header` | `cookie`). | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub r#in: Option<String>, | ||
|
||
/// The name of the HTTP Authorization scheme to be used in the Authorization header as defined in RFC7235. | ||
/// | ||
/// The values used SHOULD be registered in the IANA Authentication Scheme registry. | ||
/// (`basic` | `bearer` | `digest` | `dpop` | `hoba` | `mutual` | | ||
/// `negotiate` | `oauth` (1.0) | `privatetoken` | `scram-sha-1` | | ||
/// `scram-sha-256` | `vapid`) | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub scheme: Option<String>, | ||
|
||
/// Scenarios an API client performs to get an access token from the authorization server. | ||
/// | ||
/// For oauth2 the following keys are pre-defined for the corresponding | ||
/// OAuth flows: `authorizationCode` | `implicit` | `password` | | ||
/// `clientCredentials`. The OAuth2 Flow Object applies for oauth2, the | ||
/// Signed URL Object applies to signedUrl. | ||
#[serde(skip_serializing_if = "HashMap::is_empty", default)] | ||
pub flows: HashMap<String, Flow>, | ||
|
||
/// OpenID Connect URL to discover OpenID configuration values. | ||
/// | ||
/// This MUST be in the form of a URL. | ||
#[serde(skip_serializing_if = "Option::is_none", rename = "openIdConnectUrl")] | ||
pub open_id_connect_url: Option<String>, | ||
} | ||
|
||
/// The OAuth2 Flow Object applies for oauth2, the Signed URL Object applies to signedUrl. | ||
#[derive(Debug, Serialize, Deserialize)] | ||
#[serde(untagged)] | ||
pub enum Flow { | ||
/// Based on the [OpenAPI OAuth Flow | ||
/// Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flows-object). | ||
/// | ||
/// Allows configuration of the supported OAuth Flows. | ||
OAuth2 { | ||
/// The authorization URL to be used for this flow. | ||
/// | ||
/// This MUST be in the form of a URL. | ||
#[serde(skip_serializing_if = "Option::is_none", rename = "authorizationUrl")] | ||
authorization_url: Option<String>, | ||
|
||
/// The token URL to be used for this flow. | ||
/// | ||
/// This MUST be in the form of a URL. | ||
#[serde(skip_serializing_if = "Option::is_none", rename = "tokenUrl")] | ||
token_url: Option<String>, | ||
|
||
/// The available scopes for the authentication scheme. | ||
/// | ||
/// A map between the scope name and a short description for it. The map MAY be empty. | ||
scopes: HashMap<String, String>, | ||
|
||
/// The URL to be used for obtaining refresh tokens. | ||
/// | ||
/// This MUST be in the form of a URL. | ||
#[serde(skip_serializing_if = "Option::is_none", rename = "refreshUrl")] | ||
refresh_url: Option<String>, | ||
}, | ||
|
||
/// A signed url flow. | ||
SignedUrl { | ||
/// The method to be used for requests. | ||
method: String, | ||
|
||
/// The signed URL API endpoint to be used for this flow. | ||
/// | ||
/// If not inferred from the client environment, this must be defined in the authentication flow. | ||
#[serde(skip_serializing_if = "Option::is_none", rename = "authorizationApi")] | ||
authorization_api: Option<String>, | ||
|
||
/// Parameter definition for requests to the authorizationApi | ||
#[serde(skip_serializing_if = "HashMap::is_empty")] | ||
parameters: HashMap<String, Parameter>, | ||
|
||
/// Key name for the signed URL field in an authorizationApi response | ||
#[serde(skip_serializing_if = "Option::is_none", rename = "responseField")] | ||
response_field: Option<String>, | ||
} | ||
} | ||
|
||
/// Definition for a request parameter. | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct Parameter { | ||
/// The location of the parameter (`query` | `header` | `body`). | ||
pub r#in: String, | ||
|
||
/// Setting for optional or required parameter. | ||
pub required: bool, | ||
|
||
/// Plain language description of the parameter | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub description: Option<String>, | ||
|
||
/// Schema object following the [JSON Schema draft-07](Schema object following the JSON Schema draft-07). | ||
pub schema: HashMap<String, Value>, | ||
} | ||
|
||
impl Extension for Authentication { | ||
const IDENTIFIER: &'static str = "https://stac-extensions.github.io/authentication/v1.1.0/schema.json"; | ||
const PREFIX: &'static str = "auth"; | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{Collection, Item, Extensions}; | ||
use super::Authentication; | ||
|
||
#[test] | ||
fn collection() { | ||
let collection: Collection = crate::read("examples/auth/collection.json").unwrap(); | ||
let authentication: Authentication = collection.extension().unwrap().unwrap(); | ||
let oauth = authentication.schemes.get("oauth").unwrap(); | ||
let _ = oauth.flows.get("authorizationCode").unwrap(); | ||
// FIXME: assets should be able to have extensions from their parent item | ||
// let asset = collection.assets.get("example").unwrap(); | ||
// let authentication: Authentication = asset.extension().unwrap().unwrap(); | ||
// assert_eq!(authentication.refs, vec!["signed_url_auth".to_string()]); | ||
} | ||
|
||
#[test] | ||
fn item() { | ||
|
||
let collection: Item = crate::read("examples/auth/item.json").unwrap(); | ||
let authentication: Authentication = collection.extension().unwrap().unwrap(); | ||
let _ = authentication.schemes.get("none").unwrap(); | ||
} | ||
} |
Oops, something went wrong.