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

feat(docs): first draft requirements for the device registration API #69

Merged
merged 1 commit into from Nov 6, 2015

Conversation

@philbooth
Copy link
Contributor

@philbooth philbooth commented Oct 28, 2015

I cobbled this together for discussion, based on the approach taken in #66 and the information in Danny's gist. Hopefully it's a starting point from which to nail down the details of the device registration API.

@shane-tomlinson @rfk r?

@philbooth philbooth force-pushed the phil/fxa-45-requirements branch from 0804821 to eeaa48c Oct 28, 2015

## Stories

Is it reasonable to break these down

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

What do you have in mind for these?

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

Breaking the stories down one per endpoint seems like a good approach to me but I wasn't sure whether you guys would agree, which is why I asked the question.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

"User stories" for a backend-end API is an interesting challenge, but doing one per endpoint seems like a reasonable approach. Also if it doesn't seem like a useful way to frame things, feel free to not have "stories" here. The point isn't to conform to any particular structure, it's just to capture things in a single location.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

It might be interesting to lead with descriptions of behavior from the device's point of view, in order to clarify why we have each of these endpoints and how they fit together into an API "flow". Things like:

  • User creates an account on a brand new device
  • User signs in to a brand new device
  • User signs in to something on the web
  • User signs in to a legacy device with no device-api support
  • User resets their password
  • Users signs in after resetting their password
  • User explicitly signs out from a device
  • User disconnects a device through the web view
  • probably others that we should think through as well...

This comment has been minimized.

@philbooth

philbooth Oct 30, 2015
Author Contributor

I've pushed a first stab at the stories.

I started to come at them from the point of view of the device, then changed tack a bit and came at them from the point of view of the API consumer, whether that be the browser or the content server. Not sure how that sits with you guys, let me know what you think.

Is it reasonable to break these down
one per endpoint?

## Data

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

What sort of data is this?

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

Not 100% sure I understand the question but it's just supposed to be a note about what is stored in the database. I've added an explanatory sentence before to try and clarify that.

## API
### POST /v1/account/login

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

The URL in New device and Registered device sections reference https://api-accounts.dev.lcip.org/v1/account/device

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

What should they reference instead?

