2018-08-13 20:24:44 +00:00
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
2020-05-08 19:32:22 +00:00
// Copyright (C) 2020 Tulir Asokan
2018-08-13 20:24:44 +00:00
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package database
import (
2018-08-26 19:53:13 +00:00
"database/sql"
2018-08-29 22:10:26 +00:00
"strings"
2018-08-26 19:53:13 +00:00
2018-08-13 20:24:44 +00:00
"github.com/Rhymen/go-whatsapp"
2019-01-11 19:17:31 +00:00
log "maunium.net/go/maulogger/v2"
2018-08-16 21:11:28 +00:00
"maunium.net/go/mautrix-whatsapp/types"
2021-02-13 05:53:35 +00:00
whatsappExt "maunium.net/go/mautrix-whatsapp/whatsapp-ext"
2020-05-08 19:32:22 +00:00
"maunium.net/go/mautrix/id"
2018-08-13 20:24:44 +00:00
)
type UserQuery struct {
db * Database
2018-08-16 16:20:07 +00:00
log log . Logger
2018-08-13 20:24:44 +00:00
}
func ( uq * UserQuery ) New ( ) * User {
return & User {
2018-08-26 19:53:13 +00:00
db : uq . db ,
log : uq . log ,
2018-08-13 20:24:44 +00:00
}
}
func ( uq * UserQuery ) GetAll ( ) ( users [ ] * User ) {
2021-02-13 05:53:35 +00:00
// rows, err := uq.db.Query(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user"`)
// if err != nil || rows == nil {
// return nil
// }
// defer rows.Close()
// for rows.Next() {
// users = append(users, uq.New().Scan(rows))
// }
2018-08-13 20:24:44 +00:00
return
}
2020-05-08 19:32:22 +00:00
func ( uq * UserQuery ) GetByMXID ( userID id . UserID ) * User {
2021-02-13 05:53:35 +00:00
// row := uq.db.QueryRow(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user" WHERE mxid=$1`, userID)
// if row == nil {
// return nil
// }
// return uq.New().Scan(row)
return nil
2018-08-13 20:24:44 +00:00
}
2021-02-13 05:53:35 +00:00
func ( uq * UserQuery ) GetByJID ( userID types . GroupMeID ) * User {
// row := uq.db.QueryRow(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user" WHERE jid=$1`, stripSuffix(userID))
// if row == nil {
// return nil
// }
// return uq.New().Scan(row)
return nil
2018-08-28 21:40:54 +00:00
}
2018-08-13 20:24:44 +00:00
type User struct {
db * Database
2018-08-16 16:20:07 +00:00
log log . Logger
2018-08-13 20:24:44 +00:00
2020-05-08 19:32:22 +00:00
MXID id . UserID
2021-02-13 05:53:35 +00:00
JID types . GroupMeID
Token types . AuthToken
2020-05-08 19:32:22 +00:00
ManagementRoom id . RoomID
2019-05-22 13:46:18 +00:00
LastConnection uint64
2018-08-13 20:24:44 +00:00
}
func ( user * User ) Scan ( row Scannable ) * User {
2018-10-16 19:36:16 +00:00
var jid , clientID , clientToken , serverToken sql . NullString
2018-08-29 22:10:26 +00:00
var encKey , macKey [ ] byte
2019-06-13 18:28:14 +00:00
err := row . Scan ( & user . MXID , & jid , & user . ManagementRoom , & user . LastConnection , & clientID , & clientToken , & serverToken , & encKey , & macKey )
2018-08-13 20:24:44 +00:00
if err != nil {
2018-08-18 19:57:08 +00:00
if err != sql . ErrNoRows {
2018-08-25 22:55:21 +00:00
user . log . Errorln ( "Database scan failed:" , err )
2018-08-18 19:57:08 +00:00
}
return nil
2018-08-13 20:24:44 +00:00
}
2018-08-29 22:10:26 +00:00
if len ( jid . String ) > 0 && len ( clientID . String ) > 0 {
user . JID = jid . String + whatsappExt . NewUserSuffix
2021-02-13 05:53:35 +00:00
// user.Session = &whatsapp.Session{
// ClientId: clientID.String,
// ClientToken: clientToken.String,
// ServerToken: serverToken.String,
// EncKey: encKey,
// MacKey: macKey,
// Wid: jid.String + whatsappExt.OldUserSuffix,
// }
} // else {
// user.Session = nil
// }
2018-08-13 20:24:44 +00:00
return user
}
2021-02-13 05:53:35 +00:00
func stripSuffix ( jid types . GroupMeID ) string {
2018-08-29 22:10:26 +00:00
if len ( jid ) == 0 {
return jid
}
index := strings . IndexRune ( jid , '@' )
if index < 0 {
return jid
2018-08-28 21:40:54 +00:00
}
2018-08-29 22:10:26 +00:00
return jid [ : index ]
2018-08-28 21:40:54 +00:00
}
2018-09-01 20:38:03 +00:00
func ( user * User ) jidPtr ( ) * string {
if len ( user . JID ) > 0 {
str := stripSuffix ( user . JID )
return & str
}
return nil
}
2018-08-28 21:40:54 +00:00
func ( user * User ) sessionUnptr ( ) ( sess whatsapp . Session ) {
2021-02-13 05:53:35 +00:00
// if user.Session != nil {
// sess = *user.Session
// }
return
2018-08-28 21:40:54 +00:00
}
2019-01-21 21:55:16 +00:00
func ( user * User ) Insert ( ) {
2021-02-13 05:53:35 +00:00
// sess := user.sessionUnptr()
// _, err := user.db.Exec(`INSERT INTO "user" (mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
// user.MXID, user.jidPtr(),
// user.ManagementRoom, user.LastConnection,
// sess.ClientId, sess.ClientToken, sess.ServerToken, sess.EncKey, sess.MacKey)
// if err != nil {
// user.log.Warnfln("Failed to insert %s: %v", user.MXID, err)
// }
2018-08-13 20:24:44 +00:00
}
2019-05-22 13:46:18 +00:00
func ( user * User ) UpdateLastConnection ( ) {
2021-02-13 05:53:35 +00:00
// user.LastConnection = uint64(time.Now().Unix())
// _, err := user.db.Exec(`UPDATE "user" SET last_connection=$1 WHERE mxid=$2`,
// user.LastConnection, user.MXID)
// if err != nil {
// user.log.Warnfln("Failed to update last connection ts: %v", err)
// }
2019-05-22 13:46:18 +00:00
}
2019-01-21 21:55:16 +00:00
func ( user * User ) Update ( ) {
2021-02-13 05:53:35 +00:00
// sess := user.sessionUnptr()
// _, err := user.db.Exec(`UPDATE "user" SET jid=$1, management_room=$2, last_connection=$3, client_id=$4, client_token=$5, server_token=$6, enc_key=$7, mac_key=$8 WHERE mxid=$9`,
// user.jidPtr(), user.ManagementRoom, user.LastConnection,
// sess.ClientId, sess.ClientToken, sess.ServerToken, sess.EncKey, sess.MacKey,
// user.MXID)
// if err != nil {
// user.log.Warnfln("Failed to update %s: %v", user.MXID, err)
// }
2018-08-13 20:24:44 +00:00
}
2019-05-28 18:31:25 +00:00
2019-08-10 12:24:53 +00:00
type PortalKeyWithMeta struct {
PortalKey
InCommunity bool
}
func ( user * User ) SetPortalKeys ( newKeys [ ] PortalKeyWithMeta ) error {
2021-02-13 05:53:35 +00:00
// tx, err := user.db.Begin()
// if err != nil {
// return err
// }
// _, err = tx.Exec("DELETE FROM user_portal WHERE user_jid=$1", user.jidPtr())
// if err != nil {
// _ = tx.Rollback()
// return err
// }
// valueStrings := make([]string, len(newKeys))
// values := make([]interface{}, len(newKeys)*4)
// for i, key := range newKeys {
// pos := i * 4
// valueStrings[i] = fmt.Sprintf("($%d, $%d, $%d, $%d)", pos+1, pos+2, pos+3, pos+4)
// values[pos] = user.jidPtr()
// values[pos+1] = key.JID
// values[pos+2] = key.Receiver
// values[pos+3] = key.InCommunity
// }
// query := fmt.Sprintf("INSERT INTO user_portal (user_jid, portal_jid, portal_receiver, in_community) VALUES %s",
// strings.Join(valueStrings, ", "))
// _, err = tx.Exec(query, values...)
// if err != nil {
// _ = tx.Rollback()
// return err
// }
// return tx.Commit()
return nil
2019-05-28 18:31:25 +00:00
}
2019-11-11 20:41:58 +00:00
func ( user * User ) IsInPortal ( key PortalKey ) bool {
2021-02-13 05:53:35 +00:00
// row := user.db.QueryRow(`SELECT EXISTS(SELECT 1 FROM user_portal WHERE user_jid=$1 AND portal_jid=$2 AND portal_receiver=$3)`, user.jidPtr(), &key.JID, &key.Receiver)
// var exists bool
// _ = row.Scan(&exists)
// return exists
return false
2019-11-10 19:22:11 +00:00
}
2019-05-28 18:31:25 +00:00
func ( user * User ) GetPortalKeys ( ) [ ] PortalKey {
2021-02-13 05:53:35 +00:00
// rows, err := user.db.Query(`SELECT portal_jid, portal_receiver FROM user_portal WHERE user_jid=$1`, user.jidPtr())
// if err != nil {
// user.log.Warnln("Failed to get user portal keys:", err)
// return nil
// }
// var keys []PortalKey
// for rows.Next() {
// var key PortalKey
// err = rows.Scan(&key.JID, &key.Receiver)
// if err != nil {
// user.log.Warnln("Failed to scan row:", err)
// continue
// }
// keys = append(keys, key)
// }
// return keys
return nil
2019-05-28 18:31:25 +00:00
}
2019-08-10 12:24:53 +00:00
func ( user * User ) GetInCommunityMap ( ) map [ PortalKey ] bool {
2021-02-13 05:53:35 +00:00
// rows, err := user.db.Query(`SELECT portal_jid, portal_receiver, in_community FROM user_portal WHERE user_jid=$1`, user.jidPtr())
// if err != nil {
// user.log.Warnln("Failed to get user portal keys:", err)
// return nil
// }
// keys := make(map[PortalKey]bool)
// for rows.Next() {
// var key PortalKey
// var inCommunity bool
// err = rows.Scan(&key.JID, &key.Receiver, &inCommunity)
// if err != nil {
// user.log.Warnln("Failed to scan row:", err)
// continue
// }
// keys[key] = inCommunity
// }
// return keys
return nil
2019-08-10 12:24:53 +00:00
}