Skip to content
Snippets Groups Projects
Unverified Commit f219243e authored by Kali Kaneko's avatar Kali Kaneko
Browse files

[feat] naive motd json format implementation

parent d4313f27
Branches
Tags
No related merge requests found
motd-cli
MOTD (message of the day)
=========================
This is a stub until a more sophisticated motd mechanism can be implemented in
the future, with better platform integration.
Providers can opt-in to the motd feature (only riseup is using it at the moment).
If motd is enabled for a given provider, the client will attempt to fetch
the motd.json file from a well-known URL, and will display the first valid
message on the splash screen.
The structure of the `motd.json` file is like follows:
```
{
"motd": [{
"begin": "Jan 1 2021 00:00:00",
"end": "Dec 31 2021 23:59:00",
"type": "daily",
"platform": "all",
"text": [
{ "lang": "en",
"str": "This is a <a href='https://leap.se'>test!</a>"},
{ "lang": "es",
"str": "Esto es una <a href='https://leap.se'>pruebita!</a>"}
]}
]
}
```
Valid values are:
* Begin, End are date strings, like "Jan 1 2021 00:00:00".
* Type: "once" for a one-shot message, "daily" for a message that is displayed daily during the specified duration.
* Platform: one of "windows", "linux", "osx" or "all".
The text message can contain links.
You can use the `motd-cli` tool to parse and validate the json:
```
❯ ./motd-cli
file: motd-example.json
count: 1
Message 1 ✓
-----------
Type: daily ✓
Platform: all ✓
Languages: 2 ✓
```
Notes: I'm considering adding an explicit layer of verification of the motd
payload. Please comment on
[#554](https://0xacab.org/leap/bitmask-vpn/-/issues/554) if you have an opinion
on this.
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
)
const defaultFile = "motd-example.json"
const OK = "✓"
const WRONG = "☓"
/* TODO move structs to pkg/config/motd module, import from there */
type Messages struct {
Messages []Message `json:"motd"`
}
func (m *Messages) Length() int {
return len(m.Messages)
}
type Message struct {
Begin string `json:"begin"`
End string `json:"end"`
Type string `json:"type"`
Platform string `json:"platform"`
Text []LocalizedText `json:"text"`
}
func (m *Message) IsValid() bool {
valid := (m.IsValidBegin() && m.IsValidEnd() &&
m.IsValidType() && m.IsValidPlatform() && m.HasLocalizedText())
return valid
}
func (m *Message) IsValidBegin() bool {
return true
}
func (m *Message) IsValidEnd() bool {
return true
}
func (m *Message) IsValidType() bool {
switch m.Type {
case "once", "daily":
return true
default:
return false
}
}
func (m *Message) IsValidPlatform() bool {
switch m.Platform {
case "windows", "linux", "osx", "all":
return true
default:
return false
}
}
func (m *Message) HasLocalizedText() bool {
return true
}
type LocalizedText struct {
Lang string `json:"lang"`
Str string `json:"str"`
}
func main() {
// TODO pass url flag too, to fetch and validate remote file
file := flag.String("file", "", "file to validate")
flag.Parse()
f := *file
if f == "" {
f = defaultFile
}
fmt.Println("file:", f)
m := parseFile(f)
fmt.Printf("count: %v\n", m.Length())
fmt.Println()
for i, msg := range m.Messages {
fmt.Printf("Message %d %v\n-----------\n", i+1, mark(msg.IsValid()))
fmt.Printf("Type: %s %v\n", msg.Type, mark(msg.IsValidType()))
fmt.Printf("Platform: %s %v\n", msg.Platform, mark(msg.IsValidPlatform()))
fmt.Printf("Languages: %d %v\n", len(msg.Text), mark(msg.HasLocalizedText()))
if !msg.IsValid() {
os.Exit(1)
}
}
}
func parseFile(f string) Messages {
jsonFile, err := os.Open(f)
if err != nil {
panic(err)
}
defer jsonFile.Close()
byteVal, err := ioutil.ReadAll(jsonFile)
if err != nil {
panic(err)
}
var m Messages
json.Unmarshal(byteVal, &m)
return m
}
func mark(val bool) string {
if val {
return OK
} else {
return WRONG
}
}
{
"motd": [{
"begin": "Jan 1 2021 00:00:00",
"end": "Dec 31 2021 23:59:00",
"type": "daily",
"platform": "all",
"text": [
{ "lang": "en",
"str": "This is a <a href='https://leap.se'>test!</a>"},
{ "lang": "es",
"str": "Esto es una <a href='https://leap.se'>pruebita!</a>"}
]}
]
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment