1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
package main
import (
"context"
"flag"
"fmt"
"net"
"os"
"strconv"
"time"
"github.com/ProtonMail/gluon"
"github.com/ProtonMail/gluon/connector"
"github.com/ProtonMail/gluon/imap"
"github.com/pkg/profile"
"github.com/sirupsen/logrus"
)
var (
cpuProfileFlag = flag.Bool("profile-cpu", false, "Enable CPU profiling.")
memProfileFlag = flag.Bool("profile-mem", false, "Enable Memory profiling.")
blockProfileFlag = flag.Bool("profile-lock", false, "Enable lock profiling.")
profilePathFlag = flag.String("profile-path", "", "Path where to write profile data.")
)
func main() {
ctx := context.Background()
flag.Parse()
if *cpuProfileFlag {
p := profile.Start(profile.CPUProfile, profile.ProfilePath(*profilePathFlag))
defer p.Stop()
}
if *memProfileFlag {
p := profile.Start(profile.MemProfile, profile.MemProfileAllocs, profile.ProfilePath(*profilePathFlag))
defer p.Stop()
}
if *blockProfileFlag {
p := profile.Start(profile.BlockProfile, profile.ProfilePath(*profilePathFlag))
defer p.Stop()
}
if level, err := logrus.ParseLevel(os.Getenv("GLUON_LOG_LEVEL")); err == nil {
logrus.SetLevel(level)
}
server, err := gluon.New(
gluon.WithLogger(
logrus.StandardLogger().WriterLevel(logrus.TraceLevel),
logrus.StandardLogger().WriterLevel(logrus.TraceLevel),
),
gluon.WithDataDir(os.Getenv("GLUON_DIR")),
gluon.WithDatabaseDir(os.Getenv("GLUON_DIR")),
)
if err != nil {
logrus.WithError(err).Fatal("Failed to create server")
}
defer server.Close(ctx)
nUsers := 2
if envUsers, err := strconv.Atoi(os.Getenv("GLUON_USER_COUNT")); err == nil {
nUsers = envUsers
}
for i := 1; i <= nUsers; i++ {
if err := addUser(ctx, server, []string{
fmt.Sprintf("user%d@example.com", i),
fmt.Sprintf("alias%d@example.com", i),
}, []byte("pass")); err != nil {
logrus.WithError(err).Fatal("Failed to add user")
}
}
host := "localhost:1143"
if envHost := os.Getenv("GLUON_HOST"); envHost != "" {
host = envHost
}
listener, err := net.Listen("tcp", host)
if err != nil {
logrus.WithError(err).Fatal("Failed to listen")
}
logrus.Infof("Server is listening on %v", listener.Addr())
if err := server.Serve(ctx, listener); err != nil {
logrus.WithError(err).Fatal("Failed to serve")
}
for err := range server.GetErrorCh() {
logrus.WithError(err).Error("Error while serving")
}
if err := listener.Close(); err != nil {
logrus.WithError(err).Error("Failed to close listener")
}
}
func addUser(ctx context.Context, server *gluon.Server, addresses []string, password []byte) error {
connector := connector.NewDummy(
addresses,
password,
time.Second,
imap.NewFlagSet(`\Answered`, `\Seen`, `\Flagged`, `\Deleted`),
imap.NewFlagSet(`\Answered`, `\Seen`, `\Flagged`, `\Deleted`),
imap.NewFlagSet(),
)
userID, err := server.AddUser(
ctx,
connector,
password,
)
if err != nil {
return err
}
if err := connector.Sync(ctx); err != nil {
return err
}
logrus.WithField("userID", userID).Info("User added to server")
return nil
}
|