func (s *assertMgrSuite) TestBatchAddStreamReturnsEffectivelyAddedRefs(c *C) { s.state.Lock() defer s.state.Unlock() b := &bytes.Buffer{} enc := asserts.NewEncoder(b) // wrong order is ok err := enc.Encode(s.dev1Acct) c.Assert(err, IsNil) enc.Encode(s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) batch := assertstate.NewBatch() err = batch.Add(s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) refs, err := batch.AddStream(b) c.Assert(err, IsNil) c.Check(refs, DeepEquals, []*asserts.Ref{ {Type: asserts.AccountType, PrimaryKey: []string{s.dev1Acct.AccountID()}}, }) err = batch.Commit(s.state) c.Assert(err, IsNil) db := assertstate.DB(s.state) devAcct, err := db.Find(asserts.AccountType, map[string]string{ "account-id": s.dev1Acct.AccountID(), }) c.Assert(err, IsNil) c.Check(devAcct.(*asserts.Account).Username(), Equals, "developer1") }
func importAssertionsFromSeed(st *state.State) error { device, err := auth.Device(st) if err != nil { return err } // set device,model from the model assertion assertSeedDir := filepath.Join(dirs.SnapSeedDir, "assertions") dc, err := ioutil.ReadDir(assertSeedDir) if err != nil { return fmt.Errorf("cannot read assert seed dir: %s", err) } // FIXME: remove this check once asserts are mandatory if len(dc) == 0 { return nil } // collect var modelRef *asserts.Ref batch := assertstate.NewBatch() for _, fi := range dc { fn := filepath.Join(assertSeedDir, fi.Name()) refs, err := readAsserts(fn, batch) if err != nil { return fmt.Errorf("cannot read assertions: %s", err) } for _, ref := range refs { if ref.Type == asserts.ModelType { if modelRef != nil && modelRef.Unique() != ref.Unique() { return fmt.Errorf("cannot add more than one model assertion") } modelRef = ref } } } // verify we have one model assertion if modelRef == nil { return fmt.Errorf("need a model assertion") } if err := batch.Commit(st); err != nil { return err } a, err := modelRef.Resolve(assertstate.DB(st).Find) if err != nil { return fmt.Errorf("internal error: cannot find just added assertion %v: %v", modelRef, err) } modelAssertion := a.(*asserts.Model) // set device,model from the model assertion device.Brand = modelAssertion.BrandID() device.Model = modelAssertion.Model() if err := auth.SetDevice(st, device); err != nil { return err } return nil }
func doAssert(c *Command, r *http.Request, user *auth.UserState) Response { batch := assertstate.NewBatch() _, err := batch.AddStream(r.Body) if err != nil { return BadRequest("cannot decode request body into assertions: %v", err) } state := c.d.overlord.State() state.Lock() defer state.Unlock() if err := batch.Commit(state); err != nil { return BadRequest("assert failed: %v", err) } // TODO: what more info do we want to return on success? return &resp{ Type: ResponseTypeSync, Status: http.StatusOK, } }
func (s *assertMgrSuite) TestBatchConsiderPreexisting(c *C) { s.state.Lock() defer s.state.Unlock() // prereq store key err := assertstate.Add(s.state, s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) batch := assertstate.NewBatch() err = batch.Add(s.dev1Acct) c.Assert(err, IsNil) err = batch.Commit(s.state) c.Assert(err, IsNil) db := assertstate.DB(s.state) devAcct, err := db.Find(asserts.AccountType, map[string]string{ "account-id": s.dev1Acct.AccountID(), }) c.Assert(err, IsNil) c.Check(devAcct.(*asserts.Account).Username(), Equals, "developer1") }
func (s *assertMgrSuite) TestBatchAddUnsupported(c *C) { batch := assertstate.NewBatch() var a asserts.Assertion (func() { restore := asserts.MockMaxSupportedFormat(asserts.SnapDeclarationType, 999) defer restore() headers := map[string]interface{}{ "format": "999", "revision": "1", "series": "16", "snap-id": "snap-id-1", "snap-name": "foo", "publisher-id": s.dev1Acct.AccountID(), "timestamp": time.Now().Format(time.RFC3339), } var err error a, err = s.storeSigning.Sign(asserts.SnapDeclarationType, headers, nil, "") c.Assert(err, IsNil) })() err := batch.Add(a) c.Check(err, ErrorMatches, `proposed "snap-declaration" assertion has format 999 but 1 is latest supported`) }