1. Introduction
This document outlines in details how Alice (end-user) asserts her identity (logs in) when using Decent Photos (relying party) to access data in hers and Bob’s Solid Storage (resource servers).
2. Definitions
- OpenID Provider (OP)
- An OAuth 2.0 authorization server implementing OpenID Connect as defined in the OpenID Connect Core 1.0 specification. [OIDC.Core]
- Relying Party (RP)
- A client application using OpenID Connect to make resource requests on behalf of the resource owner. Client is one of the four roles defined in the OAuth 2.0 specification. [RFC6749]
- Resource
- Something denoted by an IRI or a literal as defined in RDF 1.1. [rdf11-concepts]
- Resource Owner
- An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user. Resource Owner is one of the four roles defined in the OAuth 2.0 specification. [RFC6749]
- Resource Server (RS)
- A server hosting resources, capable of accepting and responding to protected resource requests using access tokens. RS is one of the four roles defined in the OAuth 2.0 specification. [RFC6749]
- Solid Storage
- A Solid compliant Resource Server as defined in the Solid Protocol. [Solid.Protocol]
- Solid OpenID Connect (Solid OIDC)
- The specification defining authentication in the Solid ecosystem. [Solid.OIDC]
- WebID
- A WebID is an HTTP URI which refers to an Agent (Person, Organization, Group, Device, etc.) as defined in the WebID 1.0 specification. [WebID]
3. Actors
Several actors are at play in our example Solid OIDC authentication flows:
- Alice
- Alice will be providing consent for Decent Photos to make resource requests on her behalf. Let’s assume that Alice is using a standard web browser.
- Alice’s OP
- Alice’s OpenID Provider, also known as an Identity Provider (IdP), is the
service responsible for authorizing our third-party web app (Decent Photos) by
providing it with the tokens necessary to gain access to any resource Alice has
access to (in any Storage, for example Alice’s and Bob’s). In our example, Alice’s
OP is hosted at
https://secureauth.example
. - Alice’s WebID
- Alice’s WebID is
https://alice.coolpod.example/profile/card#me
. The WebID profile document denoted by URIhttps://alice.coolpod.example/profile/card
is hosted on Alice’s Solid Storage and contains the URI of her OP. Alice’s WebIDhttps://alice.coolpod.example/profile/card#me
serves as her unique identifier in the Solid Ecosystem. - RP
- The Decent Photos application is a third party photo viewing web application.
It is OIDC compliant and will therefore be referred to as the Relying Party. The
Decent Photos web app allows its users to view photos they have access to. For
example, Alice’s and her friend Bob’s photos. In our example, Decent Photos is
hosted at
https://decentphotos.example
. - RP’s Client ID Document
- Decent Photos is a Solid compliant application and has a URI of its own,
which resolves to a Client ID Document. An RP’s Client ID Document
contains information identifying them as a registered OAuth 2.0 client
application. Decent Photo’s URI is
https://decentphotos.example/webid#this
- Bob’s Storage
- We will be trying to access photos stored in Bob’s Storage. In our example, Bob
is a friend of Alice and has previously indicated via access control that Alice
may access some of his photos using any web app. Bob’s Solid Storage is hosted at
https://bob.otherpod.example
. - Authorization Server for Bob’s Storage
- The Authorization Server (AS) connected to Bob’s Storage will issue access tokens that
can be used with Bob’s Storage. In these examples, this is hosted at
https://auth.otherpod.example
.
4. Solid OIDC Flow
4.1. Authorization Code Grant with PKCE Authorization Flow
The Authorization Code grant with PKCE is the primary OAuth 2.0 authorization flow recommended by the Solid OIDC. It is defined by the PKCE RFC [RFC7636] and described here in the Solid OIDC context.
1. Alice uses the Decent Photos web app
Alice has heard of a great new site that allows her to view her friend’s photos and tag faces.
She navigates to https://decentphotos.example
via her web browser which returns an HTML page.
This page contains JavaScript that will help with the authentication process.
2. Alice selects her OP or WebID
Before decentphotos can start displaying images, Alice needs to start the
process of providing consent. To do so, she must either provide her WebID
(https://alice.coolpod.example/profile/card#me
) or the URL of her OP
(https://secureauth.example
).
Although it is not the case for Alice, a user’s Storage and OP can be hosted under the
same domain. For example, Bob could have a Storage at https://bob.solidpod.example.com
,
an OP at https://solidpod.example.com/
, and a WebID of https://bob.solidpod.example.com/profile/card#me
.
2.1 Retrieve Profile (only needed if a WebID is provided)
If Alice enters her WebID’s URL rather than her OP’s URL, a request should be made to determine her OP. To do so, a request should be made to Alice’s WebId:
GET https://alice.coolpod.example/profile/card#me
It will return a body similar to this:
@prefix :< #> . @prefix solid :< http :// www .w3 .org / ns / solid / terms #> . @prefix foaf :< http :// xmlns .com / foaf / 0 .1 /> . @prefix schema :< http :// schema .org /> .<> a foaf :PersonalProfileDocument ; foaf :maker < https :// localhost :8443 / profile / card #me > ; foaf :primaryTopic < https :// localhost :8443 / profile / card #me > .:me a foaf :Person ; a schema :Person ; foaf :name " Alice " ; solid :oidcIssuer < https :// secureauth .example > ;
The OP URL is located at :me -> solid:oidcIssuer
3. Retrieves OP Configuration
Now that we have Alice’s OP’s URL, the RP must make a request to retrieve the
OP’s configuration. This is always located at the OP’s issuer URL followed by /.well-known/openid-configuration
.
GET https://secureauth.example/.well-known/openid-configuration
The openid-configuration describes everything the client will need to know to authorize with Alice’s specific OP.
Response Body:
{ "issuer" : "https://secureauth.example" , "authorization_endpoint" : "https://secureauth.example/authorize" , "token_endpoint" : "https://secureauth.example/token" , "userinfo_endpoint" : "https://secureauth.example/userinfo" , "registration_endpoint" : "https://secureauth.example/register" , "end_session_endpoint" : "https://secureauth.example/endsession" , "jwks_uri" : "https://secureauth.example/jwks" , "response_types_supported" : [ "code" ], "grant_types_supported" : [ "authorization_code" , "refresh_token" ], "subject_types_supported" : [ "public" ], "claims_supported" : [ "sub" , "webid" ], "scopes_supported" : [ "openid" , "webid" , "profile" , "email" , "offline_access" ], "token_endpoint_auth_methods_supported" : [ "client_secret_basic" ], "token_endpoint_auth_signing_alg_values_supported" : [ "ES256" ], "request_object_signing_alg_values_supported" : [ "ES256" ], "id_token_signing_alg_values_supported" : [ "ES256" ], "code_challenge_methods_supported" : [ "plain" , "S256" ], "claims_parameter_supported" : false , "request_parameter_supported" : true , "request_uri_parameter_supported" : false , "require_request_uri_registration" : false }
The thing we care about here is the authorization_endpoint
field. This will
be the url we use when we’re ready to send an authorization request to the OP.
Note that we only support the code
response type. The OIDC discovery
specification states that Dynamic OpenID Providers MUST also support id_token
and token id_token
. However, implicit flows should not be used for
security reasons. Therefore, we
don’t recommend enabling them. For the same reason, we do not support the implicit
grant type.
4. Generates PKCE code challenge and code verifier
To follow the PKCE code flow we need to generate a code challenge and code verifier as instructed in the Proof Key for Code Exchange spec.
We start by generating a code verifier. The can be done by creating a
cryptographically random string. Let’s say ours looks like this: "JXPOuToEB7"
.
Now using the code verifier, we construct a code challenge. This can be made by transforming
the code verifier with Sha 256: BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
. Here’s our
code challenge: "HSi9dwlvRpNHCDm-L8GOdM16qcb0tLHPZqQSvaWXTI0"
5. Saved code verifier to session storage
Now, we save the code verifier ("JXPOuToEB7"
) to session storage. We’ll need it later to
confirm to the OP that this is the app that initiated the request. Do not save the code
challenge anywhere.
6. Authorization request
Now that the web app is registered, we can finally make an auth request to authorize the web application.
GET https://secureauth.example/authorize?response_type=code& redirect_uri=https%3A%2F%2Fdecentphotos.example%2Fcallback& scope=openid%20webid%20offline_access& client_id=https%3A%2F%2Fdecentphotos.example%2Fwebid%23this& code_challenge_method=S256& code_challenge=HSi9dwlvRpNHCDm-L8GOdM16qcb0tLHPZqQSvaWXTI0
That URL might look a little complex, but it’s essentially a request to https://secureauth.example/authorize
with the following URL parameters:
-
response_type=code
indicates the desired response data. -
redirect_uri=https%3A%2F%2Fdecentphotos.example%2Fcallback
: The url that the OP will redirect to once the user has logged in (https://decentphotos.example/callback
). -
scope=openid%20webid%20offline_access
: a list of OIDC scopes (attributes of the RS to which this token should have access) separated by spaces (%20).-
openid
is a scope that is needed to verify Alice’s identity. -
webid
is required by the Solid OIDC specification to denote a WebID login. -
offline_access
: Is required to get a refresh token.
-
-
client_id=https%3A%2F%2Fdecentphotos.example%2Fwebid%23this
: Usually the client id of a Solid application is the app’s URI (in our casehttps://decentphotos.example/webid#this
) as seen here. -
code_challenge_method=S256
: Tells the OP that our code challenge was transformed using SHA-256. -
code_challenge=HSi9dwlvRpNHCDm-L8GOdM16qcb0tLHPZqQSvaWXTI0
: The code challenge we generated before.
Note: If the app doesn’t have a URI, you can either register an app using static registration via some UI on the OP or use dynamic registration.
7. Fetch RP Client ID Document
If an app URI is provided as the client id (see note above to see other options), we must fetch that app URI to confirm its validity.
For the URI https://decentphotos.example/webid#this
, request the Client ID Document with:
GET https://decentphotos.example/webid
Response:
{ "@context" : [ "https://www.w3.org/ns/solid/oidc-context.jsonld" ], "client_id" : "https://decentphtos.example/webid#this" , "client_name" : "DecentPhotos" , "redirect_uris" : [ "https://decentphotos.example/callback" ], "post_logout_redirect_uris" : [ "https://decentphotos.example/logout" ], "client_uri" : "https://decentphotos.example/" , "logo_uri" : "https://decentphotos.example/logo.png" , "tos_uri" : "https://decentphotos.example/tos.html" , "scope" : "openid webid offline_access" , "grant_types" : [ "refresh_token" , "authorization_code" ], "response_types" : [ "code" ], "default_max_age" : 3600 , "require_auth_time" : true }
Notice that the application Client ID Document contains a JSON-LD representation of an OIDC Client Registration.
It also must use the specific "@context": ["https://www.w3.org/ns/solid/oidc-context.jsonld"]
.
8. Validate redirect url with Client ID Document
Check to be sure that the redirect_uri
value provided in the auth request
(https://decentphotos.example/callback
) is listed in the redirect_uris
array in the
Client ID Document. If it is not, the OP must reject the request. In our case, the redirect_uri
is valid, so we may continue.
9. Alice Logs In
The OP should redirect to its login screen. The actual implementation of this is completely up to the OP. A user can log in with her password, a TLS certificate, or any other proven method of authentication. The important thing is that, thanks to the redirect, the control is now out of the hands of the RP and is in complete control of the OP.
10. Generate a code
Generate a cryptographically random string that will be used as a code (Let’s say ours is m-OrTPHdRsm8W_e9P0J2Bt
). Store that string in a persistant keystore as the key for the client
id, the code challenge, the user’s webid, their desired response types, and their scopes:
{ "m-OrTPHdRsm8W_e9P0J2Bt" : { "client_id" : "https://decentphotos.example/webid#this" , "code_challenge" : "HSi9dwlvRpNHCDm-L8GOdM16qcb0tLHPZqQSvaWXTI0" , "webid" : "https://alice.coolpod.example/profile/card#me" , "response_types" : [ "code" ], "scope" : [ "openid" , "webid" , "offline_access" ] } }
11. Send code to redirect url
Once Alice successfully logs in, the OP redirects back to the application via the provided redirect uri, including useful information with it:
302 redirect to: https://decentphotos.example/callback?code=m-OrTPHdRsm8W_e9P0J2Bt
This redirect gives decentphotos the code that it will exchange for an access token.
12. Generates a DPoP Client Key Pair
Solid-OIDC depends on Demonstration of Proof-of-Possession (DPoP) tokens. DPoP tokens ensure that third-party web applications can send requests to any number of Storage servers while ensuring that malicious actors can’t steal and replay a user’s token.
The first step to generating a DPoP token is generating a public and private key pair on the third-party RP. In our example, the private key is generated using elliptic curves and looks like:
{ "kty" : "EC" , "kid" : "2i00gHnREsMhD5WqsABPSaqEjLC5MS-E98ykd-qtF1I" , "use" : "sig" , "alg" : "EC" , "crv" : "P-256" , "x" : "N6VsICiPA1ciAA82Jhv7ykkPL9B0ippUjmla8Snr4HY" , "y" : "ay9qDOrFGdGe_3hAivW5HnqHYdnYUkXJJevHOBU4z5s" , "d" : "RrM4Ou_7PzjP24B4k06B9ZML16HbfzNPKFN11Z8c9_s" }
From now on we will refer to this as RP_PRIVATE_KEY
.
The public key looks like:
{ "kty" : "EC" , "kid" : "2i00gHnREsMhD5WqsABPSaqEjLC5MS-E98ykd-qtF1I" , "use" : "sig" , "alg" : "EC" , "crv" : "P-256" , "x" : "N6VsICiPA1ciAA82Jhv7ykkPL9B0ippUjmla8Snr4HY" , "y" : "ay9qDOrFGdGe_3hAivW5HnqHYdnYUkXJJevHOBU4z5s" }
13. Generates a DPoP Header
Now that we generated a private key for the client, we need to generate the DPoP header. To do so, we create a JSON Web Token and sign it using the key we generated.
Our token could look like the following (you can decode the token using https://jwt.io):
eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand0IiwiandrIjp7Imt0eSI6IkVDIiwia2lkIjoiZkJ1STExTkdGbTQ4Vlp6RzNGMjVDOVJmMXYtaGdEakVnV2pEQ1BrdV9pVSIsInVzZSI6InNpZyIsImFsZyI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiOWxlT2gxeF9IWkhzVkNScDcyQzVpR01jek1nUnpDUFBjNjBoWldfSFlLMCIsInkiOiJqOVVYcnRjUzRLVzBIYmVteW1vRWlMXzZ1cko0TFFHZXJQZXVNaFNEaV80In19.eyJodHUiOiJodHRwczovL3NlY3VyZWF1dGguZXhhbXBsZS90b2tlbiIsImh0bSI6InBvc3QiLCJqdGkiOiI0YmEzZTllZi1lOThkLTQ2NDQtOTg3OC03MTYwZmE3ZDNlYjgiLCJpYXQiOjE2MDMzMDYxMjgsImV4cCI6MTYwMzMwOTcyOH0.2lbgLoRCkj0MsDc9BpquoaYuq0-XwRf_URdXru2JKrVzaWUqQfyKRK76_sQ0aJyVwavM3pPswLlHq2r9032O7Q
Token Header:
{ "alg" : "ES256" , "typ" : "dpop+jwt" , "jwk" : { "kty" : "EC" , "kid" : "2i00gHnREsMhD5WqsABPSaqEjLC5MS-E98ykd-qtF1I" , "use" : "sig" , "alg" : "EC" , "crv" : "P-256" , "x" : "N6VsICiPA1ciAA82Jhv7ykkPL9B0ippUjmla8Snr4HY" , "y" : "ay9qDOrFGdGe_3hAivW5HnqHYdnYUkXJJevHOBU4z5s" } }
-
"alg": "ES256"
: The signing algorithm used in this token. In this case,ES256
because we generated the keys using eliptic curves. -
"typ": "dpop+jwt"
: The type of token. All DPoP Tokens should have a type of "dpop+jwt" -
"jwk": { "kty": "EC" ... }
: The client’s public key.
Token Body:
{ "htu" : "https://secureauth.example/token" , "htm" : "POST" , "jti" : "4ba3e9ef-e98d-4644-9878-7160fa7d3eb8" , "iat" :<PHONE_NUMBER> }
-
"htu": "https://secureauth.example/token"
: htu limits the token for use only on the given url. -
"htm": "POST"
: htm limits the token for use only on a specific http method, in this casePOST
. -
"jti": "4ba3e9ef-e98d-4644-9878-7160fa7d3eb8"
: jti is a unique identifier for the DPoP token that can optionally be used by the server to defend against replay attacks -
"iat":<PHONE_NUMBER>
: The date the token was issued, in this case October 21, 2020 15:52:33 GMT.
14. Token request with code and code verifier
Now, we have everything we need to make an auth request. No need to redirect the web browser
for this one. We only need to make an AJAX request to the token
endpoint as defined in the
OP’s openid-configuration
file, in our case https://secureauth.example/token
POST https://secureauth.example/token Headers: { "DPoP": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand0IiwiandrIjp7Imt0eSI6IkVDIiwia2lkIjoiZkJ1STExTkdGbTQ4Vlp6RzNGMjVDOVJmMXYtaGdEakVnV2pEQ1BrdV9pVSIsInVzZSI6InNpZyIsImFsZyI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiOWxlT2gxeF9IWkhzVkNScDcyQzVpR01jek1nUnpDUFBjNjBoWldfSFlLMCIsInkiOiJqOVVYcnRjUzRLVzBIYmVteW1vRWlMXzZ1cko0TFFHZXJQZXVNaFNEaV80In19.eyJodHUiOiJodHRwczovL3NlY3VyZWF1dGguZXhhbXBsZS90b2tlbiIsImh0bSI6InBvc3QiLCJqdGkiOiI0YmEzZTllZi1lOThkLTQ2NDQtOTg3OC03MTYwZmE3ZDNlYjgiLCJpYXQiOjE2MDMzMDYxMjgsImV4cCI6MTYwMzMwOTcyOH0.2lbgLoRCkj0MsDc9BpquoaYuq0-XwRf_URdXru2JKrVzaWUqQfyKRK76_sQ0aJyVwavM3pPswLlHq2r9032O7Q", "content-type": "application/x-www-form-urlencoded" } Body: grant_type=authorization_code& code_verifier=JXPOuToEB7& code=m-OrTPHdRsm8W_e9P0J2Bt& redirect_uri=https%3A%2F%2Fdecentphotos.example%2Fcallback& client_id=https%3A%2F%2Fdecentphotos.example%2Fwebid%23this
-
headers.DPoP: "eyJhbGciOiJFUz..."
: The DPoP token we generated before. This will tell the OP what the client’s public key is. -
headers.content-type: "application/x-www-form-urlencoded"
: Sets to body’s content type toapplication/x-www-form-urlencoded
. Some OPs will accept other content types likeapplication/json
but they all must access urlencoded content types, so it’s safest to use that. -
body.grant_type=authorization_code
: Tells the OP that we are doing the authorization code flow. -
body.code_verifier=JXPOuToEB7
: Our code verifier that we stored in session storage -
body.code=m-OrTPHdRsm8W_e9P0J2Bt
: The code that we received from the OP upon redirect -
body.redirect_uri
: The app’s redirect url. In this case, this isn’t needed because we’re doing an AJAX request. -
body.client_id=https%3A%2F%2Fdecentphotos.example%2Fwebid%23this
: The app’s client id.
Once this request is completed decentphotos can remove the code verifier from session storage.
15. Validate code verifier
The OP looks up the code that was saved earlier in a keystore. It checks to see that the client
id in the keystore corresponds to the client id from the request. If it does not, it must
reject the request with a 400 HTTP status and invalid_grant
error code.
The OP then verifies that the code verifier [corresponds with the code challenge] (https://tools.ietf.org/html/rfc7636#section-4.6) stored in the keystore.
BASE64URL-ENCODE( SHA256( ASCII( code_verifier))) == code_challenge
If they do not correspond the OP must reject the request with a 400 HTTP status and invalid_grant
error code.
16. Validates DPoP Token Signature
The OP extracts the client’s public key from the DPoP header (at header.jwk). It confirms that
the DPoP token has a valid signature. If not, the OP must reject the request with a 400 HTTP
status and invalid_dpop_proof
error code.
17. Converts the DPoP public key to a JWK thumbprint
Currently the DPoP token contains a JWK public key, but before we place it inside the access token, it needs to be converted into a JWK thumbprint. Our JWK thumbprint looks more like:
9XmwK8mQ3H5-PnzAt3lFHzWBW_v5QhYynezbbit4kC8
19. Generates the id_token
Since openid
was listed as a scope during the authorization request, the OP generates an id
token. The id token will be pushed as claim to any Solid Authorization Server needed, which clients want to get Access Token from.
This token is a JSON Web Token. It would look like
the following (you can decrypt the token with https://jwt.io):
encoded token needs to be updated
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJodHRwczovL2FsaWNlLmNvb2xwb2QuZXhhbXBsZS9wcm9maWxlL2NhcmQjbWUiLCJhdWQiOiJodHRwczovL2RlY2VudHBob3Rvcy5leGFtcGxlL3dlYmlkI3RoaXMiLCJ3ZWJpZCI6Imh0dHBzOi8vYWxpY2UuY29vbHBvZC5leGFtcGxlL3Byb2ZpbGUvY2FyZCNtZSIsImlzcyI6Imh0dHBzOi8vc2VjdXJlYXV0aC5leGFtcGxlIiwianRpIjoiODQ0YTA5NWMtOWNkYi00N2U1LTk1MTAtMWRiYTk4N2MwYTVmIiwiaWF0IjoxNjAzMzg2NDQ4LCJleHAiOjE2MDMzODcwNDh9.T306vT8dmn9gQIMEdG92AM4WRnrhqWZTfDpovwqZ6Zn0mK9yxj0iOVGqXD4CW8-tzDTitNwEGorAo85atL0Oeg
Token Header:
{ "alg" : "ES256" , "typ" : "JWT" }
-
"alg": "ES256"
: indicates the token was signed using eliptic curve -
"typ": "JWT"
: indicates that this is a JSON web token
Token Body:
{ "sub" : "https://alice.coolpod.example/profile/card#me" , "aud" : [ "solid" , "https://decentphotos.example/webid#this" ], "azp" : "https://decentphotos.example/webid#this" "webid" : "https://alice.coolpod.example/profile/card#me" , "iss" : "https://secureauth.example" , "jti" : "844a095c-9cdb-47e5-9510-1dba987c0a5f" , "iat" :<PHONE_NUMBER> , "exp" :<PHONE_NUMBER> , "cnf" : { "jkt" : "9XmwK8mQ3H5-PnzAt3lFHzWBW_v5QhYynezbbit4kC8" }, }
-
"sub": "https://alice.coolpod.example/profile/card#me"
: The subject claim. It must be the same as the authenticated user’s WebID. -
"aud": "https://decentphotos.example/webid#this"
: The token’s audience. Because an id_token is intended for the client and any Solid Authorization Server, its audience is the client id and the string "solid". -
"azp": "https://decentphotos.example/webid#this"
: The token’s authorized party. Because an id_token is intended to be used by the client, its authorized party is the client id. -
"webid": "https://alice.coolpod.example/profile/card#me"
: The WebID of the user that logged in -
"iss": "https://secureauth.example"
: The OP that was used to generate this token -
"jti": "844a095c-9cdb-47e5-9510-1dba987c0a5f"
: The jti is an optional unique identifier for this token that can be used to prevent replay attacks. -
"iat":<PHONE_NUMBER>
: The date the token was issued, in this case October 22, 2020 8:44:01 -
"exp":<PHONE_NUMBER>
: The token’s expiration date, in this case October 22, 2020 8:54:01 -
"cnf": { "jkt": "9XmwK8mQ3H5-PnzAt3lFHzWBW_v5QhYynezbbit4kC8" }
: The jwk thrumbprint must be embedded in an object on the field "jkt"
20. Generates refresh token
If offline_access
was provided as a scope, the OP creates an opaque token as
a refresh token. It could be like the one below. Notice the one below is a JWT, but a refresh
token does not need to be a JWT.
eyJhbGciOiJub25lIn0.eyJqdGkiOiJhNzhiNDllZi03MWM1LTQ5ODUtYTUwYy01ZWYzYWVmMGZkOGYifQ.
The example token would decrypt as:
Token Header:
{ "alg" : "none" }
Token Body:
{ "jti" : "a78b49ef-71c5-4985-a50c-5ef3aef0fd8f" }
Save the refresh token to a persistant store.
21. Sends tokens
Once the OP has confirmed that everything checks out and all the tokens are generated, it sends a response with the tokens in the body:
Response (content-type: application/json)
{ "access_token" : "531683bf-fea8-4bca-8976-2de50e5c9a50" , "id_token" : "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJodHRwczovL2FsaWNlLmNvb2xwb2QuZXhhbXBsZS9wcm9maWxlL2NhcmQjbWUiLCJhdWQiOiJodHRwczovL2RlY2VudHBob3Rvcy5leGFtcGxlL3dlYmlkI3RoaXMiLCJ3ZWJpZCI6Imh0dHBzOi8vYWxpY2UuY29vbHBvZC5leGFtcGxlL3Byb2ZpbGUvY2FyZCNtZSIsImlzcyI6Imh0dHBzOi8vc2VjdXJlYXV0aC5leGFtcGxlIiwianRpIjoiODQ0YTA5NWMtOWNkYi00N2U1LTk1MTAtMWRiYTk4N2MwYTVmIiwiaWF0IjoxNjAzMzg2NDQ4LCJleHAiOjE2MDMzODcwNDh9.T306vT8dmn9gQIMEdG92AM4WRnrhqWZTfDpovwqZ6Zn0mK9yxj0iOVGqXD4CW8-tzDTitNwEGorAo85atL0Oeg" , "refresh_token" : "eyJhbGciOiJub25lIn0.eyJqdGkiOiJhNzhiNDllZi03MWM1LTQ5ODUtYTUwYy01ZWYzYWVmMGZkOGYifQ." }
-
"access_token": "531683bf-feea8..."
: The OAuth 2.0 access token, which may be used at the OP’suserinfo_endpoint
. -
"id_token": "eyJhbGciOiJFU..."
: The ID token we generated. The client will use this to extract information such as the user’s WebId. A client will also exchange the ID token for an access token at an authorization server. -
"refresh_token": "eyJhbGciOiJ..."
: The refresh token. The client will use this to fetch a new ID token when the current token expires.
4.2. Request Flow
In this example, Alice has logged into https://decentphotos.example
and has completed the
authentication steps above. She wants to make a request to Bob’s Storage to get a photo album
information at https://bob.otherpod.example/private/photo_album.ttl
. Bob has previously
granted access to Alice but has not granted access to anyone else.
1. Discover Authorization Server
Client can discover Authorization Server by making request to the resource
Request:
GET https://bob.otherpod.example/private/photo_album.ttl
Response:
HTTP / 1.1 401 Unauthorized WWW-Authenticate : UMA realm="example", as_uri="https://auth.otherpod.example", ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
2. Request AS configuration
Knowing Authorization Server now client can discover its Token Endpoint ([RFC8414])
Request:
GET https://auth.otherpod.example/.well-known/uma2-configuration
Response:
{ "issuer" : "https://auth.otherpod.example" , "token_endpoint" : "https://auth.otherpod.example/token" , "grant_types_supported" : [ "urn:ietf:params:oauth:grant-type:uma-ticket" ] ...}
3. Creates a DPoP header token
Before we request access token, we need to generate a DPoP header token. A new DPoP token must be generated every time a request is made.
Generating a DPoP token is done the same way we did it in the authentication section. It must be signed by the same keypair that we generated in the authentication section. Our token could look like the following (you can decode the token using https://jwt.io):
eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand0IiwiandrIjp7Imt0eSI6IkVDIiwia2lkIjoiQ21HVE9Dd3ZKWXhrb0dGOGNxcFpBNTdab2xVdThBcFJQb3MwVlduWk1TNCIsInVzZSI6InNpZyIsImFsZyI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiU0FZcmF5VUh4Z1FPQ29YSC1MbHdyOW1iSWJpUHBsLXRQRUpLeE1WWFltcyIsInkiOiJ6eGJQODdPQ3JpeEZpMk9vZjU1QkhsTC1ySHhvWHVuUmttNFBkV3duUzJnIn19.eyJodHUiOiJodHRwczovL2JvYi5vdGhlcnBvZC5leGFtcGxlL3ByaXZhdGUvcGhvdG9fYWxidW0udHRsIiwiaHRtIjoiZ2V0IiwianRpIjoiZmIxMjY0ZGQtZmZmMS00NTA5LWE3YjEtMGZlNThkMDhkM2UxIiwiaWF0IjoxNjAzMzg5NjE2LCJleHAiOjE2MDMzOTMyMTZ9.G8JktoMOadenCYtO4Z_ZI7ACnjKJvT59OyKlQ6WpB1Qq2GoCK6v1ocrpsfELDOKIL5nt5fwWccfvCAA2bMrkjA
Token Header:
{ "alg" : "ES256" , "typ" : "dpop+jwt" , "jwk" : { "kty" : "EC" , "kid" : "2i00gHnREsMhD5WqsABPSaqEjLC5MS-E98ykd-qtF1I" , "use" : "sig" , "alg" : "EC" , "crv" : "P-256" , "x" : "N6VsICiPA1ciAA82Jhv7ykkPL9B0ippUjmla8Snr4HY" , "y" : "ay9qDOrFGdGe_3hAivW5HnqHYdnYUkXJJevHOBU4z5s" , } }
-
"alg": "ES256"
: The signing algorithm used in this token. In this case,ES256
because we generated the keys using eliptic curves. -
"typ": "dpop+jwt"
: The type of token. All DPoP Tokens should have a type of "dpop+jwt" -
"jwk": { "kty": "EC" ... }
: The client’s public key.
Token Body:
{ "htu" : "https://auth.otherpod.example/token" , "htm" : "POST" , "jti" : "fb1264dd-fff1-4509-a7b1-0fe58d08d3e1" , "iat" :<PHONE_NUMBER> }
-
"htu": "https://auth.otherpod.example/token"
: htu limits the token for use only on the given url. -
"htm": "POST"
: htm limits the token for use only on a specific http method, in this casePOST
. -
"jti": "fb1264dd-fff1-4509-a7b1-0fe58d08d3e1"
: jti is a unique identifier for the DPoP token that can optionally be used by the server to defend against replay attacks -
"iat":<PHONE_NUMBER>
: The date the token was issued, in this case October 22, 2020 14:00:16 GMT.
4. Request Access Token
Request:
POST /token HTTP / 1.1 Host : auth.otherpod.example DPoP : eyJhbGciOi... ... grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket &ticket=016f84e8-f9b9-11e0-bd6f-0021cc6004de &claim_token=eyj0... &claim_token_format=http%3A%2F%2Fopenid.net%2Fspecs%2Fopenid-connect-core-1_0.html%23IDToken
5. Checks ID Token expirations
The AS checks if the id token is still valid by looking at the exp
claim. If the token
does not have an exp
claim or the token is expired, the AS must reject the request with
a 403 HTTP status. When using UMA 2.0, the AS will include need_info
and required_claims
values in the error response.
6. Checks the DPoP token url and method
The AS checks the htu
and htm
claims of the DPoP token. If the htu
does not match the
protocol, origin and path of the request or the htm
does not correspond the the http method
of the request, the AS must reject the request with a 400 HTTP status and an invalid_dpop_proof
error code.
6.1. (Optional) Checks DPoP token unique identifier
The AS can optionally keep track of all DPoP jti
claims it received. Because a new DPoP token
must be generated each time a request is made, no two tokens should have the same jti
. If the
AS receives a DPoP token with a jti
it has already encountered it may reject the request with
a 400 HTTP status and an invalid_dpop_proof
error code.
7. Checks DPoP signature against Access Token
The AS first confirms that the DPoP token was signed by the public key listed in its header
jwk
. If it was not, the AS must reject the request with a 400 HTTP status and an invalid_dpop_proof
error code.
The AS checks if the public key in the DPoP token’s header.jwk
corresponds to the jwk
thumbprint in the access token in the cnf
field. If they do not, the OP must reject the
request. When using UMA 2.0, the response will include a 403 HTTP status code and a need_info
field in the error response.
8. Retrieves WebID Document
Using the webid
claim in the access token (for us, it’s https://alice.coolpod.example/profile/card#me
), the AS retreives the user’s WebId document.
Request
GET https://alice.coolpod.example/profile/card#me
Response
@prefix :< #> . @prefix solid :< http :// www .w3 .org / ns / solid / terms #> . @prefix foaf :< http :// xmlns .com / foaf / 0 .1 /> . @prefix schema :< http :// schema .org /> .<> a foaf :PersonalProfileDocument ; foaf :maker < https :// localhost :8443 / profile / card #me > ; foaf :primaryTopic < https :// localhost :8443 / profile / card #me > .:me a foaf :Person ; a schema :Person ; foaf :name " Alice " ; solid :oidcIssuer < https :// secureauth .example > ;
9. Checks issuer
The AS checks that the iss
claim in the ID token matches the issuer listed in the user’s
WebID. If it does not, the AS must reject the request.
10. Retrieves OP configuration
The AS uses the iss
claim to get the issuer’s configuration. The url is the issuer claim with /.well-known/openid-configuration
appended to the end.
Request
GET https://secureauth.example/.well-known/openid-configuration
Response
{ "issuer" : "https://secureauth.example" , "authorization_endpoint" : "https://secureauth.example/authorize" , "token_endpoint" : "https://secureauth.example/token" , "userinfo_endpoint" : "https://secureauth.example/userinfo" , "registration_endpoint" : "https://secureauth.example/register" , "end_session_endpoint" : "https://secureauth.example/endsession" , "jwks_uri" : "https://secureauth.example/jwks" , "response_types_supported" : [ "code" ], "grant_types_supported" : [ "authorization_code" , "refresh_token" ], "subject_types_supported" : [ "public" ], "claims_supported" : [ "sub" , "webid" ], "scopes_supported" : [ "openid" , "webid" , "profile" , "email" , "offline_access" ], "token_endpoint_auth_methods_supported" : [ "client_secret_basic" ], "token_endpoint_auth_signing_alg_values_supported" : [ "ES256" ], "request_object_signing_alg_values_supported" : [ "ES256" ], "id_token_signing_alg_values_supported" : [ "ES256" ], "code_challenge_methods_supported" : [ "plain" , "S256" ], "claims_parameter_supported" : false , "request_parameter_supported" : true , "request_uri_parameter_supported" : false , "require_request_uri_registration" : false }
11. Requests JWKS
Using the jwks_uri
field in the openid-configuration, the AS makes a request to retreive the
OP’s public keys.
Request
GET https://secureauth.example/jwks
Response (application/json)
{ "keys" : [ { "alg" : "EC" , "crv" : "P-256" , "kid" : "Xu68Q0ZfwDiRfWOb2UE8N77GoEQQ7q58_3gl1wsKENs" , "kty" : "EC" , "use" : "sig" , "x" : "qBbrIQNVTIm7M88iJFVB3e1GqsbFbYYfFiibkd48_Ac" , "y" : "SCl_hDR_6SEuJhKFOiVo8-zLqNglZ56jiJw2_PNE9hU" } ] }
Notice that the keys
field is an array, so an OP could have multiple public keys.
12. Checks ID token signature validity
Using the kid
value in the ID token, the AS searches the OP public keys for one that matches the
one used to sign the ID token. If no public key is found, the AS must reject the request.
13. Access Token Response
Now that the AS has performed all of its checks, we can trust that the agent in the webid
claim (https://alice.coolpod.example/profile/card#me
) is the same agent on whose behalf the
request was made. Using that information, the AS performs authorization and returns access token.
Response:
{ "access_token" : "sbjsbhs(/SSJHBSUSSJHVhjsgvhsgvshgsv" , "token_type" : "Bearer" }
14. Sends request with Access Token
Note: In practice client would need to upgrade RPT by pushing authorization related claim. This primer only focuses on authentication so we omit this detail here.
With the access token, we’re ready to make our request.
GET https://bob.otherpod.example/private/photo_album.ttl Headers: { authorization: "Bearer sbjsbhs(/SSJHBSUSSJHVhjsgvhsgvshgsv", }
15. Returns Result
Given all went well, the RS should return the requested content.


--- layout: post status: publish published: true title: Series Recap—Cubs vs. Rockies (4/25–4/27) author: display_name: Kurt login: Kurt email<EMAIL_ADDRESS>url: '' author_login: Kurt author_email<EMAIL_ADDRESS>wordpress_id: 5127 wordpress_url: http://ivyenvy.com/?p=5127 date: '2011-04-28 15:17:03 +0000' date_gmt: '2011-04-28 20:17:03 +0000' categories: - Series Recap tags: - cubs - Kosuke Fukudome - Rockies - Starlin Castro - Jeff Baker - Carlos Pena - Matt Garza - James Russell - Darwin Barney - Jorge De La Rosa comments: - id: 3413 author: Ryan author_email<EMAIL_ADDRESS>author_url: '' date: '2011-05-03 11:38:23 +0000' date_gmt: '2011-05-03 16:38:23 +0000' content: "Baker impresses me the most out of anybody. \r\n\r\nSometimes it's the little things\r\n\r\nMeehan" ---
Cubs enter the series 10-11 and exit the series 10-13.
Rockies enter the series 14-7 and exit the series 16-7.
Monday April 25 - Rockies 5 Cubs 3
WP - Rogers (3-1)
LP - Garza (0-3)
SV - Street (8)
Darwin Barney hit his first major league home run, Fukedome was 5-5 (a career high), Baker 3-4 and Garza pitched 6 innings and gave up just three hits with 7 strike outs...CUBS LOSE.
Sounds impossible, but 4 team errors, three by Castro in the same inning, and 12 stranded will do it. The Rockies were able to squeak out 5 runs on just 4 hits while the Cubs could manage only 3 runs on 11 hits. That stat looks even worse when you consider that two of the runs were from Barney's two-run homer. The horrendous situational hitting continued. They were 0-12 with runners in scoring position in this game.
Poor Matt Garza. He was responsible for one of the errors, but he should have picked up a W, but instead is 0-3. I'm not sure if it's good team unity or just bad baseball cliche, but after the game it seemed like every player stepped up with an entry into the "It was my fault", "No, it's my fault" game.
This game recap could go on, but I'm going to cut it off there. You just need to know that the Cubs played horribly and we all need to hope this is just a fluke game that won't happen again, or at least not often. What's most upsetting is that the Cubs have broken their + or - 1 game from .500 streak and won't be 11-11 this season. Very sad.
Tuesday April 26 - Cubs 3 Rockies 4
WP - De La Rosa (4-0)
LP - Russell (1-3)
S - Street (9)
It was clear that this would be a tough matchup for the Cubs before it ever started. They were facing Jorge De La Rosa who came in 3-0 with an ERA below 3, James Russell was up for his third fill-in start and the wind was blowing out at 12 mph. Russell did manage to go 4 innings, allowing 5 runs. I can't be too upset with Russell. He gave up three home runs on a windy night to a good offense. When he exited the Cubs were only down 2 and still in the game.
After giving up 2 in the first, De La Rosa settled down leaving after 7 with 9 strike outs. He shut the Cubs down on a night they should have scored a lot of runs.
This game was right on track with what we've seen from this team so far this season. The starting pitching could have been better and the offense just couldn't score. Not surprisingly, Barney and Baker—getting his 5th start at first—were both 2-4 and Castro picked up a hit and scored a run. Soriano is in mid-season bat-flip form as seen following his nearly meaningless solo shot in the 9th inning. And thankfully, the Cubs did not have any errors in this game.
Wednesday April 27 – Postponed until June 27
I can imagine that scheduling 162 games for 30 teams is not easy, but it seems a little odd to me the Cubs scheduled so many games at Wrigley with NL West teams in April (12 of 27 games). It rains a lot in April and scheduling make up games has to be difficult. Luckily, both the Cubs and Rockies have a scheduled day off on June 27.
E-6. If you're scoring at home practice writing that. Starlin Castro has 7 errors. Milwaukee only has 7 as a team. The Cubs have committed 20 errors. Only Oakland, Houston and Washington have more. Not good company.
Carlos Pena really sucks. .169, 22 K. Average pitchers make him look silly. He has yet to hit a home run
Jeff Baker does not suck. He's is hitting .409. Baker is probably not an every day first baseman, but you can't let this guy sit on the bench. In 5 games playing first Baker is hitting .412 with 2 doubles and 5 RBI. I'm just sayin'.


|
MLIB
|
Representation of a simple, non-intersecting polygon that partitions the 2D space in two regions. More...
Public Member Functions | |
| Border () | |
| Create an empty border object. | |
| Border (const char *fname) | |
| Load a border object from a text file. | |
| void | add (double x, double y) |
| void | close (double x, double y) |
| bool | inside (double x, double y) |
| Check if a point is inside the border. More... | |
The polygon is represented by its vertexes and it is always assumed that there is a segment joining the last point with the first point. A Border object can be stored in a text file where each line represents a vertex. The last vertex defines what is considered the "inside" of the polygon: if the point lays inside the polygon, it is an "island" border. If the last point is outside the polygon, it is a "hole" border.
| bool mlib::Border::inside | ( | double | x, |
| double | y | ||
| ) |
| x | - X coordinate of the point |
| y | - Y coordinate of the point |
Algorithm adapted from W. Randolph Franklin wrf@e cse. rpi.e duhttp://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html


Saudi King Salman: Oil policy aims for stability of global oil market
by Eren SengezerSaudi Arabia's oil policy aims for the stability of the global oil market, serving producers and consumers alike, Saudi Arabia's King Salman said in an annual address to the Shura Council advisory body on Wednesday.
Salman further added that they aim for security and reliability of oil supplies. "The ability of Aramco to quickly restore oil production capacity after the September attacks proves the Kingdom's ability to meet global demand during any shortage."
Crude oil largely ignored these comments and the barrel of West Texas Intermediate was trading at $55.60, adding nearly 1% on the day.


4 Day Trip (Cultural Zone)
Day 1: Cusco → Bamboo Lodge
- Departure from Hotel in Cusco
- Breakfast in Huancarani
- Ninamarka Archeological Site
- Paucartambo Museum
- Manu National Park
- Wildlife Spotting in the Cloud Forest
- Lunch on Manu Roa
- Wildlife Spotting on Manu Road
- Dinner upon arrival at Bamboo Lodge
Our trip begins around 6:00 am from your Hotel. Our guide will pick you up, along with other guests on your trip. We will start the trip by driving up the beautiful Andes Mountains. After a quick breakfast in the small town of Hauncarani, we will visit the pre-Inca Archeological site of Ninamarka and the Paucartambo Inca Museum. After we cross the peaks, we will start our decent into the Cloud Forest. This is the entrance to the Amazon Rainforest and will be our first chance to see unique flora and fauna, including monkeys, unique plants, and several bird species. If we are lucky, we might see Peru's national bird, "Cock of the Rock." We will stop for lunch down this legendry road, spotting wildlife all along the way. When we reach the bottom, we will arrive at the "Bamboo Lodge" for the night. Here we will enjoy dinner and have a look around the forest.
Day 2: Bamboo lodge → Soga de Oro Lodge
- Morning walk around the Lodge
- Breakfast
- Visit to Wildlife Recue Center
- Wildlife Spotting on the way to Atalaya
- Motorized Canoe to Soga de Oro Lodge
- Lunch
- Rainforest Trek
- Dinner
- Optional Night Hike
In the morning, we will take a small walk around the lodge to see the local banana trees and crops. Then we will enjoy breakfast before starting our drive towards Atalaya. We will spot many species on the road. We will also stop at a small Wildlife Rescue Center, where several animals have been rescued from the Black Market. When we reach Atalaya, we will get our Rubber Boots and transfer to a motorized canoe. This will take us down the Rio Madre de Dios to the Soga de Oro Lodge where we will be spending the next two nights. We will have lunch and trek around the surrounding rainforest. After dinner, we will offer an optional night hike to see nocturnal animals like snakes, frogs, and insects.
Day 3: Soga de Oro Lodge
- Early departure for the Clay-lick to see Parrots and Macaws
- Breakfast
- Rainforest Trek
- Lunch
- Paddle Boat / Rafting on Machuwasi lake
- Dinner
- Optional Night Hike
We will be leaving the lodge at 5:00 am on this morning. The boat will drop us off for an up-close look at one of the world famous Clay licks. Parrots and Macaws rely on this clay for nutrition. Afterwards, we have breakfast and will go on a rainforest trek. There will be many opportunities to see wildlife and to learn about this extremely diverse region of the Amazon. Later in the day, we will visit Machuwasi Lake to see several species of birds, including the ancient Hoatzin. We will have a relaxing afternoon on Balsa wood paddle boats around the lake. After dinner, a night hike is optional.
Day 4: Bamboo Lodge → Cusco
- Breakfast
- Boat to Atalaya
- Wildlife Spotting on Manu Road
- Lunch
- Drop off at Hotel in Cusco
After breakfast, we will take the boat back to Atalaya. Then we will take the van back towards the Manu Road. Here we will have another wonderful chance to spot wildlife at every altitude along the road. With every change in elevation, we enter a new ecosystem with its own species of flora and fauna. We will have lunch on the road before making our final drive towards Cusco.
What's Included?
- Naturalist guide — English and Spanish (with telescope and books)
- Snacks, juices and mineral water
- Meals (breakfast, lunch and dinner)
- Lodging
- Private bus and boat
- Entrance to Clay-lick & Lake
- Rubber boots
What to bring?
- Light clothes
- Long sleeve shirts and pants
- Hiking or quality Tennis shoes
- Sun glasses
- Sun block
- Insect repellent
- Sandals
- Camera (the guide will tell you where to charge your batteries in this trip)
- Water Bottle (we will provide drinking water every day)
- Raincoat or Pancho
- Binoculars (can rent from your Guide prior to departure)
6 Day Trip (Reserved Zone)
Day 1: Cusco → Bamboo Lodge
- Departure from Hotel in Cusco
- Breakfast in Huancarani
- Ninamarka Archeological Site
- Paucartambo Museum
- Manu National Park
- Wildlife Spotting in the Cloud Forest
- Lunch on Manu Roa
- Wildlife Spotting on Manu Road
- Dinner upon arrival at Bamboo Lodge
Our trip begins around 6:00 am from your Hotel. Our guide will pick you up, along with other guests on your trip. We will start the trip by driving up the beautiful Andes Mountains. After a quick breakfast in the small town of Hauncarani, we will visit the pre-Inca Archeological site of Ninamarka and the Paucartambo Inca Museum. After we cross the peaks, we will start our decent into the Cloud Forest. This is the entrance to the Amazon Rainforest and will be our first chance to see unique flora and fauna, including monkeys, unique plants, and several bird species. If we are lucky, we might see Peru's national bird, "Cock of the Rock." We will stop for lunch down this legendry road, spotting wildlife all along the way. When we reach the bottom, we will arrive at the "Bamboo Lodge" for the night. Here we will enjoy dinner and have a look around the forest.
Day 2: Bamboo Lodge → Hummingbird Lodge
- Breakfast
- Visit to Wildlife Recue Center
- Wildlife Spotting on the way to Atalaya
- 6 hour Motorized Canoe to Hummingbird Lodge
- Lunch on the River
- Diner at the Lodge
- Optional Night Hike
This day we will travel three hours by car and six hours navigating the Madre de Dios River. After breakfast, we will begin our journey spotting wildlife along the road. We will also stop at a small Wildlife Rescue Center, where several animals have been rescued from the Black Market. When we reach Atalaya, we will get our Rubber boots and transfer to a motorized canoe. This will take us down the Rio Madre de Dios. Lunch will be provided on this 6 hour boat trip. Here, we will have many chances to see wildlife on the river bank. In the evening, we will arrive at the Hummingbird Lodge for dinner. There will be an optional night hike to see nocturnal animals like snakes, frogs, and insects.
Day 3: Hummingbird Lodge → Casa Matsiguenka / Manu National Park
- Breakfast at the Lodge
- Boat down the river to see wildlife
- Arrival to Casa Matsiguenka Lodge
- Lunch at the Lodge
- Oxbow Lake to see wildlife
- Dinner at the Lodge
- Optional Night Hike
We leave early in the morning after breakfast. This is one of the best days on the Manu River. We will take every advantage to see wildlife in the rainforest. In about four hours we will arrive at Casa Matsiguenka (a lodge in Manu National Park) where the locals will be waiting for us. After lunch, we will visit an Oxbow Lake to see giant river otters, caimans, monkeys and many birds. In the evening we will enjoy dinner and an optional night hike.
Day 4: Casa Matsiguenka Lodge → Tambo Blanquillo Lodge
- Breakfast at the Lodge
- Visit to a nearby Oxbow Lake
- Lunch
- Boat ride to the Blanquillo Lodge
- Visit to the Tapir Lick
- Diner
- Optional Night Hike
After breakfast, we will be visiting another Oxbow lake in Manu National Park. This will increase our chances of seeing many species of animals. After lunch, we will go down the Manu River to the Tambo Blanquillo lodge. After settling in, we will visit the Tapir Clay Lick. This is a unique area of the forest where giant Tapir come to get nutrients. After diner we will provide an optional night hike.
Day 5: Tambo Blanquillo Lodge
- Early departure to Macaw Clay Lick
- Breakfast in the Blind during Macaw show
- Lunch upon return to the Lodge
- Afternoon Rainforest Trek
- Visit to an Oxbow Lake
- Dinner at Lodge
- Optional Night Hike
This is the best day to see extreme activity of the Parrots, Parakeets and Macaws. We will be going to a blind to enjoy breakfast, 50 meters from the Clay Lick early in the morning. Here, we also have a great chance to see Monkeys, Tapir and many other animals. After this we will go back to the lodge for lunch. In the afternoon, we will go trekking in the trails of the rainforest. We will also visit another oxbow lake see the river otters. We will enjoy dinner at the lodge and have one last chance at a night hike.
Day 6: Tambo Blanquillo Lodge → Cusco
- Breakfast at the Lodge
- Boat Ride to Atalaya
- Wildlife spotting on the Road
- Lunch
- Wildlife spotting in the Cloud Forest
- Arrival to Cusco at 5:00-6:00pm
Today we leave in the morning after a nice breakfast. We will travel by boat to Atalaya. Then we will transfer to Van and take Peru's Trans-oceanic road back to Cusco. We will enjoy its amazing views and landscapes, making some stops on the way. We will have lunch, surrounded by nature on the road. Then we will continue our drive through the Cloud Forest. We will arrive in Cusco around 5:00-6:00pm.
What's included?
- Entrance to Manu National Park
- Naturalist guide — English and Spanish (with telescope and books)
- Snacks, juices and mineral water
- Meals (breakfast, lunch and dinner)
- Lodging
- Private bus and boat
- Entrance to Clay-lick & Lakes
- Rubber boots
What to bring?
- Light clothes
- Long sleeve shirts and pants
- Hiking or quality Tennis shoes
- Sun glasses
- Sun block
- Insect repellent
- Sandals
- Camera (the guide will tell you where to charge your batteries in this trip)
- Water Bottle (we will provide drinking water every day)
- Raincoat or Pancho
- Binoculars (can rent from your Guide prior to departure)
Contact and Booking
You can use the following form to find out about pricing, scheduling, or for any other information.
We will contact you as soon as possible.
Terms and Conditions
Cancellation: A portion of your trip cost will be paid as a deposit. This is a 100% non-refundable deposit. The rest of your trip cost will be returned if cancelation takes place 30 days or more prior to departure. If the client decides to cancel anytime within 30 days, there is no refund. If the client decides not to participate in parts of the tour, there is no refund.
- Adventure Amazon is not liable for additional food or alcohol not specified in the individual trip itinerary.
- The tour itineraries may be changed due to river or road conditions beyond the control of our company. Lodges or Hotels of the same standard may be substituted.
- We recommend purchasing travel insurance for illness, injury, death, theft, loss, accidents, acts of God, war, or flooding. This includes emergency evacuation or any medical costs.
- Adventure Amazon is not liable for any illness, injury, death, theft, loss, or accidents.
- Client's belongings are at his or her own risk.
- All of our Lodges are double rooms. If you wish to have single accommodation, it will cost extra. Please let us know if you need single accommodation.
- Clients are responsible for insurance on valuables such as camera equipment, binoculars, scopes, laptop, etc.
- Adventure Amazon reserves the right to cancel the trip before departure for any reason whatsoever. This includes insufficient group numbers, disasters, strikes, war, earthquakes, or flooding. The refund of all payments received that have not yet been used for the trip shall exclude Adventure Amazon from any liability.
- When signing up for a tour with Adventure Amazon, you agree to follow the instructions of your tour guide.
- In the event that you go on walks on your own, Adventure Amazon cannot be held responsible for any damages or injuries.
- If the road is too dangerous to pass, we may be late on our return to Cusco. Adventure Amazon is not liable for any missed flights or travel reservations up to 48 hours from our scheduled return to Cusco.
- For any further questions please contact us at AdventureAmazon1@gmail.com


RRS-OACIS (RoboCupRescue Simulation OACIS) is simulation management software for RoboCupRescue simulation．It manages agents (autonomous programs that operate in disaster simulation), maps (geographic data, scenario data), simulation itself, execution results. RRS-OACIS can conduct research and competition using managed data.
(The following images can be enlarged)
This document explains how to simulate using RRS-OACIS, the configuration is as follows.
Install and initialize the server.
After explaining how to upload Agent and Map, I will introduce a simple simulation method using Run App．
It is explanation about various operations
It shows how to add an App


View source code
Display the source code in core/stdc/errno.d from which this page was generated on
github.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
local clone.
Page wiki
View or edit the community-maintained wiki page associated with this page.
Module core.stdc.errno
D header file for C99.
This module contains bindings to selected types and
functions from the standard C header <errno.h>
. Note that this
is not automatically generated, and may omit some types/functions from the
original C header.
Standards
ISO/IEC 9899:1999 (E)
Functions
| Name | Description |
|---|---|
errno
|
Enum values
Authors
Sean Kelly, Alex Rønne Petersen
License
Distributed under the Boost Software License 1.0. (See accompanying file LICENSE)


Settings Panel
Welcome to your AttendanceBot Dashboard. Here you can view everything that needs you attention.
Set your space working session
Roles
Working Week
Time Tracking Settings
Attendance Report
Punch Permissions


Nyzo version 584 (commit on GitHub) corrects an issue that was preventing the client from forwarding cycle-signature transactions.
This version affects the client only.
This version is due to a bug report by a community member who opened an issue on GitHub.
The TransactionForwardCommand is an exceptionally useful functionality provided by the client. With it, a user can create a transaction with zero knowledge of the current state of the blockchain and pass to the client all responsibility for getting that transaction into the blockchain. The endpoint provided by this command is already used by the Chrome extension for quickly and easily sending tips.
However, this command was not working for cycle-signature transactions. The issue was due to cycle-signature transactions lacking a receiver identifier.
In TransactionForwardCommand.run(), the receiver identifier of the transaction was not checked for a null value. This caused an exception to be thrown when the value was used to create a NyzoStringPublicIdentifier for display in the result table. A null check was added for this value, and another null check was added to provide better typing for the hexadecimal value.


Find-A-Way
We'll help you find a way to your destination that is cost efficient.
Home
About Us
Meet Our Team
Contact Us
Current Location
*
Destination
*
Departure Time
No. of People
Submit
Uber X
Uber Pool
Driving
Estimated Price
Estimated Duration (minutes)
*Driving costs are calculated on the basis of hourly parking and average gas price (US Dollar).


NEWS.md
Changes:
Added rules for translating implicit string concatenation to BigQuery.
Added getTempTablePrefix()
function.
Changes:
listSupportedDialects()
function.Bugfixes:
DATEFROMPARTS
and DATETIMEFROMPARTS
translation for newer SQLite versions by first converting to INT
before converting to TEXT
.Changes:
Added Apache Spark dialect (“spark”).
Adding automated check whether correct Java Jar file is loaded, throws warning if not.
Adding translation of CEILING()
for SQLite.
Bugfixes:
Fixing setting of global tempEmulationSchema
option.
Workaround for SUBSTR()
function bug in newer versions of SQLite (by explicitly casting string to type STRING
).
Changes:
Deprecating oracleTempSchema
argument in various functions in favor of tempEmulationSchema
schema, which can also be set globally using the sqlRenderTempEmulationSchema
option.
Adding translation of DATEDIFF(YEAR, …) and DATEDIFF(MONTH, …) to all dialects.
Updated createRWrapperForSql()
to latest SqlRender standards.
Bugfixes:
Fixed translation of CTE without FROM or UNION in BigQuery.
Fixed translation of CONVERT(DATE…) in SQLite.
Fixed translation of DATEDIFF with literals in SQLite.
Bugfixes:
Changes:
loadRenderTranslateSql()
cannot find the SQL file in the specified package.Bugfixes:
On SQLite, DATEADD and CONVERT functions now cast to REAL (used to represent DATE / DATETIME).
On SQLite, DATEADD function now works when amount to add is not a verbatim number.
Changes:
Adding rules for modulus operator for BigQuery.
Deleting UPDATE STATISTICS statement for BigQuery.
Changes:
Adding support for Apache Hive LLAP.
Adding functions to convert camelCase to Title Case. (camelCaseToTitleCase)
Changes:
Added rules for SQLite for LEFT and RIGHT functions.
SQLite now dropping schema name when creating and dropping index (as this throws an error if left).
No longer automatically casting literal to TEXT in RedShift CTE. Users are required to do explicit casts instead.
BigQuery insertTable now also uses CTAS hack.
Added translation rules for HASHBYTES.
Bugfixes:
Fixing GETDATE translation for SQLite.
When calling ‘render’, the replacement value can now contain a $ sign. (Previously this caused an error).
isNumeric can now also be applied to numeric fields in Postgres.
Better handling of illegal characters in Impala.
Changes:
Bugfixes:
Changes:
Bugfixes:
Changes:
Major overhaul of BigQuery translation.
Added support for SQLite.
ISNUMERIC translation implemented for Impala, Netezza, and BigQuery.
Performance improvement for Impala temp tables (CREATE TABLE … STORED AS PARQUET).
Adding functions render
and translate
that output strings instead of lists. Deprecating renderSql
and translateSql
.
Added function translateSingleStatement
.
Bugfixes:
Dropping WHERE clause when translating CREATE INDEX for PDW.
Fixed PDW’s equivalent of CREATE TABLE IF NOT EXISTS.
Changes:
Bugfixes:
Changes:
Bugfixes:
Changes:
Improved support for Netezza.
Added random distribution hints for PDW, RedShift, Netezza.
Improved MPP index translation for PDW and Netezza.
Warnings about missing parameters when rendering SQL can now be turned off.
Bugfixes:
Changes:
Better handling of ‘FROM DUAL’ for Oracle.
Improved support for Netezza and Impala.
Changes:
Bigquery support for mismatched string and int arguments in coalesce.
Translate decimal to float for BigQuery.
Created rules to add dummy ‘group by’ for Oracle statements combining ‘case’ and ‘count’ to prevent Oracle from crashing.
Adding ‘UNBOUNDED PRECEDING’ to RedShift windowing functions.
Changes:
Added a Shiny app for developing parameterized SQL, and view how this would be rendered and translated into the various supported dialects.
Added support for Google BigQuery.
Added many more rules for Amazon RedShift, including support for optimization hints.
Added rules for DELETE FROM translation for Impala.
Bugfixes:
Changes:
Bugfixes:
Fixed bug when trying to split SQL where reserved word ‘end’ is used as a field name.
Fixes for Impala translations.
Fixed translation issues for Oracle involving ‘FROM DUAL’.
Added workaround for Oracle bug for intervals greater than 99 days.
Fixed bug when trying to split SQL where last line has comment but no EOL.
Changes:
Added ability to use regular expression in translation patterns. This allowed SELECT TOP n to be translated.
Deprecated sourceDialect argument.
Added translation for CONCAT function with >2 arguments to Oracle (which only allows 2 arguments)
Added hints for translation optimization to massive parallel platforms like RedShift
Throw warnings when translateSql is called with variable names that are not in the SQL
Throw warnings when table names are too long for Oracle
Bugfixes:


Apply
Overview
Program
Team
FAQ
Partners
San Francisco Entrepreneurship in Residence
Bring real solutions to real public sector challenges.
Coming Soon


ppmforge(1) ppmforge(1) NAME ppmforge - fractal forgeries of clouds, planets, and starry skies SYNOPSIS ppmforge [-clouds] [-night] [-dimension dimen] [-hour hour] [-inclination|-tilt angle] [-mesh size] [-power factor] [-glaciers level] [-ice level] [-saturation sat] [-seed seed] [-stars fraction] [-xsize|-width width] [-ysize|-height height] DESCRIPTION ppmforge generates three kinds of ``random fractal forgeries,'' the term coined by Richard F. Voss of the IBM Thomas J. Watson Research Center for seemingly realistic pictures of natural objects generated by simple algo‐ rithms embodying randomness and fractal self-similarity. The techniques used by ppmforge are essentially those given by Voss[1], particularly the technique of spectral synthesis explained in more detail by Dietmar Saupe[2]. The program generates two varieties of pictures: planets and clouds, which are just different renderings of data generated in an identical manner, illustrating the unity of the fractal structure of these very different objects. A third type of picture, a starry sky, is synthesised directly from pseudorandom numbers. The generation of planets or clouds begins with the preparation of an ar‐ ray of random data in the frequency domain. The size of this array, the ``mesh size,'' can be set with the -mesh option; the larger the mesh the more realistic the pictures but the calculation time and memory require‐ ment increases as the square of the mesh size. The fractal dimension, which you can specify with the -dimension option, determines the rough‐ ness of the terrain on the planet or the scale of detail in the clouds. As the fractal dimension is increased, more high frequency components are added into the random mesh. Once the mesh is generated, an inverse two dimensional Fourier transform is performed upon it. This converts the original random frequency domain data into spatial amplitudes. We scale the real components that result from the Fourier transform into numbers from 0 to 1 associated with each point on the mesh. You can further modify this number by applying a ``power law scale'' to it with the -power option. Unity scale leaves the numbers unmodified; a power scale of 0.5 takes the square root of the numbers in the mesh, while a power scale of 3 replaces the numbers in the mesh with their cubes. Power law scaling is best envisioned by thinking of the data as representing the elevation of terrain; powers less than 1 yield landscapes with vertical scarps that look like glacially-carved valleys; powers greater than one make fairy-castle spires (which require large mesh sizes and high resolution for best results). After these calculations, we have a array of the specified size contain‐ ing numbers that range from 0 to 1. The pixmaps are generated as fol‐ lows: Clouds A colour map is created that ranges from pure blue to white by increasing admixture (desaturation) of blue with white. Num‐ bers less than 0.5 are coloured blue, numbers between 0.5 and 1.0 are coloured with corresponding levels of white, with 1.0 being pure white. Planet The mesh is projected onto a sphere. Values less than 0.5 are treated as water and values between 0.5 and 1.0 as land. The water areas are coloured based upon the water depth, and land based on its elevation. The random depth data are used to cre‐ ate clouds over the oceans. An atmosphere approximately like the Earth's is simulated; its light absorption is calculated to create a blue cast around the limb of the planet. A function that rises from 0 to 1 based on latitude is modulated by the local elevation to generate polar ice caps--high altitude ter‐ rain carries glaciers farther from the pole. Based on the po‐ sition of the star with respect to the observer, the apparent colour of each pixel of the planet is calculated by ray-tracing from the star to the planet to the observer and applying a lighting model that sums ambient light and diffuse reflection (for most planets ambient light is zero, as their primary star is the only source of illumination). Additional random data are used to generate stars around the planet. Night A sequence of pseudorandom numbers is used to generate stars with a user specified density. Cloud pictures always contain 256 or fewer colours and may be displayed on most colour mapped devices without further processing. Planet pic‐ tures often contain tens of thousands of colours which must be compressed with ppmquant or ppmdither before encoding in a colour mapped format. If the display resolution is high enough, ppmdither generally produces bet‐ ter looking planets. ppmquant tends to create discrete colour bands, particularly in the oceans, which are unrealistic and distracting. The number of colours in starry sky pictures generated with the -night option depends on the value specified for -saturation. Small values limit the colour temperature distribution of the stars and reduce the number of colours in the image. If the -saturation is set to 0, none of the stars will be coloured and the resulting image will never contain more than 256 colours. Night sky pictures with many different star colours often look best when colour compressed by pnmdepth rather than ppmquant or pp‐ mdither. Try newmaxval settings of 63, 31, or 15 with pnmdepth to reduce the number of colours in the picture to 256 or fewer. OPTIONS -clouds Generate clouds. A pixmap of fractal clouds is generated. Se‐ lecting clouds sets the default for fractal dimension to 2.15 and power scale factor to 0.75. -dimension dimen Sets the fractal dimension to the specified dimen, which may be any floating point value between 0 and 3. Higher fractal di‐ mensions create more ``chaotic'' images, which require higher resolution output and a larger FFT mesh size to look good. If no dimension is specified, 2.4 is used when generating planets and 2.15 for clouds. -glaciers level The floating point level setting controls the extent to which terrain elevation causes ice to appear at lower latitudes. The default value of 0.75 makes the polar caps extend toward the equator across high terrain and forms glaciers in the highest mountains, as on Earth. Higher values make ice sheets that cover more and more of the land surface, simulating planets in the midst of an ice age. Lower values tend to be boring, re‐ sulting in unrealistic geometrically-precise ice cap bound‐ aries. -hour hour When generating a planet, hour is used as the ``hour angle at the central meridian.'' If you specify -hour 12, for example, the planet will be fully illuminated, corresponding to high noon at the longitude at the centre of the screen. You can specify any floating point value between 0 and 24 for hour, but values which place most of the planet in darkness (0 to 4 and 20 to 24) result in crescents which, while pretty, don't give you many illuminated pixels for the amount of computing that's required. If no -hour option is specified, a random hour angle is chosen, biased so that only 25% of the images generated will be crescents. -ice level Sets the extent of the polar ice caps to the given floating point level. The default level of 0.4 produces ice caps simi‐ lar to those of the Earth. Smaller values reduce the amount of ice, while larger -ice settings create more prominent ice caps. Sufficiently large values, such as 100 or more, in conjunction with small settings for -glaciers (try 0.1) create ``ice balls'' like Europa. -inclination|-tilt angle The inclination angle of the planet with regard to its primary star is set to angle, which can be any floating point value from -90 to 90. The inclination angle can be thought of as specifying, in degrees, the ``season'' the planet is presently experiencing or, more precisely, the latitude at which the star transits the zenith at local noon. If 0, the planet is at equinox; the star is directly overhead at the equator. Posi‐ tive values represent summer in the northern hemisphere, nega‐ tive values summer in the southern hemisphere. The Earth's in‐ clination angle, for example, is about 23.5 at the June sol‐ stice, 0 at the equinoxes in March and September, and -23.5 at the December solstice. If no inclination angle is specified, a random value between -21.6 and 21.6 degrees is chosen. -mesh size A mesh of size by size will be used for the fast Fourier trans‐ form (FFT). Note that memory requirements and computation speed increase as the square of size; if you double the mesh size, the program will use four times the memory and run four times as long. The default mesh is 256x256, which produces reasonably good looking pictures while using half a megabyte for the 256x256 array of single precision complex numbers re‐ quired by the FFT. On machines with limited memory capacity, you may have to reduce the mesh size to avoid running out of RAM. Increasing the mesh size produces better looking pic‐ tures; the difference becomes particularly noticeable when gen‐ erating high resolution images with relatively high fractal di‐ mensions (between 2.2 and 3). -night A starry sky is generated. The stars are created by the same algorithm used for the stars that surround planet pictures, but the output consists exclusively of stars. -power factor Sets the ``power factor'' used to scale elevations synthesised from the FFT to factor, which can be any floating point number greater than zero. If no factor is specified a default of 1.2 is used if a planet is being generated, or 0.75 if clouds are selected by the -clouds option. The result of the FFT image synthesis is an array of elevation values between 0 and 1. A non-unity power factor exponentiates each of these elevations to the specified power. For example, a power factor of 2 squares each value, while a power factor of 0.5 replaces each with its square root. (Note that exponentiating values between 0 and 1 yields values that remain within that range.) Power factors less than 1 emphasise large-scale elevation changes at the expense of small variations. Power factors greater than 1 increase the roughness of the terrain and, like high fractal dimensions, may require a larger FFT mesh size and/or higher screen resolution to look good. -saturation sat Controls the degree of colour saturation of the stars that sur‐ round planet pictures and fill starry skies created with the -night option. The default value of 125 creates stars which resemble the sky as seen by the human eye from Earth's surface. Stars are dim; only the brightest activate the cones in the hu‐ man retina, causing colour to be perceived. Higher values of sat approximate the appearance of stars from Earth orbit, where better dark adaptation, absence of skyglow, and the concentra‐ tion of light from a given star onto a smaller area of the retina thanks to the lack of atmospheric turbulence enhances the perception of colour. Values greater than 250 create ``science fiction'' skies that, while pretty, don't occur in this universe. Thanks to the inverse square law combined with Nature's love of mediocrity, there are many, many dim stars for every bright one. This population relationship is accurately reflected in the skies created by ppmforge. Dim, low mass stars live much longer than bright massive stars, consequently there are many reddish stars for every blue giant. This relationship is pre‐ served by ppmforge. You can reverse the proportion, simulating the sky as seen in a starburst galaxy, by specifying a negative sat value. -seed num Sets the seed for the random number generator to the integer num. The seed used to create each picture is displayed on standard output (unless suppressed with the -quiet option). Pictures generated with the same seed will be identical. If no -seed is specified, a random seed derived from the date and time will be chosen. Specifying an explicit seed allows you to re-render a picture you particularly like at a higher resolu‐ tion or with different viewing parameters. -stars fraction Specifies the percentage of pixels, in tenths of a percent, which will appear as stars, either surrounding a planet or filling the entire frame if -night is specified. The default fraction is 100. -xsize|-width width Sets the width of the generated image to width pixels. The de‐ fault width is 256 pixels. Images must be at least as wide as they are high; if a width less than the height is specified, it will be increased to equal the height. If you must have a long skinny pixmap, make a square one with ppmforge, then use pnmcut to extract a portion of the shape and size you require. -ysize|-height height Sets the height of the generated image to height pixels. The default height is 256 pixels. If the height specified exceeds the width, the width will be increased to equal the height. All flags can be abbreviated to their shortest unique prefix. BUGS The algorithms require the output pixmap to be at least as wide as it is high, and the width to be an even number of pixels. These constraints are enforced by increasing the size of the requested pixmap if necessary. You may have to reduce the FFT mesh size on machines with 16 bit integers and segmented pointer architectures. SEE ALSO pnmcut(1), pnmdepth(1), ppmdither(1), ppmquant(1), ppm(5) [1] Voss, Richard F., ``Random Fractal Forgeries,'' in Earnshaw et. al., Fundamental Algorithms for Computer Graphics, Berlin: Springer-Ver‐ lag, 1985. [2] Peitgen, H.-O., and Saupe, D. eds., The Science Of Fractal Images, New York: Springer Verlag, 1988. AUTHOR John Walker Autodesk SA Avenue des Champs-Montants 14b CH-2074 MARIN Suisse/Schweiz/Svizzera/Svizra/Switzerland Usenet<EMAIL_ADDRESS>Fax: 038/33 88 15 Voice: 038/33 76 33 Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, without any conditions or restrictions. This software is provided ``as is'' without express or implied warranty. PLUGWARE! If you like this kind of stuff, you may also enjoy ``James Gleick's Chaos--The Software'' for MS-DOS, available for $59.95 from your local software store or directly from Autodesk, Inc., Attn: Science Se‐ ries, 2320 Marinship Way, Sausalito, CA 94965, USA. Telephone:<PHONE_NUMBER> toll-free or, outside the U.S.<PHONE_NUMBER> Ext 4886. Fax:<PHONE_NUMBER>. ``Chaos--The Software'' includes a more comprehensive fractal forgery generator which creates three-dimensional landscapes as well as clouds and planets, plus five more modules which explore other aspects of Chaos. The user guide of more than 200 pages includes an in‐ troduction by James Gleick and detailed explanations by Rudy Rucker of the mathematics and algorithms used by each program. 25 October 1991 ppmforge(1)