Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

276 anonymous session #283

Merged
merged 21 commits into from
Aug 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions docs/sdk/api/sdkMiddlewareAuth.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ const client = createClient({
credentials: {
clientId: '123',
clientSecret: 'secret',
user: {
username: string;
password: string;
}
},
scopes: [
'view_products:test',
Expand All @@ -58,6 +62,7 @@ Creates a [middleware](/sdk/Glossary.md#middleware) to handle authentication for

1. `host` *(String)*: the host of the OAuth API service
2. `projectKey` *(String)*: the key of the project to assign the default scope to
- The user field is an object containining `username` and `password`. [Sample below](#usage-example)
3. `credentials` *(Object)*: the client credentials for authentication (`clientId`, `clientSecret`)
4. `scopes` *(Array)*: a list of [scopes](http://dev.commercetools.com/http-api-authorization.html#scopes) to assign to the OAuth token. _No default scope is sent_

Expand Down Expand Up @@ -89,3 +94,40 @@ const client = createClient({
],
})
```

## `createAuthMiddlewareForAnonymousSessionFlow(options)`

Creates a [middleware](/sdk/Glossary.md#middleware) to handle authentication for the [Anonymous Session Flow](http://dev.commercetools.com/http-api-authorization.html#tokens-for-anonymous-sessions) of the commercetools platform API.

#### Named arguments (options)

1. `host` *(String)*: the host of the OAuth API service
2. `projectKey` *(String)*: the key of the project to assign the default scope to
3. `credentials` *(Object)*: the client credentials for authentication (`clientId`, `clientSecret`, `anonymousId`)
4. `scopes` *(Array)*: a list of [scopes](http://dev.commercetools.com/http-api-authorization.html#scopes) (default `manage_project:{projectKey}`) to assign to the OAuth token


#### Usage example

```js
import { createClient } from '@commercetools/sdk-client'
import { createAuthMiddlewareForAnonymousSessionFlow } from '@commercetools/sdk-middleware-auth'

const client = createClient({
middlewares: [
createAuthMiddlewareForAnonymousSessionFlow({
host: 'https://auth.commercetools.com',
projectKey: 'test',
credentials: {
clientId: '123',
clientSecret: 'secret',
anonymousId: 'unique-id-of-customer-not-required',
},
scopes: [
'view_products:test',
'manage_orders:test',
],
}),
],
})
```
123 changes: 123 additions & 0 deletions integration-tests/sdk/auth.it.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { createClient } from '@commercetools/sdk-client'
import { getCredentials } from '@commercetools/get-credentials'
import {
createAuthMiddlewareForPasswordFlow,
createAuthMiddlewareForAnonymousSessionFlow,
} from '@commercetools/sdk-middleware-auth'
import {
createHttpMiddleware,
} from '@commercetools/sdk-middleware-http'
import { clearData, createData } from './../cli/helpers/utils'

let projectKey
if (process.env.CI === 'true')
projectKey = 'auth-integration-test'
else
projectKey = process.env.npm_config_projectkey

describe('Auth Flows', () => {
let apiConfig
const userEmail = `abi${Date.now()}@commercetooler.com`
const userPassword = 'asdifficultaspossible'
beforeAll(() => getCredentials(projectKey)
.then((credentials) => {
apiConfig = {
host: 'https://auth.sphere.io',
apiUrl: 'https://api.sphere.io',
projectKey,
credentials: {
clientId: credentials.clientId,
clientSecret: credentials.clientSecret,
},
}
})
.then(() => clearData(apiConfig, 'customers'))
.then(() => clearData(apiConfig, 'carts'))
.then(() => createData(apiConfig, 'customers', [{
email: userEmail,
password: userPassword,
}]))
, 10000)
afterAll(() => {
clearData(apiConfig, 'customers')
.then(() => clearData(apiConfig, 'carts'))
})
describe('Password Session Flow', () => {
const httpMiddleware = createHttpMiddleware({
host: 'https://api.sphere.io',
})

it('should log customer and fetch customer profile', () => {
const userConfig = {
...apiConfig,
...{ scopes: [ `manage_project:${projectKey}` ] },
...{ credentials: {
clientId: apiConfig.credentials.clientId,
clientSecret: apiConfig.credentials.clientSecret,
user: {
username: userEmail,
password: userPassword,
},
} },
}
const client = createClient({
middlewares: [
createAuthMiddlewareForPasswordFlow(userConfig),
httpMiddleware,
],
})
return client.execute({
uri: `/${projectKey}/me`,
method: 'GET',
}).then((response) => {
const user = response.body
expect(user).toHaveProperty('email', userEmail)
})
})
})

describe('Anonymous Session Flow', () => {
const httpMiddleware = createHttpMiddleware({
host: 'https://api.sphere.io',
})

it('create an anonymous session and a cart tied to the session', () => {
const anonymousId = `${Date.now()}-bar`
const userConfig = {
...apiConfig,
...{ scopes: [ `manage_project:${projectKey}` ] },
...{ credentials: {
clientId: apiConfig.credentials.clientId,
clientSecret: apiConfig.credentials.clientSecret,
anonymousId,
} },
}
const client = createClient({
middlewares: [
createAuthMiddlewareForAnonymousSessionFlow(userConfig),
httpMiddleware,
],
})
const cartMock = {
currency: 'EUR',
}
return client.execute({
// creates a cart that is tied to the logged in anonymous token
uri: `/${projectKey}/me/carts`,
method: 'POST',
body: cartMock,
}).then(({ body: cart }) => {
expect(cart).toHaveProperty('anonymousId', anonymousId)
return client.execute({
// fetch all carts tied to the anonymous token, if cart is present,
// then the cart was tied to the token
uri: `/${projectKey}/me/carts`,
method: 'GET',
})
}).then(({ body: { results: carts } }) => {
expect(carts).toHaveLength(1)
expect(carts[0]).toHaveProperty('anonymousId', anonymousId)
})
}, 7000)
})
})
70 changes: 0 additions & 70 deletions integration-tests/sdk/customer-login.it.js

This file was deleted.

37 changes: 35 additions & 2 deletions packages/sdk-middleware-auth/src/anonymous-session-flow.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
export default function createAuthMiddlewareForAnonymousSessionFlow () {
throw new Error('Middleware not implemented yet')
/* @flow */
import type {
AuthMiddlewareOptions,
Middleware,
MiddlewareRequest,
MiddlewareResponse,
Next,
Task,
} from 'types/sdk'

import { buildRequestForAnonymousSessionFlow } from './build-requests'
import authMiddlewareBase from './base-auth-flow'
import store from './utils'

export default function createAuthMiddlewareForAnonymousSessionFlow (
options: AuthMiddlewareOptions,
): Middleware {
const tokenCache = store({})
const pendingTasks: Array<Task> = []

const requestState = store(false)
return (next: Next) => (
request: MiddlewareRequest,
response: MiddlewareResponse,
) => {
const params = {
request,
response,
...buildRequestForAnonymousSessionFlow(options),
pendingTasks,
requestState,
tokenCache,
}
authMiddlewareBase(params, next)
}
}
2 changes: 0 additions & 2 deletions packages/sdk-middleware-auth/src/base-auth-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import type {
Task,
AuthMiddlewareBaseOptions,
} from 'types/sdk'

/* global fetch */
import 'isomorphic-fetch'


export default function authMiddlewareBase ({
request,
response,
Expand Down
20 changes: 17 additions & 3 deletions packages/sdk-middleware-auth/src/build-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export function buildRequestForPasswordFlow (
const scope = (options.scopes || []).join(' ')
const scopeStr = scope ? `&scope=${scope}` : ''


const basicAuth = new Buffer(`${clientId}:${clientSecret}`).toString('base64')
// This is mostly useful for internal testing purposes to be able to check
// other oauth endpoints.
Expand All @@ -94,6 +93,21 @@ export function buildRequestForRefreshTokenFlow () {
// TODO
}

export function buildRequestForAnonymousSessionFlow () {
// TODO
export function buildRequestForAnonymousSessionFlow (
options: AuthMiddlewareOptions,
): BuiltRequestParams {
if (!options)
throw new Error('Missing required options')

if (!options.projectKey)
throw new Error('Missing required option (projectKey)')
const pKey = options.projectKey
// eslint-disable-next-line no-param-reassign
options.oauthUri = options.oauthUri || `/oauth/${pKey}/anonymous/token`
const result = buildRequestForClientCredentialsFlow(options)

if (options.credentials.anonymousId)
result.body += `&anonymous_id=${options.credentials.anonymousId}`

return { ...result }
}
Loading