Example #1
0
// AtomicUpdateHandler will accept multiple TUF files and ensure that the storage
// backend is atomically updated with all the new records.
func AtomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
	defer r.Body.Close()
	s := ctx.Value("metaStore")
	store, ok := s.(storage.MetaStore)
	if !ok {
		return errors.ErrNoStorage.WithDetail(nil)
	}
	vars := mux.Vars(r)
	gun := vars["imageName"]
	reader, err := r.MultipartReader()
	if err != nil {
		return errors.ErrMalformedUpload.WithDetail(nil)
	}
	var updates []storage.MetaUpdate
	for {
		part, err := reader.NextPart()
		if err == io.EOF {
			break
		}
		role := strings.TrimSuffix(part.FileName(), ".json")
		if role == "" {
			return errors.ErrNoFilename.WithDetail(nil)
		} else if !data.ValidRole(role) {
			return errors.ErrInvalidRole.WithDetail(role)
		}
		meta := &data.SignedMeta{}
		var input []byte
		inBuf := bytes.NewBuffer(input)
		dec := json.NewDecoder(io.TeeReader(part, inBuf))
		err = dec.Decode(meta)
		if err != nil {
			return errors.ErrMalformedJSON.WithDetail(nil)
		}
		version := meta.Signed.Version
		updates = append(updates, storage.MetaUpdate{
			Role:    role,
			Version: version,
			Data:    inBuf.Bytes(),
		})
	}
	if err = validateUpdate(gun, updates, store); err != nil {
		return errors.ErrMalformedUpload.WithDetail(err)
	}
	err = store.UpdateMany(gun, updates)
	if err != nil {
		return errors.ErrUpdating.WithDetail(err)
	}
	return nil
}
Example #2
0
func (db *KeyDB) AddRole(r *data.Role) error {
	if !data.ValidRole(r.Name) {
		return ErrInvalidRole
	}
	if r.Threshold < 1 {
		return ErrInvalidThreshold
	}

	// validate all key ids are in the keys maps
	for _, id := range r.KeyIDs {
		if _, ok := db.keys[id]; !ok {
			return ErrInvalidKeyID
		}
	}

	db.roles[r.Name] = r
	return nil
}
Example #3
0
// AtomicUpdateHandler will accept multiple TUF files and ensure that the storage
// backend is atomically updated with all the new records.
func AtomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) *errors.HTTPError {
	defer r.Body.Close()
	s := ctx.Value("metaStore")
	if s == nil {
		return &errors.HTTPError{
			HTTPStatus: http.StatusInternalServerError,
			Code:       9999,
			Err:        fmt.Errorf("Version store is nil"),
		}
	}
	store, ok := s.(storage.MetaStore)
	if !ok {
		return &errors.HTTPError{
			HTTPStatus: http.StatusInternalServerError,
			Code:       9999,
			Err:        fmt.Errorf("Version store not configured"),
		}
	}
	vars := mux.Vars(r)
	gun := vars["imageName"]
	reader, err := r.MultipartReader()
	if err != nil {
		return &errors.HTTPError{
			HTTPStatus: http.StatusBadRequest,
			Code:       9999,
			Err:        err,
		}
	}
	var updates []storage.MetaUpdate
	for {
		part, err := reader.NextPart()
		if err == io.EOF {
			break
		}
		role := strings.TrimSuffix(part.FileName(), ".json")
		if role == "" {
			return &errors.HTTPError{
				HTTPStatus: http.StatusBadRequest,
				Code:       9999,
				Err:        fmt.Errorf("Empty filename provided. No updates performed"),
			}
		} else if !data.ValidRole(role) {
			return &errors.HTTPError{
				HTTPStatus: http.StatusBadRequest,
				Code:       9999,
				Err:        fmt.Errorf("Invalid role: %s. No updates performed", role),
			}
		}
		meta := &data.SignedTargets{}
		var input []byte
		inBuf := bytes.NewBuffer(input)
		dec := json.NewDecoder(io.TeeReader(part, inBuf))
		err = dec.Decode(meta)
		if err != nil {
			return &errors.HTTPError{
				HTTPStatus: http.StatusBadRequest,
				Code:       9999,
				Err:        err,
			}
		}
		version := meta.Signed.Version
		updates = append(updates, storage.MetaUpdate{
			Role:    role,
			Version: version,
			Data:    inBuf.Bytes(),
		})
	}
	err = store.UpdateMany(gun, updates)
	if err != nil {
		return &errors.HTTPError{
			HTTPStatus: http.StatusInternalServerError,
			Code:       9999,
			Err:        err,
		}
	}
	return nil
}