2022-12-03 03:20:49 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-12-10 03:16:43 +00:00
|
|
|
"encoding/json"
|
2022-12-03 03:20:49 +00:00
|
|
|
"time"
|
|
|
|
|
2022-12-06 01:48:03 +00:00
|
|
|
"github.com/livekit/protocol/livekit"
|
2022-12-03 03:20:49 +00:00
|
|
|
mastodon "github.com/mattn/go-mastodon"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
SessionData struct {
|
|
|
|
MastodonConfig *mastodon.Config
|
|
|
|
AuthCode string
|
|
|
|
AudonID string
|
|
|
|
}
|
|
|
|
|
|
|
|
AudonUser struct {
|
2022-12-04 05:19:41 +00:00
|
|
|
AudonID string `bson:"audon_id" json:"audon_id" validate:"alphanum"`
|
2022-12-04 17:52:44 +00:00
|
|
|
RemoteID string `bson:"remote_id" json:"remote_id" validate:"printascii"`
|
2022-12-04 05:19:41 +00:00
|
|
|
RemoteURL string `bson:"remote_url" json:"remote_url" validate:"url"`
|
2022-12-29 14:53:42 +00:00
|
|
|
Webfinger string `bson:"webfinger" json:"webfinger" validate:"email"`
|
2022-12-03 03:20:49 +00:00
|
|
|
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
|
|
|
}
|
|
|
|
|
2022-12-10 03:16:43 +00:00
|
|
|
RoomMetadata struct {
|
|
|
|
*Room
|
|
|
|
Speakers []*AudonUser `json:"speakers"`
|
|
|
|
}
|
|
|
|
|
2022-12-03 03:20:49 +00:00
|
|
|
Room struct {
|
2022-12-15 20:28:41 +00:00
|
|
|
RoomID string `bson:"room_id" json:"room_id" validate:"required,printascii"`
|
|
|
|
Title string `bson:"title" json:"title" validate:"required,max=100,printascii|multibyte"`
|
|
|
|
Description string `bson:"description" json:"description" validate:"max=500,ascii|multibyte"`
|
|
|
|
Host *AudonUser `bson:"host" json:"host"`
|
2022-12-16 03:36:51 +00:00
|
|
|
CoHosts []*AudonUser `bson:"cohosts" json:"cohosts"`
|
|
|
|
Restriction JoinRestriction `bson:"restriction" json:"restriction"`
|
2022-12-15 20:28:41 +00:00
|
|
|
Kicked []*AudonUser `bson:"kicked" json:"kicked"`
|
|
|
|
ScheduledAt time.Time `bson:"scheduled_at" json:"scheduled_at"`
|
|
|
|
EndedAt time.Time `bson:"ended_at" json:"ended_at"`
|
|
|
|
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
2023-01-14 23:02:15 +00:00
|
|
|
Advertise string `bson:"advertise" json:"advertise"`
|
2022-12-03 03:20:49 +00:00
|
|
|
}
|
2022-12-09 00:21:17 +00:00
|
|
|
|
|
|
|
TokenResponse struct {
|
|
|
|
Url string `json:"url"`
|
|
|
|
Token string `json:"token"`
|
|
|
|
AudonID string `json:"audon_id"`
|
|
|
|
}
|
2022-12-03 03:20:49 +00:00
|
|
|
)
|
|
|
|
|
2022-12-15 20:28:41 +00:00
|
|
|
type JoinRestriction string
|
|
|
|
|
2022-12-03 03:20:49 +00:00
|
|
|
const (
|
|
|
|
COLLECTION_USER = "user"
|
|
|
|
COLLECTION_ROOM = "room"
|
2022-12-15 20:28:41 +00:00
|
|
|
|
2022-12-29 14:53:42 +00:00
|
|
|
EVERYONE JoinRestriction = "everyone"
|
2022-12-15 20:28:41 +00:00
|
|
|
FOLLOWING JoinRestriction = "following"
|
|
|
|
FOLLOWER JoinRestriction = "follower"
|
|
|
|
FOLLOWING_OR_FOLLOWER JoinRestriction = "knowing"
|
|
|
|
MUTUAL JoinRestriction = "mutual"
|
|
|
|
PRIVATE JoinRestriction = "private"
|
2022-12-03 03:20:49 +00:00
|
|
|
)
|
|
|
|
|
2022-12-05 01:11:44 +00:00
|
|
|
func (a *AudonUser) Equal(u *AudonUser) bool {
|
|
|
|
if a == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return a.AudonID == u.AudonID || (a.RemoteID == u.RemoteID && a.RemoteURL == u.RemoteURL)
|
|
|
|
}
|
|
|
|
|
2022-12-15 20:28:41 +00:00
|
|
|
func (r *Room) IsFollowingOnly() bool {
|
|
|
|
return r.Restriction == FOLLOWING
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Room) IsFollowerOnly() bool {
|
|
|
|
return r.Restriction == FOLLOWER
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Room) IsFollowingOrFollowerOnly() bool {
|
|
|
|
return r.Restriction == FOLLOWING_OR_FOLLOWER
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Room) IsMutualOnly() bool {
|
|
|
|
return r.Restriction == MUTUAL
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Room) IsPrivate() bool {
|
|
|
|
return r.Restriction == PRIVATE
|
|
|
|
}
|
|
|
|
|
2022-12-05 01:11:44 +00:00
|
|
|
func (r *Room) IsCoHost(u *AudonUser) bool {
|
|
|
|
if r == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-12-07 19:03:22 +00:00
|
|
|
for _, cohost := range r.CoHosts {
|
2022-12-05 01:11:44 +00:00
|
|
|
if cohost.Equal(u) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Room) IsHost(u *AudonUser) bool {
|
|
|
|
return r != nil && r.Host.Equal(u)
|
|
|
|
}
|
|
|
|
|
2022-12-10 03:16:43 +00:00
|
|
|
func getRoomMetadataFromLivekitRoom(lkRoom *livekit.Room) (*RoomMetadata, error) {
|
|
|
|
metadata := new(RoomMetadata)
|
|
|
|
if err := json.Unmarshal([]byte(lkRoom.GetMetadata()), metadata); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return metadata, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Room) ExistsInLivekit(ctx context.Context) bool {
|
|
|
|
lkRooms, _ := lkRoomServiceClient.ListRooms(ctx, &livekit.ListRoomsRequest{Names: []string{r.RoomID}})
|
|
|
|
|
|
|
|
return len(lkRooms.GetRooms()) > 0
|
|
|
|
}
|
|
|
|
|
2022-12-06 01:48:03 +00:00
|
|
|
func (r *Room) IsUserInLivekitRoom(ctx context.Context, userID string) bool {
|
2022-12-10 03:16:43 +00:00
|
|
|
if r == nil {
|
|
|
|
return false
|
|
|
|
}
|
2022-12-06 01:48:03 +00:00
|
|
|
participantsInfo, _ := lkRoomServiceClient.ListParticipants(ctx, &livekit.ListParticipantsRequest{Room: r.RoomID})
|
|
|
|
participants := participantsInfo.GetParticipants()
|
|
|
|
|
|
|
|
for _, info := range participants {
|
|
|
|
if info.GetIdentity() == userID {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-12-06 06:09:15 +00:00
|
|
|
func (r *Room) IsAnyomeInLivekitRoom(ctx context.Context) bool {
|
|
|
|
participantsInfo, _ := lkRoomServiceClient.ListParticipants(ctx, &livekit.ListParticipantsRequest{Room: r.RoomID})
|
|
|
|
participants := participantsInfo.GetParticipants()
|
|
|
|
|
|
|
|
return len(participants) > 0
|
|
|
|
}
|
|
|
|
|
2022-12-03 03:20:49 +00:00
|
|
|
func createIndexes(ctx context.Context) error {
|
|
|
|
userColl := mainDB.Collection(COLLECTION_USER)
|
|
|
|
userIndexes, err := userColl.Indexes().ListSpecifications(ctx)
|
2022-12-04 17:52:44 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-03 03:20:49 +00:00
|
|
|
|
|
|
|
if len(userIndexes) < 3 {
|
|
|
|
_, err := userColl.Indexes().CreateMany(ctx, []mongo.IndexModel{
|
|
|
|
{
|
|
|
|
Keys: bson.D{{Key: "audon_id", Value: 1}},
|
2022-12-04 17:52:44 +00:00
|
|
|
Options: options.Index().SetUnique(true),
|
2022-12-03 03:20:49 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
Keys: bson.D{
|
|
|
|
{Key: "remote_url", Value: 1},
|
|
|
|
{Key: "remote_id", Value: 1},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-04 17:52:44 +00:00
|
|
|
roomColl := mainDB.Collection(COLLECTION_ROOM)
|
|
|
|
roomIndexes, err := roomColl.Indexes().ListSpecifications(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(roomIndexes) < 3 {
|
|
|
|
_, err := roomColl.Indexes().CreateMany(ctx, []mongo.IndexModel{
|
|
|
|
{
|
|
|
|
Keys: bson.D{{Key: "room_id", Value: 1}},
|
|
|
|
Options: options.Index().SetUnique(true),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Keys: bson.D{{Key: "host.audon_id", Value: 1}},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2022-12-03 03:20:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func findUserByRemote(ctx context.Context, remoteID, remoteURL string) (*AudonUser, error) {
|
|
|
|
var result AudonUser
|
|
|
|
coll := mainDB.Collection(COLLECTION_USER)
|
|
|
|
if err := coll.FindOne(ctx, bson.D{{Key: "remote_url", Value: remoteURL}, {Key: "remote_id", Value: remoteID}}).Decode(&result); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func findUserByID(ctx context.Context, audonID string) (*AudonUser, error) {
|
|
|
|
var result AudonUser
|
|
|
|
coll := mainDB.Collection(COLLECTION_USER)
|
2022-12-04 05:19:41 +00:00
|
|
|
if err := coll.FindOne(ctx, bson.D{{Key: "audon_id", Value: audonID}}).Decode(&result); err != nil {
|
2022-12-03 03:20:49 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &result, nil
|
|
|
|
}
|