##### New device
```
curl -v \

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

Does this API give the ability to register a device as part of login? If so, my guess is the /v1/account/login would both accept email, authPW and an optional device field, which would be the same as the current POST data.

curl -v \
-X POST \
-H "Content-Type: application/json" \
"https://api-accounts.dev.lcip.org/v1/account/login" \
-d '{
  "email": "me@example.com",
  "authPW": "996bc6b1aa63cd69856a2ec81cbf19d5c8a604713362df9ee15c2bf07128efab",
  "device": {
    "name": "My Phone",
    "type": "mobile",
    "callback": "https://updates.push.services.mozilla.com/update/abcdef01234567890abcdefabcdef01234567890abcdef"
  }
}'

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

My bad, there were copy/paste errors here and in some of the other code blocks. Have pushed fixes.

### POST /v1/account/login
Authenticated with session token or OAuth.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

Can login really take an OAuth token? If so, I had no idea.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

Using an OAuth token here doesn't sound right to me.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

Actually it's not authenticated with either of those things, you have to provide the password. Copy-paste from other device-related APIs that are authenticated in that manner?

This comment has been minimized.

@philbooth

philbooth Oct 30, 2015
Author Contributor

Yep, sorry, more copy-paste insanity. Have removed.

If a device id exists for this device,
the request MAY include it
but it MUST also include the other info as well,
since device ids are not globally unique.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

How come device ids are not globally unique? I was not part of that discussion, that context would be useful to have in this document somewhere.

This comment has been minimized.

This comment has been minimized.

@philbooth

philbooth Oct 30, 2015
Author Contributor

As per Ryan's comment, this is not the case any more. Have updated.

"email": "me@example.com",
"authPW": "996bc6b1aa63cd69856a2ec81cbf19d5c8a604713362df9ee15c2bf07128efab",
"device": {
"id": "3d7d",

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

It seems strange to register a device with an already existing device ID. When would that happen?

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

See the question How are shared devices handled? below.

#### Response
Instead of including the `sessionToken` field,

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

Can we add the notion of current, which is a boolean? Since no sessionToken is returned, the front end won't be able to determine which item in the list it is.

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

Assuming nobody else can see a problem with that, it sounds good to me.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

@shane-tomlinson we may actually need to return the sessionToken here, depending on the logic that will be used by the devices view. If it wants to display things that are sessions but don't have a device record, then it will need to be able to match each device record back to its current session token.

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

I've changed this endpoint to return the session token and added a clarifying note pointing out that when the sessionToken field is null it means the device is disconnected.

-H 'Authorization: Hawk id="d4c5b1e3f5791ef83896c27519979b93a45e6d0da34c7509c5632ac35b28b48d", ts="1373391043", nonce="ohQjqb", hash="vBODPWhDhiRWM4tmI9qp+np+3aoqEFzdGuGk0h7bh9w=", mac="LAnpP3P2PXelC6hUoUaHP72nCqY5Iibaa3eeiGBqIIU="' \
https://api-accounts.dev.lcip.org/v1/account/device \
-d '{
"name": "My Phone",

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

Is there any restriction on two devices having the same name, if owned by the same user?

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

It's not prohibited by the database schema. Do you think it should be?

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

I don't think we should enforce this, although we should try to generate unique names when we suggest defaults in the UI

"id": "01ab",
"name": "My Desktop",
"type": "desktop",
"status": "disconnected",

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

What does disconnected mean? Does that mean the user has not connected the device in a while, or it's not available via push, the user has signed out, or that the device has been destroyed?

This comment has been minimized.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

It means that the device does not have a session token, e.g. as a result of password reset zapping all the session tokens but leaving the device records alone. (Unless we make password reset also zap all your device records).

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

Fwiw, I've added an extra question to the Details section that covers this.

It must be:
1. Big enough to make collisions unlikely per account;
2. And small enough not to identify individual accounts.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Oct 28, 2015
Member

How did this requirement come into being? What are we guarding against and why?

This comment has been minimized.

@philbooth

philbooth Oct 28, 2015
Author Contributor

@dannycoates, can you field this one?

This comment has been minimized.

@philbooth

philbooth Oct 30, 2015
Author Contributor

As per Ryan's comment, this requirement no longer exists. Have deleted this section.

@philbooth philbooth force-pushed the phil/fxa-45-requirements branch 2 times, most recently from 041b9e2 to 78f740c Oct 28, 2015
"sessionToken": "27cd4f4a4aa03d7d186a2ec81cbf19d5c8a604713362df9ee15c4f4a4aa03d7d",
// A server assigned identifier for this device
"id":"01ab",

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

I think in the latest drafts these are now full-size uuids, see e.g. mozilla/fxa-auth-db-mysql#110 (comment) and related discussion in that PR.

This comment has been minimized.

@philbooth

philbooth Oct 30, 2015
Author Contributor

Cool, have updated.

"createdAt": 1442785364807,
// The push notification endpoint for this device/user
"callback": "https://updates.push.services.mozilla.com/update/abcdef01234567890abcdefabcdef01234567890abcdef"

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

If we want to send message bodies in our push messages, I think we're going to also need to store a key of some kind here, see e.g. the getKey() method described in [1] and the related encryption spec [2]

[1] https://developer.mozilla.org/en-US/docs/Web/API/Push_API/Using_the_Push_API#Technology_overview
[2] https://tools.ietf.org/html/draft-ietf-webpush-encryption-01

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

I finally got round to reading these links, thanks @rfk.

I'm still a bit sketchy on the details of all the ways that we're going to use the push endpoint. I know one usage is to notify a device that it's been disconnected. Are there others and, if so, what are they?

Assuming there's more than one then, yep, we'll need to send body data and, yep, we'll need to store the public key and, yep, I'll need to update the database.

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

I realise that none of the push use-cases are covered by stories yet. So I've added a story to cover the disconnected push notification and will also add any others as they come up here.

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

I'm still a bit sketchy on the details of all the ways that we're going to use the push endpoint. I know one usage is to notify a device that it's been disconnected. Are there others and, if so, what are they?

Just chatted about this with @shane-tomlinson and he also came up with:

  • When a new device is connected.
  • When the user changes the device name.
  • When the user changes their password.
  • When the user resets their password.
  • Maybe when there is a profile change.

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

I've updated the readme to include the public key and raised mozilla/fxa-auth-db-mysql#114 to add it to the database.

> particularly if the device fills in a default based on its hardware platform etc.
> If we're going to do recovering devices,
> I think we should let the device provide some sort of fingerprint
> that it's extremely confident will be unique.

This comment has been minimized.

@rfk

rfk Oct 29, 2015
Member

I think we should explicitly de-scope device recovery from the initial version of this feature, and revisit it in mozilla/fxa-auth-server#1077

This comment has been minimized.

@philbooth

philbooth Oct 30, 2015
Author Contributor

Cool, have deleted this section.

@rfk rfk added this to the FxA-45: device registration milestone Oct 29, 2015
@philbooth philbooth force-pushed the phil/fxa-45-requirements branch 5 times, most recently from 066017e to 40c4898 Oct 30, 2015
@vladikoff
Copy link
Contributor

@vladikoff vladikoff commented Nov 2, 2015

for next 2 weeks...

@philbooth philbooth force-pushed the phil/fxa-45-requirements branch 4 times, most recently from 59d3154 to 34eb51a Nov 3, 2015
@philbooth
Copy link
Contributor Author

@philbooth philbooth commented Nov 3, 2015

Marking this as in review again.

@philbooth philbooth removed their assignment Nov 3, 2015
#### Response
```
{

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 3, 2015
Member

Is this under the device namespace like in /account/create?

This comment has been minimized.

@philbooth

philbooth Nov 3, 2015
Author Contributor

Yes. That appears to be yet another sodding copy/paste error, sorry. Fixing.

@philbooth philbooth force-pushed the phil/fxa-45-requirements branch from 76d253b to 701419d Nov 3, 2015
"callback": "https://updates.push.services.mozilla.com/update/abcdef01234567890abcdefabcdef01234567890abcdef",
// The public key for encrypting messages to the push endpoint
"publicKey": "468601214f60f4828b6cd5d51d9d99d212e7c73657978955f0f5a5b7e2fa1370"

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

I'm going to nitpick the names here, because it's not at all obvious that "callback" and "publicKey" are related and should be used as a pair. Perhaps we can put "push" in the name of both somehow, to make it more obvious?

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

Good point, well made. Fixed.


* As an API consumer,
I want to create an account with the auth server
using a registered device id.

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

IIUC, when you're creating a new account, you can't possibly have an existing device id, because device ids are local to the account.

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

Oh yeah, I think I saw that when I looked at the schema but failed to think it through. Have removed this and all the shared device gubbins.

> ISTM that "Bob logs in" implies that Alice gets logged out,
> which could clear the locally-stored device name
> and other FxA-related customizations.
> For a dedicated Firefox device maybe it's not so simple.

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

In our implementation, the device id is subsidiary to the account, so I don't think there's anything useful we can do with the notion of "shared devices". If Bob logs in, the device now belongs to Bob as far as we're concerned. We may be able to just remove this whole section.

from the device list
by the user.
Posting to `/v1/account/device` can attach a new device
to the current session.

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

Would it be better to return null, or to generate and return a new device id? The device clearly wanted to be registered as such.

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

Good point. Just so I understand precisely: if the login request arrives with a new device id and none of the other device info, should that request fail?

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

TBH, I don't know what the best behaviour would be in that case. It may be a case of "try it out and see what feels right".

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

Okey-doke, I've updated this section to specify that a new device record is created and the newly-generated device id is returned in the response. We can cross/burn the other bridge as seems appropriate when we get to it.

@philbooth philbooth force-pushed the phil/fxa-45-requirements branch 5 times, most recently from 8ff5fd8 to 398bd46 Nov 4, 2015
I want to receive a `"disconnected"` push notification
when a registered device transitions to the disconnected state.

### As a user

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

@rfk, I've pushed some new "As a user..." stories to try and capture some of the missing flow that happens outside the auth server.

I'm reluctant to replace the "As an API consumer..." stories with these entirely because I like the granularity that those stories bring. The ones below are a bit fluffier. Am I on the right track with them?

This comment has been minimized.

@rfk

rfk Nov 5, 2015
Member

One tiny nit we be that the user stories should come first, but at that point we're well off into the process-over-product weeds :-)

I think this document completely fulls its purported purpose of "first draft" and we should merge it, and continue to iterate on it concurrently with the implementation. Thanks for pushing this through @philbooth!

This comment has been minimized.

@philbooth

philbooth Nov 6, 2015
Author Contributor

Ha, I realised this too and had it on my list of things to get round to. Will do it in a follow-up PR.

#### Requests
##### New device

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

What happens if a 2nd device is registered for a given sessionToken? Is the existing device removed? Does the endpoint throw a 400/500?

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

If the existing device is removed, is its sessionToken destroyed?

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

What happens if a 2nd device is registered for a given sessionToken?

I think it should be a 400. Will update the doc to clarify.

If the existing device is removed, is its sessionToken destroyed?

Yep, both are deleted by the stored procedure.

-H 'Authorization: Hawk id="d4c5b1e3f5791ef83896c27519979b93a45e6d0da34c7509c5632ac35b28b48d", ts="1373391043", nonce="ohQjqb", hash="vBODPWhDhiRWM4tmI9qp+np+3aoqEFzdGuGk0h7bh9w=", mac="LAnpP3P2PXelC6hUoUaHP72nCqY5Iibaa3eeiGBqIIU="' \
https://api-accounts.dev.lcip.org/v1/account/device \
-d '{
"id": "0f7aa00356e5416e82b3bef7bc409eef",

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

If the ID is unknown, is a 400 error returned?

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

I think the handling should be consistent across endpoints. As we've already said it generates and returns a new device id in this scenario on /v1/account/login, I think the behaviour should be the same here too.

But happy to be over-ruled if you guys think differently.

This comment has been minimized.

@rfk

rfk Nov 5, 2015
Member

Consitency++. However this case should be pretty rare on both endpoints, perhaps there's value in using a 400 error in both places.

We can also revisit this decision as implementation progresses, so let's not get too caught up on it right now.

https://api-accounts.dev.lcip.org/v1/account/device \
-d '{
"name": "My Phone",
"type": "mobile",

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

Are the only two valid types mobile and desktop?

This comment has been minimized.

@philbooth

philbooth Nov 4, 2015
Author Contributor

Actually, the two possibilities at the moment are "mobile" and null. See:

https://github.com/mozilla/fxa-auth-server/blob/master/lib/userAgent.js#L58-L62

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 5, 2015
Member

Looking at the linked code, it looks like type is determined based on the UA string, whereas here, we are passing in an explicit type as determined by the browser.

As an aside, null for desktop seems weird to me, can we have the endpoint accept desktop and it can use whatever representation it pleases internally?

This comment has been minimized.

@philbooth

philbooth Nov 5, 2015
Author Contributor

You're right of course, clearly I was feeling tired when I responded. 😕

If there's a plan to seed legacy device info from the sessionTokens table, this is where it will be seeded from but, of course, there's nothing to stop us translating null into "desktop" as part of that process.

So I'm happy to accept whatever strings you think are suitable, although "desktop" seems weirder than null to me. As a word to describe common computing habits it's becoming an anachronism I think.

This comment has been minimized.

@philbooth

philbooth Nov 5, 2015
Author Contributor

I'm happy to accept whatever strings you think are suitable

Just to be crystal clear, max length in the database is 16 characters.

This comment has been minimized.

@rfk

rfk Nov 5, 2015
Member

If there's a plan to seed legacy device info from the sessionTokens table

I'm less and less excited about this idea, I feel like having a device record that's not actively maintained by the device is a recipe for weirdness.

"pushPublicKey": "468601214f60f4828b6cd5d51d9d99d212e7c73657978955f0f5a5b7e2fa1370"
}
```

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

The auth-server api.md document specifies a list of possible errors for each endpoint, we should probably spec those out here too.

### GET /v1/account/devices
Authenticated with session token or OAuth.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

Are we allowing OAuth tokens to be used to interact with these endpoints?

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

I think we should eventually, but maybe we can drop this req from the initial version since I think all initial consumers will have a sessionToken.

### POST /v1/account/device/destroy
Authenticated with session token or OAuth.

This comment has been minimized.

@shane-tomlinson

shane-tomlinson Nov 4, 2015
Member

If a device is destroyed, does that destroy its sessionToken as well?

This comment has been minimized.

@rfk

rfk Nov 4, 2015
Member

Yes. The lifetime of a devices sessionToken should be bounded by the lifetime of the device itself.

@rfk
Copy link
Member

@rfk rfk commented Nov 6, 2015

I'm going to merge this and file follow-up bugs for a couple of outstanding items.

rfk added a commit that referenced this pull request Nov 6, 2015
feat(docs): first draft requirements for the device registration API
@rfk rfk merged commit acd022e into master Nov 6, 2015
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
continuous-integration/travis-ci/push The Travis CI build passed
Details
@rfk rfk removed the waffle:review label Nov 6, 2015
@philbooth philbooth deleted the phil/fxa-45-requirements branch Nov 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants