gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/overlord/assertstate/helpers.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2017 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package assertstate 21 22 import ( 23 "github.com/snapcore/snapd/asserts" 24 "github.com/snapcore/snapd/logger" 25 "github.com/snapcore/snapd/overlord/auth" 26 "github.com/snapcore/snapd/overlord/snapstate" 27 "github.com/snapcore/snapd/overlord/state" 28 ) 29 30 // TODO: snapstate also has this, move to auth, or change a bit the approach now that we have DeviceAndAuthContext in the store? 31 func userFromUserID(st *state.State, userID int) (*auth.UserState, error) { 32 if userID == 0 { 33 return nil, nil 34 } 35 return auth.User(st, userID) 36 } 37 38 // handleUnsupported behaves as a fallback in case of bugs, we do ask 39 // the store to filter unsupported formats! 40 func handleUnsupported(db asserts.RODatabase) func(ref *asserts.Ref, unsupportedErr error) error { 41 return func(ref *asserts.Ref, unsupportedErr error) error { 42 if _, err := ref.Resolve(db.Find); err != nil { 43 // nothing there yet or any other error 44 return unsupportedErr 45 } 46 // we keep the old one, but log the issue 47 logger.Noticef("Cannot update assertion %v: %v", ref, unsupportedErr) 48 return nil 49 } 50 } 51 52 func doFetch(s *state.State, userID int, deviceCtx snapstate.DeviceContext, fetching func(asserts.Fetcher) error) error { 53 // TODO: once we have a bulk assertion retrieval endpoint this approach will change 54 55 db := cachedDB(s) 56 57 b := asserts.NewBatch(handleUnsupported(db)) 58 59 user, err := userFromUserID(s, userID) 60 if err != nil { 61 return err 62 } 63 64 sto := snapstate.Store(s, deviceCtx) 65 66 retrieve := func(ref *asserts.Ref) (asserts.Assertion, error) { 67 // TODO: ignore errors if already in db? 68 return sto.Assertion(ref.Type, ref.PrimaryKey, user) 69 } 70 71 s.Unlock() 72 err = b.Fetch(db, retrieve, fetching) 73 s.Lock() 74 if err != nil { 75 return err 76 } 77 78 // TODO: trigger w. caller a global sanity check if a is revoked 79 // (but try to save as much possible still), 80 // or err is a check error 81 return b.CommitTo(db, nil) 82 }