Private
Public Access
1
0
Files
Kordophone/server/server.go

160 lines
3.4 KiB
Go

package server
import (
"sort"
"code.severnaya.net/kordophone-mock/v2/data"
"code.severnaya.net/kordophone-mock/v2/model"
)
const VERSION = "Kordophone-2.0"
const (
AUTH_USERNAME = "test"
AUTH_PASSWORD = "test"
)
type Server struct {
version string
conversations []model.Conversation
authTokens []model.AuthToken
messageStore map[string][]model.Message
}
type AuthError struct {
message string
}
func (e *AuthError) Error() string {
return e.message
}
type DatabaseError struct {
message string
}
func (e *DatabaseError) Error() string {
return e.message
}
func NewServer() *Server {
return &Server{
version: VERSION,
conversations: []model.Conversation{},
authTokens: []model.AuthToken{},
messageStore: make(map[string][]model.Message),
}
}
func (s *Server) Version() string {
return s.version
}
func (s *Server) Conversations() []model.Conversation {
return s.conversations
}
func (s *Server) SortedConversations() []model.Conversation {
conversations := s.Conversations()
sort.Slice(conversations, func(i, j int) bool {
return conversations[i].Date.After(conversations[j].Date)
})
return conversations
}
func (s *Server) ConversationForGUID(guid string) (*model.Conversation, error) {
var conversation *model.Conversation = nil
for i := range s.conversations {
c := &s.conversations[i]
if c.Guid == guid {
conversation = c
break
}
}
if conversation != nil {
return conversation, nil
}
return nil, &DatabaseError{message: "Conversation not found"}
}
func (s *Server) AddConversation(c model.Conversation) {
s.conversations = append(s.conversations, c)
}
func (s *Server) PopulateWithTestData() {
numConversations := 100
cs := make([]model.Conversation, numConversations)
for i := 0; i < numConversations; i++ {
cs[i] = data.GenerateRandomConversation()
// Generate messages
convo := &cs[i]
var lastMessage model.Message
for i := 0; i < 100; i++ {
message := data.GenerateRandomMessage(convo.Participants)
s.AppendMessageToConversation(convo, message)
if lastMessage.Date.Before(message.Date) {
lastMessage = message
}
}
// Update last message preview
convo.LastMessagePreview = lastMessage.Text
}
s.conversations = cs
}
func (s *Server) Authenticate(username string, password string) (*model.AuthToken, error) {
if username != AUTH_USERNAME || password != AUTH_PASSWORD {
return nil, &AuthError{"Invalid username or password"}
}
token, err := model.NewAuthToken(username)
if err != nil {
return nil, err
}
// Register for future auth
s.registerAuthToken(token)
return token, nil
}
func (s *Server) CheckBearerToken(token string) bool {
return s.authenticateToken(token)
}
func (s *Server) MessagesForConversation(conversation *model.Conversation) []model.Message {
messages := s.messageStore[conversation.Guid]
sort.Slice(messages, func(i int, j int) bool {
return messages[i].Date.Before(messages[j].Date)
})
return messages
}
func (s *Server) AppendMessageToConversation(conversation *model.Conversation, message model.Message) {
s.messageStore[conversation.Guid] = append(s.messageStore[conversation.Guid], message)
}
// Private
func (s *Server) registerAuthToken(token *model.AuthToken) {
s.authTokens = append(s.authTokens, *token)
}
func (s *Server) authenticateToken(token string) bool {
for _, t := range s.authTokens {
if t.SignedToken == token {
return true
}
}
return false
}