Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ingest adds keyhash to files db table #1073

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/integration/tests/sda/10_upload_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ if [ -z "$STORAGETYPE" ]; then
exit 1
fi

if [ "$STORAGETYPE" = "posix" ]; then
for t in curl jq openssh-client postgresql-client; do
if [ ! "$(command -v $t)" ]; then
if [ "$(id -u)" != 0 ]; then
echo "$t is missing, unable to install it"
exit 1
fi

apt-get -o DPkg::Lock::Timeout=60 update >/dev/null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is inefficient and waste of time to (potentially) run apt-get update multiple times. It can be refactored to run apt-get update only once.

apt-get -o DPkg::Lock::Timeout=60 install -y "$t" >/dev/null
fi
done
fi

cd shared || true

## verify that messages exists in MQ
Expand Down
9 changes: 8 additions & 1 deletion .github/integration/tests/sda/20_ingest-verify_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,11 @@ until [ "$(curl -su guest:guest http://rabbitmq:15672/api/queues/sda/verified/ |
sleep 2
done

echo "ingestion and verification test completed successfully"
# check that the files have key hashes assigned
key_hashes="$(psql -U postgres -h postgres -d sda -At -c "select distinct key_hash from sda.files" | wc -l)"
if [ "$key_hashes" -lt 0 ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if [ "$key_hashes" -lt 0 ]; then
if [ "$key_hashes" -eq 0 ]; then

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result of wc -l can never be negative.

echo "::error::Ingested files did not have any key hashes."
exit 1
fi

echo "ingestion and verification test completed successfully"
16 changes: 16 additions & 0 deletions sda/cmd/ingest/ingest.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package main
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
Expand All @@ -14,6 +15,7 @@ import (
"strings"
"syscall"

"github.com/neicnordic/crypt4gh/keys"
"github.com/neicnordic/crypt4gh/model/headers"
"github.com/neicnordic/crypt4gh/streaming"
"github.com/neicnordic/sensitive-data-archive/internal/broker"
Expand Down Expand Up @@ -388,6 +390,20 @@ func main() {
continue mainWorkLoop
}

// Set the file's hex encoded public key
log.Debugln("Compute and set key hash")
publicKey := keys.DerivePublicKey(*key)
keyhash := hex.EncodeToString(publicKey[:])
err = db.SetKeyHash(keyhash, fileID)
if err != nil {
log.Errorf("Key hash %s could not be set for fileID %s: (%s)", keyhash, fileID, err.Error())
MalinAhlberg marked this conversation as resolved.
Show resolved Hide resolved
if err = delivered.Nack(false, true); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use a different variable name for the inner err to increase the clarity. However, maybe this not inline with the style of sda? What do others think?

log.Errorf("Failed to Nack message, reason: (%s)", err.Error())
}

continue mainWorkLoop
}

log.Debugln("store header")
if err := db.StoreHeader(header, fileID); err != nil {
log.Errorf("StoreHeader failed, reason: (%s)", err.Error())
Expand Down
18 changes: 18 additions & 0 deletions sda/internal/database/db_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,3 +782,21 @@ func (dbs *SDAdb) addKeyHash(keyHash, keyDescription string) error {

return nil
}

func (dbs *SDAdb) SetKeyHash(keyHash, fileID string) error {
dbs.checkAndReconnectIfNeeded()
db := dbs.DB

query := "UPDATE sda.files SET key_hash = $1 WHERE id = $2;"
result, err := db.Exec(query, keyHash, fileID)
if err != nil {

return err
}
if rowsAffected, _ := result.RowsAffected(); rowsAffected == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ignore the potentially returned error message?

return errors.New("something went wrong with the query, zero rows were changed")
}
log.Debugf("Successfully set key hash for file %v", fileID)

return nil
}
40 changes: 40 additions & 0 deletions sda/internal/database/db_functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -657,3 +657,43 @@ func (suite *DatabaseTests) TestAddKeyHash() {
assert.NoError(suite.T(), err, "failed to verify key hash existence")
assert.True(suite.T(), exists, "key hash was not added to the database")
}

func (suite *DatabaseTests) TestSetKeyHash() {
// Test that using an unknown key hash produces an error
db, err := NewSDAdb(suite.dbConf)
assert.NoError(suite.T(), err, "got (%v) when creating new connection", err)
// Register a new key and a new file
keyHex := `6af1407abc74656b8913a7d323c4bfd30bf7c8ca359f74ae35357acef29dc507`
keyDescription := "this is a test key"
err = db.addKeyHash(keyHex, keyDescription)
assert.NoError(suite.T(), err, "failed to register key in database")
fileID, err := db.RegisterFile("/testuser/file1.c4gh", "testuser")
assert.NoError(suite.T(), err, "failed to register file in database")

// Test that the key hash can be set in the files table
err = db.SetKeyHash(keyHex, fileID)
assert.NoError(suite.T(), err, "Could not set key hash")

// Verify that the key+file was added
var exists bool
err = db.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM sda.files WHERE key_hash=$1 AND id=$2)", keyHex, fileID).Scan(&exists)
assert.NoError(suite.T(), err, "failed to verify key hash set for file")
assert.True(suite.T(), exists, "key hash was not set for file in the database")
}
MalinAhlberg marked this conversation as resolved.
Show resolved Hide resolved

func (suite *DatabaseTests) TestSetKeyHash_wrongHash() {
// Add key hash and file
db, err := NewSDAdb(suite.dbConf)
assert.NoError(suite.T(), err, "got (%v) when creating new connection", err)
keyHex := "6af1407abc74656b8913a7d323c4bfd30bf7c8ca359f74ae35357acef29dc501"
keyDescription := "this is a test hash"
err = db.addKeyHash(keyHex, keyDescription)
assert.NoError(suite.T(), err, "failed to register key in database")
fileID, err := db.RegisterFile("/testuser/file2.c4gh", "testuser")
assert.NoError(suite.T(), err, "failed to register file in database")

// Ensure failure if a non existing hash is used
newKeyHex := "6af1407abc74656b8913a7d323c4bfd30bf7c8ca359f74ae35357acef29dc502"
err = db.SetKeyHash(newKeyHex, fileID)
assert.ErrorContains(suite.T(), err, "violates foreign key constraint")
}
Loading