diff --git a/server/db/db.go b/server/db/db.go index 9f64fc4e3e1bc3f8cd102a1e286ba5dfc1de9edf..100b1c4a515e1139221645add3f666a329a338eb 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -47,6 +47,7 @@ type CollabStore interface { DeleteRepoCollab(int, int) error ListRepoCollabs(string) ([]*types.User, error) ListRepoPublicKeys(string) ([]*types.PublicKey, error) + IsRepoPublicKeyCollab(string, string) (bool, error) } // Store is a database. diff --git a/server/db/fakedb/db.go b/server/db/fakedb/db.go index 8c9c9f680154da21f6096ba9aa2199bbeda44d19..d4913b3a93b2d04500df142c63a17900f826e8e7 100644 --- a/server/db/fakedb/db.go +++ b/server/db/fakedb/db.go @@ -165,6 +165,11 @@ func (*FakeDB) ListRepoPublicKeys(string) ([]*types.PublicKey, error) { return nil, nil } +// IsRepoPublicKeyCollab implements db.Store. +func (*FakeDB) IsRepoPublicKeyCollab(string, string) (bool, error) { + return false, nil +} + // Close implements db.Store. func (*FakeDB) Close() error { return nil diff --git a/server/db/sqlite/sql.go b/server/db/sqlite/sql.go index 7a1c91700de8010f780ce31878751c20a6ce79b4..8ab1a885a8cb3d9540f31c92a7126079521dc95c 100644 --- a/server/db/sqlite/sql.go +++ b/server/db/sqlite/sql.go @@ -81,12 +81,13 @@ var ( sqlUpdateRepoPrivateByName = `UPDATE repo SET private = ?, updated_at = CURRENT_TIMESTAMP WHERE name = ?;` // Collab. - sqlInsertCollab = `INSERT INTO collab (user_id, repo_id, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP);` - sqlInsertCollabByName = `INSERT INTO collab (user_id, repo_id, updated_at) VALUES (?, (SELECT id FROM repo WHERE name = ?), CURRENT_TIMESTAMP);` - sqlDeleteCollab = `DELETE FROM collab WHERE user_id = ? AND repo_id = ?;` - sqlDeleteCollabByName = `DELETE FROM collab WHERE user_id = ? AND repo_id = (SELECT id FROM repo WHERE name = ?);` - sqlSelectRepoCollabs = `SELECT user.id, user.name, user.login, user.email, user.admin, user.created_at, user.updated_at FROM user INNER JOIN collab ON user.id = collab.user_id WHERE collab.repo_id = ?;` - sqlSelectRepoCollabsByName = `SELECT user.id, user.name, user.login, user.email, user.admin, user.created_at, user.updated_at FROM user INNER JOIN collab ON user.id = collab.user_id WHERE collab.repo_id = (SELECT id FROM repo WHERE name = ?);` - sqlSelectRepoPublicKeys = `SELECT public_key.id, public_key.user_id, public_key.public_key, public_key.created_at, public_key.updated_at FROM public_key INNER JOIN collab ON public_key.user_id = collab.user_id WHERE collab.repo_id = ?;` - sqlSelectRepoPublicKeysByName = `SELECT public_key.id, public_key.user_id, public_key.public_key, public_key.created_at, public_key.updated_at FROM public_key INNER JOIN collab ON public_key.user_id = collab.user_id WHERE collab.repo_id = (SELECT id FROM repo WHERE name = ?);` + sqlInsertCollab = `INSERT INTO collab (user_id, repo_id, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP);` + sqlInsertCollabByName = `INSERT INTO collab (user_id, repo_id, updated_at) VALUES (?, (SELECT id FROM repo WHERE name = ?), CURRENT_TIMESTAMP);` + sqlDeleteCollab = `DELETE FROM collab WHERE user_id = ? AND repo_id = ?;` + sqlDeleteCollabByName = `DELETE FROM collab WHERE user_id = ? AND repo_id = (SELECT id FROM repo WHERE name = ?);` + sqlSelectRepoCollabs = `SELECT user.id, user.name, user.login, user.email, user.admin, user.created_at, user.updated_at FROM user INNER JOIN collab ON user.id = collab.user_id WHERE collab.repo_id = ?;` + sqlSelectRepoCollabsByName = `SELECT user.id, user.name, user.login, user.email, user.admin, user.created_at, user.updated_at FROM user INNER JOIN collab ON user.id = collab.user_id WHERE collab.repo_id = (SELECT id FROM repo WHERE name = ?);` + sqlSelectRepoPublicKeys = `SELECT public_key.id, public_key.user_id, public_key.public_key, public_key.created_at, public_key.updated_at FROM public_key INNER JOIN collab ON public_key.user_id = collab.user_id WHERE collab.repo_id = ?;` + sqlSelectRepoPublicKeysByName = `SELECT public_key.id, public_key.user_id, public_key.public_key, public_key.created_at, public_key.updated_at FROM public_key INNER JOIN collab ON public_key.user_id = collab.user_id WHERE collab.repo_id = (SELECT id FROM repo WHERE name = ?);` + sqlSelectRepoPublicKeyCollabByName = `SELECT COUNT(*) FROM public_key INNER JOIN collab ON public_key.user_id = collab.user_id WHERE collab.repo_id = (SELECT id FROM repo WHERE name = ?) AND public_key.public_key = ?;` ) diff --git a/server/db/sqlite/sqlite.go b/server/db/sqlite/sqlite.go index c92481f7c8c9ae255982dc4c06bbcfa41625b94b..055b2512f79ea934e7a681663545f242f3c73c86 100644 --- a/server/db/sqlite/sqlite.go +++ b/server/db/sqlite/sqlite.go @@ -404,6 +404,24 @@ func (d *Sqlite) ListRepoPublicKeys(repo string) ([]*types.PublicKey, error) { return keys, nil } +// IsRepoPublicKeyCollab returns true if the public key is a collaborator for the repository. +func (d *Sqlite) IsRepoPublicKeyCollab(repo string, key string) (bool, error) { + var count int + if err := d.wrapTransaction(func(tx *sql.Tx) error { + rows := tx.QueryRow(sqlSelectRepoPublicKeyCollabByName, repo, key) + if err := rows.Scan(&count); err != nil { + return err + } + if err := rows.Err(); err != nil { + return err + } + return nil + }); err != nil { + return false, err + } + return count > 0, nil +} + // WrapTransaction runs the given function within a transaction. func (d *Sqlite) wrapTransaction(f func(tx *sql.Tx) error) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)