Add 'mock/' from commit '2041d3ce6377da091eca17cf9d8ad176a3024616'
git-subtree-dir: mock git-subtree-mainline:8216d7c706git-subtree-split:2041d3ce63
This commit is contained in:
57
mock/model/attachment.go
Normal file
57
mock/model/attachment.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type AttachmentStore struct {
|
||||
basePath string
|
||||
}
|
||||
|
||||
func NewAttachmentStore(basePath string) AttachmentStore {
|
||||
_, err := os.Stat(basePath)
|
||||
if os.IsNotExist(err) {
|
||||
os.MkdirAll(basePath, 0755)
|
||||
}
|
||||
|
||||
return AttachmentStore{
|
||||
basePath: basePath,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AttachmentStore) FetchAttachment(guid string) (io.Reader, error) {
|
||||
fullPath := path.Join(s.basePath, guid)
|
||||
f, err := os.Open(fullPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bufio.NewReader(f), nil
|
||||
}
|
||||
|
||||
func (s *AttachmentStore) StoreAttachment(filename string, reader io.Reader) (*string, error) {
|
||||
// Generate GUID
|
||||
guid := uuid.New().String()
|
||||
|
||||
fullPath := path.Join(s.basePath, guid)
|
||||
f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := bufio.NewReader(reader)
|
||||
w := bufio.NewWriter(f)
|
||||
_, err = w.ReadFrom(r)
|
||||
|
||||
return &guid, err
|
||||
}
|
||||
|
||||
func (s *AttachmentStore) DeleteAttachment(guid string) error {
|
||||
fullPath := path.Join(s.basePath, guid)
|
||||
return os.Remove(fullPath)
|
||||
}
|
||||
59
mock/model/authtoken.go
Normal file
59
mock/model/authtoken.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type AuthToken struct {
|
||||
SignedToken string `json:"jwt"`
|
||||
token jwt.Token
|
||||
}
|
||||
|
||||
type TokenGenerationError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e *TokenGenerationError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
// Create a struct to hold your custom claims
|
||||
type customClaims struct {
|
||||
Username string `json:"username"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
const signingKey = "nDjYmTjoPrAGzuyhHz6Dq5bqcRrEZJc5Ls3SQcdylBI="
|
||||
|
||||
func NewAuthToken(username string) (*AuthToken, error) {
|
||||
claims := customClaims{
|
||||
Username: username,
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
ExpiresAt: time.Now().Add(time.Hour * 24 * 5).Unix(), // 5 days
|
||||
},
|
||||
}
|
||||
|
||||
// Create a new JWT token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
if token == nil {
|
||||
log.Error().Msg("Error creating Jwt Token")
|
||||
return nil, &TokenGenerationError{"Error creating Jwt Token"}
|
||||
}
|
||||
|
||||
// Sign the token with the specified signing key
|
||||
decodedSigningKey, _ := base64.StdEncoding.DecodeString(signingKey)
|
||||
signedToken, err := token.SignedString(decodedSigningKey)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Error signing Jwt Token")
|
||||
return nil, &TokenGenerationError{"Error signing Jwt Token"}
|
||||
}
|
||||
|
||||
return &AuthToken{
|
||||
SignedToken: signedToken,
|
||||
token: *token,
|
||||
}, nil
|
||||
}
|
||||
73
mock/model/conversation.go
Normal file
73
mock/model/conversation.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Conversation struct {
|
||||
Date Date `json:"date"`
|
||||
Participants []string `json:"participantDisplayNames"`
|
||||
DisplayName *string `json:"displayName,omitempty"` // Optional
|
||||
UnreadCount int `json:"unreadCount"`
|
||||
LastMessagePreview string `json:"lastMessagePreview"`
|
||||
LastMessage Message `json:"lastMessage"`
|
||||
Guid string `json:"guid"`
|
||||
}
|
||||
|
||||
func (c *Conversation) GetDisplayName() string {
|
||||
if c.DisplayName == nil {
|
||||
return strings.Join(c.Participants, ",")
|
||||
}
|
||||
|
||||
return *c.DisplayName
|
||||
}
|
||||
|
||||
func (c *Conversation) MarshalZerologObject(e *zerolog.Event) {
|
||||
e.Str("guid", c.Guid)
|
||||
e.Time("date", time.Time(c.Date))
|
||||
e.Int("unreadCount", c.UnreadCount)
|
||||
e.Str("lastMessagePreview", c.LastMessagePreview)
|
||||
e.Strs("participants", c.Participants)
|
||||
if c.DisplayName != nil {
|
||||
e.Str("displayName", *c.DisplayName)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conversation) Equal(o *Conversation) bool {
|
||||
if c.Guid != o.Guid {
|
||||
return false
|
||||
}
|
||||
|
||||
if !c.Date.Equal(o.Date) {
|
||||
return false
|
||||
}
|
||||
|
||||
if c.UnreadCount != o.UnreadCount {
|
||||
return false
|
||||
}
|
||||
|
||||
if c.LastMessagePreview != o.LastMessagePreview {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(c.Participants) != len(o.Participants) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, p := range c.Participants {
|
||||
if p != o.Participants[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if c.DisplayName != nil && o.DisplayName != nil {
|
||||
if *c.DisplayName != *o.DisplayName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
53
mock/model/date.go
Normal file
53
mock/model/date.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Date time.Time
|
||||
|
||||
func (d Date) Equal(other Date) bool {
|
||||
// usec and nsec are lost in ISO8601 conversion
|
||||
dr := time.Time(d).Round(time.Minute)
|
||||
or := time.Time(other).Round(time.Minute)
|
||||
|
||||
return dr.Equal(or)
|
||||
}
|
||||
|
||||
func (d Date) After(other Date) bool {
|
||||
return time.Time(d).After(time.Time(other))
|
||||
}
|
||||
|
||||
func (d Date) Before(other Date) bool {
|
||||
return time.Time(d).Before(time.Time(other))
|
||||
}
|
||||
|
||||
func (d Date) Format(layout string) string {
|
||||
return time.Time(d).Format(layout)
|
||||
}
|
||||
|
||||
func (d Date) MarshalJSON() ([]byte, error) {
|
||||
// Must use ISO8601
|
||||
formatted := fmt.Sprintf("\"%s\"", time.Time(d).Format("2006-01-02T15:04:05+00:00"))
|
||||
return []byte(formatted), nil
|
||||
}
|
||||
|
||||
func (d *Date) UnmarshalJSON(data []byte) error {
|
||||
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
|
||||
return errors.New("Time.UnmarshalJSON: input is not a JSON string")
|
||||
}
|
||||
|
||||
data = data[len(`"`) : len(data)-len(`"`)]
|
||||
|
||||
var err error
|
||||
var t time.Time
|
||||
t, err = time.ParseInLocation("2006-01-02T15:04:05+00:00", string(data), time.Now().Location())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*d = Date(t)
|
||||
return nil
|
||||
}
|
||||
35
mock/model/message.go
Normal file
35
mock/model/message.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Text string `json:"text"`
|
||||
Guid string `json:"guid"`
|
||||
Sender *string `json:"sender,omitempty"` // Optional: nil means from "me"
|
||||
Date Date `json:"date"`
|
||||
|
||||
// Map of attachment GUID to attachment metadata
|
||||
AttachmentGUIDs []string `json:"fileTransferGUIDs,omitempty"`
|
||||
AttachmentMetadata *map[string]AttributionInfo `json:"attachmentMetadata,omitempty"` // Optional
|
||||
}
|
||||
|
||||
type AttributionInfo struct {
|
||||
ThumbnailWidth int `json:"pgensw"`
|
||||
ThumbnailHeight int `json:"pgensh"`
|
||||
}
|
||||
|
||||
func (c Message) MarshalZerologObject(e *zerolog.Event) {
|
||||
e.Str("guid", c.Guid)
|
||||
e.Str("text", c.Text)
|
||||
e.Time("date", time.Time(c.Date))
|
||||
|
||||
if c.Sender != nil {
|
||||
e.Str("sender", *c.Sender)
|
||||
} else {
|
||||
e.Str("sender", "(Me)")
|
||||
}
|
||||
}
|
||||
26
mock/model/update.go
Normal file
26
mock/model/update.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package model
|
||||
|
||||
import "github.com/rs/zerolog"
|
||||
|
||||
type UpdateItem struct {
|
||||
MessageSequenceNumber int `json:"messageSequenceNumber"`
|
||||
Conversation *Conversation `json:"conversation,omitempty"`
|
||||
Message *Message `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func New(conversation *Conversation, message *Message) *UpdateItem {
|
||||
return &UpdateItem{
|
||||
Conversation: conversation,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *UpdateItem) MarshalZerologObject(e *zerolog.Event) {
|
||||
e.Int("messageSequenceNumber", i.MessageSequenceNumber)
|
||||
if i.Conversation != nil {
|
||||
e.Object("conversation", i.Conversation)
|
||||
}
|
||||
if i.Message != nil {
|
||||
e.Object("message", i.Message)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user