1 // mmc -- Mattermost client
2 // Copyright (C) 2023-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 "github.com/davecgh/go-spew/spew"
29 "github.com/mattermost/mattermost-server/v6/model"
30 "go.cypherpunks.ru/recfile"
36 OutRecLock = "out.rec.lock"
40 var SleepTime = 250 * time.Millisecond
47 func PostToRec(w *recfile.Writer, users map[string]*model.User, post Post) error {
48 _, err := w.RecordStart()
52 created := time.Unix(post.P.CreateAt/1000, 0)
53 user := users[post.P.UserId]
56 sender = user.Username
58 fields := []recfile.Field{
59 {Name: "Id", Value: post.P.Id},
60 {Name: "Created", Value: created.Format("2006-01-02 15:04:05")},
61 {Name: "Sender", Value: sender},
63 if post.E != model.WebsocketEventPosted {
64 fields = append(fields, recfile.Field{Name: "Event", Value: post.E})
66 if post.P.RootId != "" {
67 fields = append(fields, recfile.Field{Name: "RootId", Value: post.P.RootId})
69 if post.P.Metadata != nil {
70 for _, fi := range post.P.Metadata.Files {
73 recfile.Field{Name: "File", Value: fi.Id},
74 recfile.Field{Name: "FileName", Value: fi.Name},
78 if _, err = w.WriteFields(fields...); err != nil {
81 _, err = w.WriteFieldMultiline("Text", strings.Split(post.P.Message, "\n"))
85 func GetUsers(c *model.Client4, debugFd *os.File) (map[string]*model.User, error) {
86 users := make(map[string]*model.User)
89 page, resp, err := c.GetUsers(n, PerPage, "")
92 spew.Fdump(debugFd, resp)
97 spew.Fdump(debugFd, page)
99 for _, u := range page {
102 if len(page) < PerPage {
109 func GetEntrypoint() string {
110 s := os.Getenv("MMC_ENTRYPOINT")
112 return "http://mm.invalid"
117 func GetSPKIHash() string {
118 s := os.Getenv("MMC_SPKI")
125 func NewVerifyPeerCertificate(hashExpected string) func(
126 rawCerts [][]byte, verifiedChains [][]*x509.Certificate,
129 rawCerts [][]byte, verifiedChains [][]*x509.Certificate,
131 cer, err := x509.ParseCertificate(rawCerts[0])
135 spki := cer.RawSubjectPublicKeyInfo
136 hsh := sha256.Sum256(spki)
137 if hashExpected != hex.EncodeToString(hsh[:]) {
138 return errors.New("server certificate's SPKI hash mismatch")