mirror of
https://github.com/mgerb/tmail
synced 2026-01-08 08:52:48 +00:00
init
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
vendor
|
||||
*.db
|
||||
tmail
|
||||
101
Gopkg.lock
generated
Normal file
101
Gopkg.lock
generated
Normal file
@@ -0,0 +1,101 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/asdine/storm"
|
||||
packages = [
|
||||
".",
|
||||
"codec",
|
||||
"codec/json",
|
||||
"index",
|
||||
"internal",
|
||||
"q"
|
||||
]
|
||||
revision = "68fc73b635f890fe7ba2f3b15ce80c85b28a744f"
|
||||
version = "v2.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/coreos/bbolt"
|
||||
packages = ["."]
|
||||
revision = "583e8937c61f1af6513608ccc75c97b6abdf4ff9"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gin-contrib/sse"
|
||||
packages = ["."]
|
||||
revision = "22d885f9ecc78bf4ee5d72b937e4bbcdc58e8cae"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gin-gonic/gin"
|
||||
packages = [
|
||||
".",
|
||||
"binding",
|
||||
"render"
|
||||
]
|
||||
revision = "d459835d2b077e44f7c9b453505ee29881d5d12d"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "925541529c1fa6821df4e44ce2723319eb2be768"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mhale/smtpd"
|
||||
packages = ["."]
|
||||
revision = "1f9c0adefd94a30cab2ffcc25587b90a6b7a50c1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba"
|
||||
version = "v1.0.4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/ugorji/go"
|
||||
packages = ["codec"]
|
||||
revision = "9831f2c3ac1068a78f50999a30db84270f647af6"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
revision = "1875d0a70c90e57f11972aefd42276df65e895b9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "8f27ce8a604014414f8dfffc25cbcde83a3f2216"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/go-playground/validator.v8"
|
||||
packages = ["."]
|
||||
revision = "5f1438d3fca68893a817e4a66806cea46a9e4ebf"
|
||||
version = "v8.18.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "466f07b37f7df05f3425d1710259c615b219c5ebb3bd49dfaa4a1d5520a3804c"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
34
Gopkg.toml
Normal file
34
Gopkg.toml
Normal file
@@ -0,0 +1,34 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mhale/smtpd"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
20
db/db.go
Normal file
20
db/db.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/asdine/storm"
|
||||
)
|
||||
|
||||
var Conn *storm.DB
|
||||
|
||||
func Init() {
|
||||
|
||||
var err error
|
||||
Conn, err = storm.Open("mail.db")
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
22
mail/mail.go
Normal file
22
mail/mail.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"github.com/mgerb/tmail/db"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Mail struct {
|
||||
ID int `storm:"increment" json:"id"`
|
||||
From string `json:"from"`
|
||||
To string `storm:"index" json:"to"`
|
||||
Subject string `json:"subject"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
func (m *Mail) Save() {
|
||||
err := db.Conn.Save(m)
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
37
main.go
Normal file
37
main.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/asdine/storm"
|
||||
"github.com/mgerb/tmail/db"
|
||||
"github.com/mgerb/tmail/smtpserver"
|
||||
"github.com/mgerb/tmail/webserver"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
//DB - database instance
|
||||
var DB *storm.DB
|
||||
|
||||
func init() {
|
||||
// Log as JSON instead of the default ASCII formatter.
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
|
||||
// Output to stdout instead of the default stderr
|
||||
// Can be any io.Writer, see below for File example
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
// Only log the warning severity or above.
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
func main() {
|
||||
db.Init()
|
||||
defer db.Conn.Close()
|
||||
|
||||
// start webserver
|
||||
go webserver.Start()
|
||||
|
||||
// start smtp server
|
||||
smtpserver.Start()
|
||||
}
|
||||
12
readme.md
Normal file
12
readme.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# TMail
|
||||
A throwaway smtp mail server.
|
||||
|
||||
|
||||
## Check email
|
||||
```
|
||||
All mail:
|
||||
http://host:8090/api/mail
|
||||
|
||||
Specific mail:
|
||||
http://host:8090/api/mail?to=<address>
|
||||
```
|
||||
35
smtpserver/smtpserver.go
Normal file
35
smtpserver/smtpserver.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package smtpserver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"net/mail"
|
||||
|
||||
mymail "github.com/mgerb/tmail/mail"
|
||||
"github.com/mhale/smtpd"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
log.Error(smtpd.ListenAndServe("0.0.0.0:25", mailHandler, "tmail", ""))
|
||||
}
|
||||
|
||||
func mailHandler(origin net.Addr, from string, to []string, data []byte) {
|
||||
msg, err := mail.ReadMessage(bytes.NewReader(data))
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
subject := msg.Header.Get("Subject")
|
||||
|
||||
m := &mymail.Mail{
|
||||
Content: string(data),
|
||||
From: from,
|
||||
To: to[0],
|
||||
Subject: subject,
|
||||
}
|
||||
|
||||
m.Save()
|
||||
}
|
||||
30
webserver/webserver.go
Normal file
30
webserver/webserver.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package webserver
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mgerb/tmail/db"
|
||||
"github.com/mgerb/tmail/mail"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
r := gin.Default()
|
||||
r.GET("/api/mail", mailHander)
|
||||
r.Run("0.0.0.0:8090")
|
||||
}
|
||||
|
||||
func mailHander(c *gin.Context) {
|
||||
|
||||
to := c.Query("to")
|
||||
var mail []mail.Mail
|
||||
log.Println(to)
|
||||
|
||||
if to != "" {
|
||||
db.Conn.Find("To", to, &mail)
|
||||
} else {
|
||||
db.Conn.All(&mail)
|
||||
}
|
||||
|
||||
c.JSON(200, mail)
|
||||
}
|
||||
Reference in New Issue
Block a user