Esempio n. 1
0
func (self *Store) Op_hash(operation *operations.Hash) (ret bucket.BucketReturn) {

	opGet := operations.Get{
		BucketId: operation.BucketId,
		Key:      operation.Key,
	}
	ret = self.Op_get(&opGet)
	if !ret.GetCode().IsOk() {
		// Error
		return
	}
	if ret.GetCode() == retcode.OkNotFound {
		// Not found, so we cannot hash it
		return
	}

	// Ok, something we can hash
	returnGet := ret.(*operations.GetReturn)
	value := returnGet.Value

	hasher := hasher.NewHasher(value)

	hashreturn := new(operations.HashReturn)
	hashreturn.FirstElementSha256Hash = hasher.FirstElement()
	hashreturn.AllElementsSha256Hash = hasher.AllElements()
	hashreturn.Status = retcode.NewStatusOk()

	return hashreturn
}
Esempio n. 2
0
func fillMissingHashesAccordingToConfig(returnConfig *operations.ReturnConfig,
	value types.Array,
	hashes *hashes.Hashes) {
	// Can only return hashes if value is available
	if returnConfig.HashReturn && value != nil {
		// Ok, need hashes
		if hashes.AllElementsSha256Hash == nil ||
			hashes.FirstElementSha256Hash == nil {
			// Ok, hash is missing
			hasher := hasher.NewHasher(value)
			hashes.FirstElementSha256Hash = hasher.FirstElement()
			hashes.AllElementsSha256Hash = hasher.AllElements()
		}
	}
}
Esempio n. 3
0
func (self *hasherInstance) op_put(operation *operations.Put,
	state *minos.OperationState) (ret bucket.BucketReturn) {

	if operation.Value == nil {
		// Removes are ignored
		return &bucket.ReturnGeneric{retcode.NewStatus(retcode.ErrorOperationNotSupported)}
	}

	var firstElementHashBytes []byte
	if operation.Hashes.FirstElementSha256Hash == nil {
		theHasher := syshasher.NewHasher(operation.Value)
		firstElementHashBytes = theHasher.FirstElement()
		//TODO: Also forward alle elements hash
	}
	firstElementHash := hashes.FirstElementSha256Hash(firstElementHashBytes)

	// Always forward a put with the generated hash as value, even if already exists
	//TODO: Security problem if someone listens for such things?
	putForward := operations.Put{
		Key:   operation.Key,
		Value: types.Array{firstElementHashBytes},
		Hashes: hashes.Hashes{
			FirstElementSha256Hash: firstElementHash,
		},
	}
	state.PutForwarder.ForwardIfOk(&putForward)

	// Check if already exists
	existsOperation := operations.Exists{
		BucketId: self.backendId,
		Key:      types.Key{firstElementHashBytes},
	}
	apiExists := state.Dispatcher.Perform(state.Context, &existsOperation)
	if apiExists.GetCode() == retcode.Ok {
		// Already exists, end here
		return &operations.PutReturn{retcode.NewStatus(retcode.OkAlreadyExists)}
	}

	if !apiExists.GetCode().IsOk() {
		return &bucket.ReturnGeneric{retcode.NewStatusError(
			apiExists.GetCode(),
			errors.New("Unable to check if the entry already exists"))}
	}

	originalValue := operation.Value
	var valueToSupply []byte
	if len(originalValue) > 0 {
		valueToSupply = originalValue[0]
	} else {
		// If there's no value, take empty bytes
		valueToSupply = []byte{}
	}

	newPutOperation := operations.Put{
		BucketId: self.backendId,
		Key:      types.Key{firstElementHashBytes},
		// Only the first element survives
		Value: types.Array{valueToSupply},
	}

	apiPerformRet := state.Dispatcher.Perform(state.Context, &newPutOperation)
	if !apiPerformRet.GetCode().IsOk() {
		return &bucket.ReturnGeneric{retcode.NewStatusError(
			apiPerformRet.GetCode(),
			errors.New("Unable to transfer the data to the backend bucket"))}
	}

	return &bucket.ReturnGeneric{retcode.NewStatusOk()}
}