mirror of
https://github.com/Unkn0wnCat/matrix-veles.git
synced 2025-04-29 18:26:48 +02:00
Add hash-lists filtering, format code, prepare API
This commit is contained in:
parent
b81af24e50
commit
1b15b12859
11 changed files with 353 additions and 106 deletions
|
@ -18,7 +18,6 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/Unkn0wnCat/matrix-veles/internal/config"
|
||||
"github.com/spf13/viper"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -49,13 +48,16 @@ func Execute() {
|
|||
func init() {
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./config.yaml)")
|
||||
|
||||
viper.SetDefault("bot.homeserver", "https://matrix.org")
|
||||
viper.SetDefault("bot.homeserver", "matrix.org")
|
||||
viper.SetDefault("bot.homeserver_url", "https://matrix.org")
|
||||
viper.SetDefault("bot.username", "")
|
||||
viper.SetDefault("bot.password", "")
|
||||
viper.SetDefault("bot.accessKey", "")
|
||||
viper.SetDefault("bot.rooms", config.RoomConfigTree{})
|
||||
viper.SetDefault("bot.mongo.uri", "mongodb://localhost:27017")
|
||||
viper.SetDefault("bot.mongo.database", "veles")
|
||||
viper.SetDefault("bot.mongo.collection.entries", "entries")
|
||||
viper.SetDefault("bot.mongo.collection.lists", "lists")
|
||||
viper.SetDefault("bot.mongo.collection.rooms", "rooms")
|
||||
|
||||
cobra.OnInitialize(loadConfig)
|
||||
}
|
||||
|
|
80
internal/bot/getState.go
Normal file
80
internal/bot/getState.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package bot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
type StateEventPL struct {
|
||||
Type string `json:"type"`
|
||||
Sender string `json:"sender"`
|
||||
RoomID string `json:"room_id"`
|
||||
EventID string `json:"event_id"`
|
||||
OriginServerTS int64 `json:"origin_server_ts"`
|
||||
Content StateEventPLContent `json:"content"`
|
||||
Unsigned struct {
|
||||
Age int `json:"age"`
|
||||
} `json:"unsigned"`
|
||||
}
|
||||
|
||||
type StateEventPLContent struct {
|
||||
Ban int `json:"ban"`
|
||||
Events map[string]int `json:"events"`
|
||||
EventsDefault int `json:"events_default"`
|
||||
Invite int `json:"invite"`
|
||||
Kick int `json:"kick"`
|
||||
Notifications map[string]int `json:"notifications"`
|
||||
Redact int `json:"redact"`
|
||||
StateDefault int `json:"state_default"`
|
||||
Users map[string]int `json:"users"`
|
||||
UsersDefault int `json:"users_default"`
|
||||
}
|
||||
|
||||
func GetRoomState(matrixClient *mautrix.Client, roomId id.RoomID) (*StateEventPLContent, error) {
|
||||
url := matrixClient.BuildURL("rooms", roomId.String(), "state")
|
||||
res, err := matrixClient.MakeRequest("GET", url, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ERROR: Could request room state - %v", err)
|
||||
}
|
||||
|
||||
var stateEvents []StateEventPL
|
||||
|
||||
err = json.Unmarshal(res, &stateEvents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ERROR: Could parse room state - %v", err)
|
||||
}
|
||||
|
||||
var plEventContent StateEventPLContent
|
||||
|
||||
found := false
|
||||
|
||||
for _, e2 := range stateEvents {
|
||||
if e2.Type != event.StatePowerLevels.Type {
|
||||
continue
|
||||
}
|
||||
|
||||
found = true
|
||||
plEventContent = e2.Content
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, fmt.Errorf("ERROR: Could find room power level - %v", err)
|
||||
}
|
||||
|
||||
if plEventContent.Events == nil {
|
||||
plEventContent.Events = make(map[string]int)
|
||||
}
|
||||
|
||||
if plEventContent.Notifications == nil {
|
||||
plEventContent.Notifications = make(map[string]int)
|
||||
}
|
||||
|
||||
if plEventContent.Users == nil {
|
||||
plEventContent.Users = make(map[string]int)
|
||||
}
|
||||
|
||||
return &plEventContent, nil
|
||||
}
|
|
@ -15,7 +15,6 @@ import (
|
|||
"log"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
func handleHashing(content *event.MessageEventContent, evt *event.Event, matrixClient *mautrix.Client) {
|
||||
|
@ -86,6 +85,36 @@ func handleHashing(content *event.MessageEventContent, evt *event.Event, matrixC
|
|||
matrixClient.SendNotice(evt.RoomID, fmt.Sprintf("DEBUG:\n%s", buf.String()))
|
||||
}
|
||||
|
||||
if roomConfig.HashChecker.SubscribedLists == nil {
|
||||
log.Printf("Room %s is not subscribed to any lists!", roomConfig.RoomID)
|
||||
return // Not subscribed to any lists
|
||||
}
|
||||
|
||||
subMap := make(map[string]bool)
|
||||
|
||||
for _, listId := range roomConfig.HashChecker.SubscribedLists {
|
||||
subMap[listId.Hex()] = true
|
||||
}
|
||||
|
||||
found := false
|
||||
log.Printf("%v", subMap)
|
||||
|
||||
for _, listId := range hashObj.PartOf {
|
||||
_, ok := subMap[listId.Hex()]
|
||||
|
||||
if ok {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.Printf("Room %s is not subscribed to any lists of hashobj %s!", roomConfig.RoomID, hashObj.ID.Hex())
|
||||
return // Not subscribed
|
||||
}
|
||||
|
||||
log.Printf("Illegal content detected in room %s!", roomConfig.RoomID)
|
||||
|
||||
handleIllegalContent(evt, matrixClient, hashObj, roomConfig)
|
||||
}
|
||||
|
||||
|
@ -97,78 +126,6 @@ func redactMessage(evt *event.Event, matrixClient *mautrix.Client, hashObj *mode
|
|||
}
|
||||
}
|
||||
|
||||
type StateEventPL struct {
|
||||
Type string `json:"type"`
|
||||
Sender string `json:"sender"`
|
||||
RoomID string `json:"room_id"`
|
||||
EventID string `json:"event_id"`
|
||||
OriginServerTS int64 `json:"origin_server_ts"`
|
||||
Content StateEventPLContent `json:"content"`
|
||||
Unsigned struct {
|
||||
Age int `json:"age"`
|
||||
} `json:"unsigned"`
|
||||
}
|
||||
|
||||
type StateEventPLContent struct {
|
||||
Ban int `json:"ban"`
|
||||
Events map[string]int `json:"events"`
|
||||
EventsDefault int `json:"events_default"`
|
||||
Invite int `json:"invite"`
|
||||
Kick int `json:"kick"`
|
||||
Notifications map[string]int `json:"notifications"`
|
||||
Redact int `json:"redact"`
|
||||
StateDefault int `json:"state_default"`
|
||||
Users map[string]int `json:"users"`
|
||||
UsersDefault int `json:"users_default"`
|
||||
}
|
||||
|
||||
func GetRoomState(matrixClient *mautrix.Client, roomId id.RoomID) (*StateEventPLContent, error) {
|
||||
url := matrixClient.BuildURL("rooms", roomId.String(), "state")
|
||||
log.Println(url)
|
||||
res, err := matrixClient.MakeRequest("GET", url, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ERROR: Could request room state - %v", err)
|
||||
}
|
||||
|
||||
var stateEvents []StateEventPL
|
||||
|
||||
err = json.Unmarshal(res, &stateEvents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ERROR: Could parse room state - %v", err)
|
||||
}
|
||||
|
||||
var plEventContent StateEventPLContent
|
||||
|
||||
found := false
|
||||
|
||||
for _, e2 := range stateEvents {
|
||||
if e2.Type != event.StatePowerLevels.Type {
|
||||
continue
|
||||
}
|
||||
|
||||
found = true
|
||||
plEventContent = e2.Content
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, fmt.Errorf("ERROR: Could find room power level - %v", err)
|
||||
}
|
||||
|
||||
if plEventContent.Events == nil {
|
||||
plEventContent.Events = make(map[string]int)
|
||||
}
|
||||
|
||||
if plEventContent.Notifications == nil {
|
||||
plEventContent.Notifications = make(map[string]int)
|
||||
}
|
||||
|
||||
if plEventContent.Users == nil {
|
||||
plEventContent.Users = make(map[string]int)
|
||||
}
|
||||
|
||||
return &plEventContent, nil
|
||||
}
|
||||
|
||||
func muteUser(evt *event.Event, matrixClient *mautrix.Client, hashObj *model.DBEntry) {
|
||||
plEventContent, err := GetRoomState(matrixClient, evt.RoomID)
|
||||
if err != nil {
|
||||
|
@ -186,6 +143,15 @@ func muteUser(evt *event.Event, matrixClient *mautrix.Client, hashObj *model.DBE
|
|||
|
||||
}
|
||||
|
||||
func banUser(evt *event.Event, matrixClient *mautrix.Client, hashObj *model.DBEntry) {
|
||||
req := mautrix.ReqBanUser{
|
||||
Reason: fmt.Sprintf("Veles has detected an hash-map-match! Tags: %s, ID: %s", hashObj.Tags, hashObj.ID.Hex()),
|
||||
UserID: evt.Sender,
|
||||
}
|
||||
|
||||
matrixClient.BanUser(evt.RoomID, &req)
|
||||
}
|
||||
|
||||
func postNotice(evt *event.Event, matrixClient *mautrix.Client, hashObj *model.DBEntry, roomConfig config.RoomConfig) {
|
||||
local, server, err := evt.Sender.Parse()
|
||||
if err != nil {
|
||||
|
@ -198,18 +164,39 @@ If you believe this action was an accident, please contact an room administrator
|
|||
|
||||
}
|
||||
|
||||
/*func msgMods(evt *event.Event, matrixClient *mautrix.Client, hashObj *model.DBEntry, roomConfig config.RoomConfig) {
|
||||
local, server, err := evt.Sender.Parse()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
SendAlert(matrixClient, evt.RoomID.String(), fmt.Sprintf(
|
||||
`Veles Triggered: The message by %s (on %s) was flagged for containing material used by spammers or trolls! (Reference: %s)`, local, server, hashObj.ID.Hex()))
|
||||
}*/
|
||||
|
||||
func handleIllegalContent(evt *event.Event, matrixClient *mautrix.Client, hashObj *model.DBEntry, roomConfig config.RoomConfig) {
|
||||
switch roomConfig.HashCheckMode {
|
||||
switch roomConfig.HashChecker.HashCheckMode {
|
||||
case 0:
|
||||
postNotice(evt, matrixClient, hashObj, roomConfig)
|
||||
break
|
||||
case 1:
|
||||
redactMessage(evt, matrixClient, hashObj)
|
||||
if roomConfig.HashChecker.NoticeToChat {
|
||||
postNotice(evt, matrixClient, hashObj, roomConfig)
|
||||
}
|
||||
break
|
||||
case 2:
|
||||
muteUser(evt, matrixClient, hashObj)
|
||||
redactMessage(evt, matrixClient, hashObj)
|
||||
postNotice(evt, matrixClient, hashObj, roomConfig)
|
||||
if roomConfig.HashChecker.NoticeToChat {
|
||||
postNotice(evt, matrixClient, hashObj, roomConfig)
|
||||
}
|
||||
break
|
||||
case 3:
|
||||
banUser(evt, matrixClient, hashObj)
|
||||
redactMessage(evt, matrixClient, hashObj)
|
||||
if roomConfig.HashChecker.NoticeToChat {
|
||||
postNotice(evt, matrixClient, hashObj, roomConfig)
|
||||
}
|
||||
break
|
||||
|
||||
}
|
||||
|
|
47
internal/bot/sendAlert.go
Normal file
47
internal/bot/sendAlert.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package bot
|
||||
|
||||
/*func SendAlert(matrixClient *mautrix.Client, room string, message string) {
|
||||
roomConfig, err := config.GetRoomConfigByRoomID(room)
|
||||
if err != nil {
|
||||
log.Printf("Failed to get room config - %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if roomConfig.AlertChannel == nil {
|
||||
roomPLState, err := GetRoomState(matrixClient, id.RoomID(room))
|
||||
if err != nil {
|
||||
log.Printf("Failed to get room power levels - %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
var mods []id.UserID
|
||||
|
||||
for member, level := range roomPLState.Users {
|
||||
if level >= roomConfig.HashChecker.NotificationPowerLevel {
|
||||
mods = append(mods, id.UserID(member))
|
||||
}
|
||||
}
|
||||
|
||||
req := mautrix.ReqCreateRoom{
|
||||
Name: "Veles Alert Channel",
|
||||
Topic: "Veles Alerts",
|
||||
Invite: mods,
|
||||
IsDirect: true,
|
||||
Visibility: "private",
|
||||
}
|
||||
|
||||
resp, err := matrixClient.CreateRoom(&req)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create alert room - %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
str := resp.RoomID.String()
|
||||
|
||||
roomConfig.AlertChannel = &str
|
||||
|
||||
config.SaveRoomConfig(roomConfig)
|
||||
}
|
||||
|
||||
matrixClient.SendNotice(id.RoomID(*roomConfig.AlertChannel), message)
|
||||
}*/
|
|
@ -42,7 +42,7 @@ func SetRoomConfigActive(id string, active bool) {
|
|||
roomConfigWg.Add(1)
|
||||
|
||||
roomConfig := GetRoomConfig(id)
|
||||
roomConfig.Active = true
|
||||
roomConfig.Active = active
|
||||
|
||||
err := SaveRoomConfig(&roomConfig)
|
||||
if err != nil {
|
||||
|
@ -67,9 +67,9 @@ func GetRoomConfig(id string) RoomConfig {
|
|||
|
||||
// RoomConfigInitialUpdate updates all RoomConfig entries to set activity and create blank configs
|
||||
func RoomConfigInitialUpdate(ids []id.RoomID) {
|
||||
db := db.DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
database := db.DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
cursor, err := db.Collection("rooms").Find(context.TODO(), bson.D{}, nil)
|
||||
cursor, err := database.Collection("rooms").Find(context.TODO(), bson.D{}, nil)
|
||||
if err != nil {
|
||||
log.Panicf("Error querying room configs: %v", err)
|
||||
}
|
||||
|
@ -105,7 +105,8 @@ func AddRoomConfig(id string) RoomConfig {
|
|||
roomConfigWg.Wait()
|
||||
roomConfigWg.Add(1)
|
||||
|
||||
config := RoomConfig{ID: primitive.NewObjectID(), Active: true, RoomID: id}
|
||||
config := GetDefaultRoomConfig()
|
||||
config.RoomID = id
|
||||
|
||||
err := SaveRoomConfig(&config)
|
||||
if err != nil {
|
||||
|
@ -119,26 +120,26 @@ func AddRoomConfig(id string) RoomConfig {
|
|||
}
|
||||
|
||||
func SaveRoomConfig(roomConfig *RoomConfig) error {
|
||||
db := db.DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
database := db.DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
opts := options.Replace().SetUpsert(true)
|
||||
|
||||
filter := bson.D{{"room_id", roomConfig.RoomID}}
|
||||
|
||||
_, err := db.Collection("rooms").ReplaceOne(context.TODO(), filter, roomConfig, opts)
|
||||
_, err := database.Collection(viper.GetString("bot.mongo.collection.rooms")).ReplaceOne(context.TODO(), filter, roomConfig, opts)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetRoomConfigByRoomID(id string) (*RoomConfig, error) {
|
||||
db := db.DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
database := db.DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
res := db.Collection("rooms").FindOne(context.TODO(), bson.D{{"room_id", id}})
|
||||
res := database.Collection(viper.GetString("bot.mongo.collection.rooms")).FindOne(context.TODO(), bson.D{{"room_id", id}})
|
||||
if res.Err() != nil {
|
||||
return nil, res.Err()
|
||||
}
|
||||
|
||||
object := RoomConfig{}
|
||||
object := GetDefaultRoomConfig()
|
||||
|
||||
err := res.Decode(&object)
|
||||
if err != nil {
|
||||
|
@ -147,3 +148,18 @@ func GetRoomConfigByRoomID(id string) (*RoomConfig, error) {
|
|||
|
||||
return &object, nil
|
||||
}
|
||||
|
||||
func GetDefaultRoomConfig() RoomConfig {
|
||||
return RoomConfig{
|
||||
ID: primitive.NewObjectID(),
|
||||
Active: true,
|
||||
RoomID: "",
|
||||
Debug: false,
|
||||
AdminPowerLevel: 100,
|
||||
HashChecker: HashCheckerConfig{
|
||||
NoticeToChat: true,
|
||||
NotificationPowerLevel: 50,
|
||||
HashCheckMode: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,14 +35,28 @@ type RoomConfig struct {
|
|||
// Debug specifies if the bot shall run in dry run mode
|
||||
Debug bool `yaml:"debug" bson:"debug"`
|
||||
|
||||
AlertChannel *string `bson:"alert_channel"`
|
||||
|
||||
AdminPowerLevel int `bson:"admin_power_level"`
|
||||
|
||||
HashChecker HashCheckerConfig `bson:"hash_checker"`
|
||||
}
|
||||
|
||||
type HashCheckerConfig struct {
|
||||
NoticeToChat bool `bson:"chat_notice"`
|
||||
|
||||
NotificationPowerLevel int `yaml:"notification_level" bson:"notification_level"`
|
||||
|
||||
/*
|
||||
HashCheckMode specifies the mode the bot should operate under in this room
|
||||
|
||||
HashCheck-Modes:
|
||||
0. Silent Mode (Don't do anything)
|
||||
1. Notify Mode (Message Room Admins & Mods)
|
||||
2. Mute Mode (Remove message, notify admin & mute user)
|
||||
3. Ban Mode (Remove message, notify admin & ban user)
|
||||
0. Notice Mode (Post notice)
|
||||
1. Delete Mode (Remove message, post notice)
|
||||
2. Mute Mode (Remove message, post notice & mute user)
|
||||
3. Ban Mode (Remove message, post notice & ban user)
|
||||
*/
|
||||
HashCheckMode uint8 `yaml:"mode" bson:"hash_check_mode"`
|
||||
|
||||
SubscribedLists []*primitive.ObjectID `bson:"subscribed_lists" json:"subscribed_lists"`
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/Unkn0wnCat/matrix-veles/internal/db/model"
|
||||
"github.com/spf13/viper"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"log"
|
||||
|
@ -37,15 +38,15 @@ func SaveEntry(entry *model.DBEntry) error {
|
|||
|
||||
filter := bson.D{{"_id", entry.ID}}
|
||||
|
||||
_, err := db.Collection("entries").ReplaceOne(context.TODO(), filter, entry, opts)
|
||||
_, err := db.Collection(viper.GetString("bot.mongo.collection.entries")).ReplaceOne(context.TODO(), filter, entry, opts)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetEntryByHash(hash string) (*model.DBEntry, error) {
|
||||
func GetEntryByID(id primitive.ObjectID) (*model.DBEntry, error) {
|
||||
db := DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
res := db.Collection("entries").FindOne(context.TODO(), bson.D{{"hash_value", hash}})
|
||||
res := db.Collection(viper.GetString("bot.mongo.collection.entries")).FindOne(context.TODO(), bson.D{{"_id", id}})
|
||||
if res.Err() != nil {
|
||||
return nil, res.Err()
|
||||
}
|
||||
|
@ -59,3 +60,51 @@ func GetEntryByHash(hash string) (*model.DBEntry, error) {
|
|||
|
||||
return &object, nil
|
||||
}
|
||||
|
||||
func GetEntryByHash(hash string) (*model.DBEntry, error) {
|
||||
db := DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
res := db.Collection(viper.GetString("bot.mongo.collection.entries")).FindOne(context.TODO(), bson.D{{"hash_value", hash}})
|
||||
if res.Err() != nil {
|
||||
return nil, res.Err()
|
||||
}
|
||||
|
||||
object := model.DBEntry{}
|
||||
|
||||
err := res.Decode(&object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &object, nil
|
||||
}
|
||||
|
||||
func SaveList(list *model.DBHashList) error {
|
||||
db := DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
opts := options.Replace().SetUpsert(true)
|
||||
|
||||
filter := bson.D{{"_id", list.ID}}
|
||||
|
||||
_, err := db.Collection(viper.GetString("bot.mongo.collection.lists")).ReplaceOne(context.TODO(), filter, list, opts)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetListByID(id primitive.ObjectID) (*model.DBHashList, error) {
|
||||
db := DbClient.Database(viper.GetString("bot.mongo.database"))
|
||||
|
||||
res := db.Collection(viper.GetString("bot.mongo.collection.lists")).FindOne(context.TODO(), bson.D{{"_id", id}})
|
||||
if res.Err() != nil {
|
||||
return nil, res.Err()
|
||||
}
|
||||
|
||||
object := model.DBHashList{}
|
||||
|
||||
err := res.Decode(&object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &object, nil
|
||||
}
|
||||
|
|
8
internal/db/model/comment.go
Normal file
8
internal/db/model/comment.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package model
|
||||
|
||||
import "go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
type DBComment struct {
|
||||
CommentedBy *primitive.ObjectID `bson:"commented_by" json:"commented_by"`
|
||||
Content string `bson:"content" json:"content"`
|
||||
}
|
|
@ -6,16 +6,12 @@ import (
|
|||
)
|
||||
|
||||
type DBEntry struct {
|
||||
ID primitive.ObjectID `bson:"_id" json:"id"`
|
||||
Tags []string `bson:"tags" json:"tags"`
|
||||
HashValue string `bson:"hash_value" json:"hash"`
|
||||
FileURL string `bson:"file_url" json:"file_url"`
|
||||
Timestamp time.Time `bson:"timestamp" json:"timestamp"`
|
||||
AddedBy *primitive.ObjectID `bson:"added_by" json:"added_by"`
|
||||
Comments []*DBEntryComment `bson:"comments" json:"comments"`
|
||||
}
|
||||
|
||||
type DBEntryComment struct {
|
||||
CommentedBy *primitive.ObjectID `bson:"commented_by" json:"commented_by"`
|
||||
Content string `bson:"content" json:"content"`
|
||||
ID primitive.ObjectID `bson:"_id" json:"id"`
|
||||
Tags []string `bson:"tags" json:"tags"`
|
||||
PartOf []*primitive.ObjectID `bson:"part_of" json:"part_of"`
|
||||
HashValue string `bson:"hash_value" json:"hash"`
|
||||
FileURL string `bson:"file_url" json:"file_url"`
|
||||
Timestamp time.Time `bson:"timestamp" json:"timestamp"`
|
||||
AddedBy *primitive.ObjectID `bson:"added_by" json:"added_by"`
|
||||
Comments []*DBComment `bson:"comments" json:"comments"`
|
||||
}
|
||||
|
|
10
internal/db/model/list.go
Normal file
10
internal/db/model/list.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package model
|
||||
|
||||
import "go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
type DBHashList struct {
|
||||
ID primitive.ObjectID `bson:"_id" json:"id"`
|
||||
Tags []string `bson:"tags" json:"tags"`
|
||||
Comments []*DBComment `bson:"comments" json:"comments"`
|
||||
Maintainers []*primitive.ObjectID `bson:"maintainers" json:"maintainers"`
|
||||
}
|
38
internal/db/model/user.go
Normal file
38
internal/db/model/user.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type DBUser struct {
|
||||
Username string `bson:"username" json:"username"`
|
||||
HashedPassword string `bson:"password" json:"password"`
|
||||
|
||||
Password *string `bson:"-" json:"-"`
|
||||
}
|
||||
|
||||
func (usr *DBUser) HashPassword() error {
|
||||
if usr.Password == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(*usr.Password), 14)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
usr.HashedPassword = base64.StdEncoding.EncodeToString(hash)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (usr *DBUser) CheckPassword(password string) error {
|
||||
hash, err := base64.StdEncoding.DecodeString(usr.HashedPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword(hash, []byte(password))
|
||||
|
||||
return err
|
||||
}
|
Loading…
Add table
Reference in a new issue