/v2/find with select=private has different behaviour for queries and name searches

Bug #1659153 reported by Robert Ancell
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
snapd
Triaged
Low
Unassigned

Bug Description

If you do a /v2/find with select=private the behaviour is different when using a query or a name. The name form will return non-private results from the store, but the query only returns results for private snaps.

When using a query only private results are returned, when using a name non-private results are returned. I would have expected only private results to be selected in both cases.

e.g.
$ sudo nc -C -U /run/snapd.socket
GET /v2/find?q=moon-buggy&select=private HTTP/1.1
Host:
Authorization: Macaroon root="..."

HTTP/1.1 200 OK
Content-Type: application/json
Date: Wed, 25 Jan 2017 00:33:55 GMT
Content-Length: 106

{"type":"sync","status-code":200,"status":"OK","result":[],"sources":["store"],"suggested-currency":"USD"}

$ sudo nc -C -U /run/snapd.socket
GET /v2/find?name=moon-buggy&select=private HTTP/1.1
Host:
Authorization: Macaroon root="..."

HTTP/1.1 200 OK
Content-Type: application/json
Date: Wed, 25 Jan 2017 00:34:29 GMT
Content-Length: 1221

{"type":"sync","status-code":200,"status":"OK","result":[{"channel":"","channels":{"beta":{"revision":"12","confinement":"strict","version":"1.0.51.11","channel":"beta","epoch":"0","size":90112},"candidate":{"revision":"12","confinement":"strict","version":"1.0.51.11","channel":"candidate","epoch":"0","size":90112},"edge":{"revision":"12","confinement":"strict","version":"1.0.51.11","channel":"edge","epoch":"0","size":90112},"stable":{"revision":"12","confinement":"strict","version":"1.0.51.11","channel":"stable","epoch":"0","size":90112}},"confinement":"strict","description":"Moon-buggy is a simple character graphics game, where you drive some kind of car across the moon's surface. Unfortunately there are dangerous craters there. Fortunately your car can jump over them!\r\n","developer":"dholbach","download-size":90112,"icon":"https://myapps.developer.ubuntu.com/site_media/appmedia/2015/11/moon-buggy.jpg.png","id":"2kkitQurgOkL3foImG4wDwn9CIANuHlt","name":"moon-buggy","private":false,"resource":"/v2/find?name=moon-buggy\u0026select=private","revision":"12","status":"available","summary":"Drive a car across the moon","type":"app","version":"1.0.51.11"}],"sources":["store"],"suggested-currency":"USD"}

Tags: papercut
Revision history for this message
Robert Ancell (robert-ancell) wrote :

Actually, now I read the docs more closely:

'private: search private snaps (by default, find only searches public snaps). Can't be used with name, only q (for now at least)."

So I think this should be returning an error when this is attempted.

Revision history for this message
Robert Ancell (robert-ancell) wrote :

The relevant part of the code is (daemon/api.go):

        query := r.URL.Query()
        q := query.Get("q")
        section := query.Get("section")
        name := query.Get("name")
        private := false
        prefix := false

        if name != "" {
                if q != "" {
                        return BadRequest("cannot use 'q' and 'name' together")
                }

                if name[len(name)-1] != '*' {
                        return findOne(c, r, user, name)
                }

                prefix = true
                q = name[:len(name)-1]
        }

        if sel := query.Get("select"); sel != "" {
                switch sel {
                case "refresh":
                        if prefix {
                                return BadRequest("cannot use 'name' with 'select=refresh'")
                        }
                        if q != "" {
                                return BadRequest("cannot use 'q' with 'select=refresh'")
                        }
                        return storeUpdates(c, r, user)
                case "private":
                        private = true
                }
        }

        theStore := getStore(c)
        found, err := theStore.Find(&store.Search{
                Query: q,
                Section: section,
                Private: private,
                Prefix: prefix,
        }, user)

The main issue seems to be if you pass ?name=&select= no BadRequest is generated because the function returns after findOne().

Also note the 'section' parameter is not documented in https://github.com/snapcore/snapd/wiki/REST-API

Revision history for this message
Robert Ancell (robert-ancell) wrote :

I've found the /v2/find to be the hardest part to understand in the REST API due to the interaction between the q, name and select parameters.

The question is, does select=private even need to exist? Since the JSON snap object have a private value, shouldn't all searches return private snaps if authorization is provided? The client can then filter the results if this is required.

Perhaps it would be simpler if select=refresh was replaced with /v2/find/refreshable - this and the above would get rid of the select parameter entirely.

Revision history for this message
Seth Arnold (seth-arnold) wrote : Re: [Bug 1659153] Re: /v2/find with select=private has different behaviour for queries and name searches

On Wed, Jan 25, 2017 at 02:36:13AM -0000, Robert Ancell wrote:
> The question is, does select=private even need to exist? Since the JSON
> snap object have a private value, shouldn't all searches return private
> snaps if authorization is provided? The client can then filter the
> results if this is required.

What's the intention of the 'private' in 'private snaps'? Is the intention
to keep their existence secret? Or just the contents of the snap?

Thanks

Changed in snappy:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
John Lenton (chipaca) wrote :

So... at this point, what remains to be done is to detect and return an error when 'private' is true and 'name' does not end in a *. That is, just before api.go's searchStore calls out to findOne, it should check for private and bail with a 400.

tags: added: papercut
Changed in snappy:
importance: Medium → Low
status: Confirmed → Triaged
Michael Vogt (mvo)
affects: snappy → snapd
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.