Implemented blocking on the server-side

This commit is contained in:
2025-02-10 19:27:24 +02:00
parent c0e615133c
commit a496d59fd6
6 changed files with 225 additions and 35 deletions

View File

@@ -327,7 +327,7 @@ func (m *Model) updateConnected(message tea.Msg) tea.Cmd {
state.UpdateMessages(msg)
case *packet.TrustInfo:
state.UpdateTrusteds(msg)
state.UpdateTrustedUsers(msg)
case *packet.NotificationsInfo:
signals := state.UpdateNotifications(msg)

View File

@@ -231,7 +231,7 @@ func FromJsonUserData(s string) {
log.Println("Updated user data:", Data)
}
func UpdateTrusteds(info *packet.TrustInfo) {
func UpdateTrustedUsers(info *packet.TrustInfo) {
for _, removed := range info.RemovedTrustedUsers {
delete(State.TrustedUsers, removed)
}

View File

@@ -12,6 +12,50 @@ import (
"github.com/kyren223/eko/pkg/snowflake"
)
const blockUser = `-- name: BlockUser :exec
INSERT OR IGNORE INTO blocked_users (
blocking_user_id, blocked_user_id
) VALUES (?, ?)
`
type BlockUserParams struct {
BlockingUserID snowflake.ID
BlockedUserID snowflake.ID
}
func (q *Queries) BlockUser(ctx context.Context, arg BlockUserParams) error {
_, err := q.db.ExecContext(ctx, blockUser, arg.BlockingUserID, arg.BlockedUserID)
return err
}
const getBlockedUsers = `-- name: GetBlockedUsers :many
SELECT blocked_user_id FROM blocked_users
WHERE blocking_user_id = ?
`
func (q *Queries) GetBlockedUsers(ctx context.Context, blockingUserID snowflake.ID) ([]snowflake.ID, error) {
rows, err := q.db.QueryContext(ctx, getBlockedUsers, blockingUserID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []snowflake.ID
for rows.Next() {
var blocked_user_id snowflake.ID
if err := rows.Scan(&blocked_user_id); err != nil {
return nil, err
}
items = append(items, blocked_user_id)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getTrustedPublicKey = `-- name: GetTrustedPublicKey :one
SELECT trusted_public_key FROM trusted_users
WHERE trusting_user_id = ? AND trusted_user_id = ?
@@ -29,25 +73,25 @@ func (q *Queries) GetTrustedPublicKey(ctx context.Context, arg GetTrustedPublicK
return trusted_public_key, err
}
const getUserTrusteds = `-- name: GetUserTrusteds :many
const getTrustedUsers = `-- name: GetTrustedUsers :many
SELECT trusted_user_id, trusted_public_key FROM trusted_users
WHERE trusting_user_id = ?
`
type GetUserTrustedsRow struct {
type GetTrustedUsersRow struct {
TrustedUserID snowflake.ID
TrustedPublicKey ed25519.PublicKey
}
func (q *Queries) GetUserTrusteds(ctx context.Context, trustingUserID snowflake.ID) ([]GetUserTrustedsRow, error) {
rows, err := q.db.QueryContext(ctx, getUserTrusteds, trustingUserID)
func (q *Queries) GetTrustedUsers(ctx context.Context, trustingUserID snowflake.ID) ([]GetTrustedUsersRow, error) {
rows, err := q.db.QueryContext(ctx, getTrustedUsers, trustingUserID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetUserTrustedsRow
var items []GetTrustedUsersRow
for rows.Next() {
var i GetUserTrustedsRow
var i GetTrustedUsersRow
if err := rows.Scan(&i.TrustedUserID, &i.TrustedPublicKey); err != nil {
return nil, err
}
@@ -62,6 +106,23 @@ func (q *Queries) GetUserTrusteds(ctx context.Context, trustingUserID snowflake.
return items, nil
}
const isUserBlocked = `-- name: IsUserBlocked :one
SELECT blocked_user_id FROM blocked_users
WHERE blocking_user_id = ? AND blocked_user_id = ?
`
type IsUserBlockedParams struct {
BlockingUserID snowflake.ID
BlockedUserID snowflake.ID
}
func (q *Queries) IsUserBlocked(ctx context.Context, arg IsUserBlockedParams) (snowflake.ID, error) {
row := q.db.QueryRowContext(ctx, isUserBlocked, arg.BlockingUserID, arg.BlockedUserID)
var blocked_user_id snowflake.ID
err := row.Scan(&blocked_user_id)
return blocked_user_id, err
}
const trustUser = `-- name: TrustUser :exec
INSERT OR IGNORE INTO trusted_users (
trusting_user_id, trusted_user_id, trusted_public_key
@@ -79,6 +140,21 @@ func (q *Queries) TrustUser(ctx context.Context, arg TrustUserParams) error {
return err
}
const unblockUser = `-- name: UnblockUser :exec
DELETE FROM blocked_users
WHERE blocking_user_id = ? AND blocked_user_id = ?
`
type UnblockUserParams struct {
BlockingUserID snowflake.ID
BlockedUserID snowflake.ID
}
func (q *Queries) UnblockUser(ctx context.Context, arg UnblockUserParams) error {
_, err := q.db.ExecContext(ctx, unblockUser, arg.BlockingUserID, arg.BlockedUserID)
return err
}
const untrustUser = `-- name: UntrustUser :exec
DELETE FROM trusted_users
WHERE trusting_user_id = ? AND trusted_user_id = ?

View File

@@ -126,6 +126,35 @@ func SendMessage(ctx context.Context, sess *session.Session, request *packet.Sen
log.Println("database error 4:", err)
return &ErrInternalError
}
// Session user blocked the user he tried to message
_, err = queries.IsUserBlocked(ctx, data.IsUserBlockedParams{
BlockingUserID: sess.ID(),
BlockedUserID: user.ID,
})
if err != nil && err != sql.ErrNoRows {
log.Println("database error 5:", err)
return &ErrInternalError
}
if err != sql.ErrNoRows {
// Can't message a user if you blocked them
return &ErrPermissionDenied
}
// Session user was blocked by the user they tried to message
_, err = queries.IsUserBlocked(ctx, data.IsUserBlockedParams{
BlockingUserID: user.ID,
BlockedUserID: sess.ID(),
})
if err != nil && err != sql.ErrNoRows {
log.Println("database error 6:", err)
return &ErrInternalError
}
if err != sql.ErrNoRows {
// Can't message a user if they blocked you
return &ErrPermissionDenied
}
if !user.IsPublicDM {
pubKey, err := queries.GetTrustedPublicKey(ctx, data.GetTrustedPublicKeyParams{
TrustingUserID: user.ID,
@@ -135,7 +164,7 @@ func SendMessage(ctx context.Context, sess *session.Session, request *packet.Sen
return &ErrPermissionDenied
}
if err != nil {
log.Println("database error 5:", err)
log.Println("database error 7:", err)
return &ErrInternalError
}
if !bytes.Equal(sess.PubKey, pubKey) {
@@ -152,7 +181,7 @@ func SendMessage(ctx context.Context, sess *session.Session, request *packet.Sen
Ping: nil,
})
if err != nil {
log.Println("database error 6:", err)
log.Println("database error 8:", err)
return &ErrInternalError
}
@@ -162,7 +191,7 @@ func SendMessage(ctx context.Context, sess *session.Session, request *packet.Sen
LastRead: 0,
})
if err != nil {
log.Println("database error 7:", err)
log.Println("database error 9:", err)
return &ErrInternalError
}
@@ -1170,9 +1199,9 @@ func TrustUser(ctx context.Context, sess *session.Session, request *packet.Trust
})
if err == nil {
return &packet.TrustInfo{
TrustedUsers: []snowflake.ID{user.ID},
TrustedPublicKeys: []ed25519.PublicKey{publicKey},
RemovedTrustedUsers: nil,
TrustedUsers: []snowflake.ID{user.ID},
TrustedPublicKeys: []ed25519.PublicKey{publicKey},
RemovedTrustedUsers: nil,
}
}
if err != nil && err != sql.ErrNoRows {
@@ -1185,45 +1214,38 @@ func TrustUser(ctx context.Context, sess *session.Session, request *packet.Trust
TrustedUserID: user.ID,
TrustedPublicKey: user.PublicKey,
})
if err != nil && err != sql.ErrNoRows {
if err != nil {
log.Println("database error 2:", err)
return &ErrInternalError
}
return &packet.TrustInfo{
TrustedUsers: []snowflake.ID{user.ID},
TrustedPublicKeys: []ed25519.PublicKey{user.PublicKey},
RemovedTrustedUsers: nil,
TrustedUsers: []snowflake.ID{user.ID},
TrustedPublicKeys: []ed25519.PublicKey{user.PublicKey},
RemovedTrustedUsers: nil,
}
} else {
err = queries.UntrustUser(ctx, data.UntrustUserParams{
TrustingUserID: sess.ID(),
TrustedUserID: user.ID,
})
if err == sql.ErrNoRows {
return &packet.TrustInfo{
TrustedUsers: nil,
TrustedPublicKeys: nil,
RemovedTrustedUsers: []snowflake.ID{user.ID},
}
}
if err != nil {
log.Println("database error 3:", err)
return &ErrInternalError
}
return &packet.TrustInfo{
TrustedUsers: nil,
TrustedPublicKeys: nil,
RemovedTrustedUsers: []snowflake.ID{user.ID},
TrustedUsers: nil,
TrustedPublicKeys: nil,
RemovedTrustedUsers: []snowflake.ID{user.ID},
}
}
}
func GetUserTrusteds(ctx context.Context, sess *session.Session) packet.Payload {
func GetTrustedUsers(ctx context.Context, sess *session.Session) packet.Payload {
queries := data.New(db)
trustedRows, err := queries.GetUserTrusteds(ctx, sess.ID())
trustedRows, err := queries.GetTrustedUsers(ctx, sess.ID())
if err != nil && err != sql.ErrNoRows {
log.Println("database error 0:", err)
return &ErrInternalError
@@ -1238,9 +1260,9 @@ func GetUserTrusteds(ctx context.Context, sess *session.Session) packet.Payload
}
return &packet.TrustInfo{
TrustedUsers: trusteds,
TrustedPublicKeys: trustedPublicKeys,
RemovedTrustedUsers: nil,
TrustedUsers: trusteds,
TrustedPublicKeys: trustedPublicKeys,
RemovedTrustedUsers: nil,
}
}
@@ -1371,3 +1393,80 @@ func SetLastReadMessages(ctx context.Context, sess *session.Session, request *pa
return &ErrSuccess
}
func BlockUser(ctx context.Context, sess *session.Session, request *packet.BlockUser) packet.Payload {
if sess.ID() == request.User {
return &packet.Error{Error: "you cannot block yourself"}
}
queries := data.New(db)
user, err := queries.GetUserById(ctx, request.User)
if err == sql.ErrNoRows {
return &packet.Error{Error: "requested user doesn't exist"}
}
if err != nil {
log.Println("database error 0:", err)
return &ErrInternalError
}
if request.Block {
_, err := queries.IsUserBlocked(ctx, data.IsUserBlockedParams{
BlockingUserID: sess.ID(),
BlockedUserID: user.ID,
})
if err == nil {
return &packet.BlockInfo{
BlockedUsers: []snowflake.ID{user.ID},
RemovedBlockedUsers: nil,
}
}
if err != nil && err != sql.ErrNoRows {
log.Println("database error 1:", err)
return &ErrInternalError
}
err = queries.BlockUser(ctx, data.BlockUserParams{
BlockingUserID: sess.ID(),
BlockedUserID: user.ID,
})
if err != nil {
log.Println("database error 2:", err)
return &ErrInternalError
}
return &packet.BlockInfo{
BlockedUsers: []snowflake.ID{user.ID},
RemovedBlockedUsers: nil,
}
} else {
err = queries.UntrustUser(ctx, data.UntrustUserParams{
TrustingUserID: sess.ID(),
TrustedUserID: user.ID,
})
if err != nil {
log.Println("database error 3:", err)
return &ErrInternalError
}
return &packet.BlockInfo{
BlockedUsers: nil,
RemovedBlockedUsers: []snowflake.ID{user.ID},
}
}
}
func GetBlockedUsers(ctx context.Context, sess *session.Session) packet.Payload {
queries := data.New(db)
blockedUsers, err := queries.GetBlockedUsers(ctx, sess.ID())
if err != nil && err != sql.ErrNoRows {
log.Println("database error 0:", err)
return &ErrInternalError
}
return &packet.BlockInfo{
BlockedUsers: blockedUsers,
RemovedBlockedUsers: nil,
}
}

View File

@@ -371,6 +371,9 @@ func processRequest(ctx context.Context, sess *session.Session, request packet.P
case *packet.SetLastReadMessages:
response = timeout(50*time.Millisecond, api.SetLastReadMessages, ctx, sess, request)
case *packet.BlockUser:
response = timeout(10*time.Millisecond, api.BlockUser, ctx, sess, request)
default:
response = &packet.Error{Error: "use of disallowed packet type for request"}
}
@@ -418,7 +421,15 @@ func (server *server) sendInitialPackets(ctx context.Context, sess *session.Sess
pkt := packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.Write(ctx, pkt)
payload = api.GetUserTrusteds(ctx, sess)
payload = api.GetTrustedUsers(ctx, sess)
if payload == &api.ErrInternalError {
return false
}
log.Println(sess.Addr(), "sending", payload.Type(), "payload:", payload)
pkt = packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.Write(ctx, pkt)
payload = api.GetBlockedUsers(ctx, sess)
if payload == &api.ErrInternalError {
return false
}

View File

@@ -19,9 +19,13 @@ WHERE trusting_user_id = ? AND trusted_user_id = ?;
SELECT blocked_user_id FROM blocked_users
WHERE blocking_user_id = ?;
-- name: IsUserBlocked :one
SELECT blocked_user_id FROM blocked_users
WHERE blocking_user_id = ? AND blocked_user_id = ?;
-- name: BlockUser :exec
INSERT OR IGNORE INTO blocked_users (
blocking_user_id, blocking_user_id
blocking_user_id, blocked_user_id
) VALUES (?, ?);
-- name: UnblockUser :exec