-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
L11R
committed
Nov 29, 2018
0 parents
commit e4fb656
Showing
10 changed files
with
421 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# jetbrains goland | ||
.idea | ||
|
||
# go modules | ||
go.sum |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# go-autoconfig | ||
IMAP/SMTP autodiscover feature for Thunderbird, Apple Mail and Microsoft Outlook | ||
|
||
You need DNS SRV-record to get work Outlook and Thunderbird: | ||
``` | ||
_autodiscover._tcp IN SRV 0 0 443 autoconfig.example.com. | ||
``` | ||
Of course `autoconfig.example.com` domain should point to your server with this service. | ||
|
||
### Thunderbird | ||
`GET https://autoconfig.example.com/mail/config-v1.1.xml` | ||
|
||
### Apple Mail | ||
`GET https://autoconfig.example.com/email.mobileconfig?email=your@email.com` | ||
|
||
### Outlook | ||
`POST https://autoconfig.example.com/autodiscover/autodiscover.xml` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
service_addr: ":1323" | ||
|
||
domain: lord.sh | ||
|
||
imap: | ||
server: imap.mailbox.org | ||
port: 993 | ||
|
||
smtp: | ||
server: smtp.mailbox.org | ||
port: 465 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package config | ||
|
||
import ( | ||
"gopkg.in/go-playground/validator.v9" | ||
"gopkg.in/yaml.v2" | ||
"io/ioutil" | ||
) | ||
|
||
type Config struct { | ||
ServiceAddr string `yaml:"service_addr"` | ||
|
||
Domain string `yaml:"domain" validate:"required"` | ||
|
||
IMAP *Server `yaml:"imap"` | ||
SMTP *Server `yaml:"smtp"` | ||
} | ||
|
||
type Server struct { | ||
Host string `yaml:"server" validate:"required"` | ||
Port int `yaml:"port" validate:"required"` | ||
STARTTLS bool `yaml:"starttls"` | ||
} | ||
|
||
func NewConfig(p string) (*Config, error) { | ||
b, err := ioutil.ReadFile(p) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var c Config | ||
if err := yaml.Unmarshal(b, &c); err != nil { | ||
return nil, err | ||
} | ||
|
||
validate := validator.New() | ||
if err := validate.Struct(c); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &c, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module go-autoconfig | ||
|
||
require ( | ||
github.com/go-playground/locales v0.12.1 // indirect | ||
github.com/go-playground/universal-translator v0.16.0 // indirect | ||
github.com/labstack/echo v3.3.8+incompatible | ||
github.com/labstack/gommon v0.2.8 // indirect | ||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 // indirect | ||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect | ||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect | ||
gopkg.in/go-playground/validator.v9 v9.23.0 | ||
gopkg.in/yaml.v2 v2.2.2 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package handlers | ||
|
||
import ( | ||
"encoding/xml" | ||
"github.com/labstack/echo" | ||
"go-autoconfig/config" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
type Handler struct { | ||
Config *config.Config | ||
} | ||
|
||
type server struct { | ||
Host string | ||
Port int | ||
STARTTLS bool | ||
} | ||
|
||
func (h *Handler) Outlook(ctx echo.Context) error { | ||
var req struct { | ||
XMLName xml.Name `xml:"Autodiscover"` | ||
Text string `xml:",chardata"` | ||
Xmlns string `xml:"xmlns,attr"` | ||
Request struct { | ||
Text string `xml:",chardata"` | ||
EMailAddress string `xml:"EMailAddress"` | ||
AcceptableResponseSchema string `xml:"AcceptableResponseSchema"` | ||
} `xml:"Request"` | ||
} | ||
|
||
b, err := ioutil.ReadAll(ctx.Request().Body) | ||
if err != nil { | ||
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | ||
} | ||
|
||
if err := xml.Unmarshal(b, &req); err != nil { | ||
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | ||
} | ||
|
||
data := struct { | ||
Schema string | ||
Email string | ||
Domain string | ||
IMAP *server | ||
SMTP *server | ||
}{ | ||
Schema: req.Request.AcceptableResponseSchema, | ||
Email: req.Request.EMailAddress, | ||
Domain: h.Config.Domain, | ||
IMAP: &server{ | ||
Host: h.Config.IMAP.Host, | ||
Port: h.Config.IMAP.Port, | ||
STARTTLS: h.Config.IMAP.STARTTLS, | ||
}, | ||
SMTP: &server{ | ||
Host: h.Config.SMTP.Host, | ||
Port: h.Config.SMTP.Port, | ||
STARTTLS: h.Config.SMTP.STARTTLS, | ||
}, | ||
} | ||
|
||
ctx.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) | ||
return ctx.Render(http.StatusOK, "outlook", data) | ||
} | ||
|
||
func (h *Handler) Thunderbird(ctx echo.Context) error { | ||
data := struct { | ||
Domain string | ||
IMAP *server | ||
SMTP *server | ||
}{ | ||
Domain: h.Config.Domain, | ||
IMAP: &server{ | ||
Host: h.Config.IMAP.Host, | ||
Port: h.Config.IMAP.Port, | ||
STARTTLS: h.Config.IMAP.STARTTLS, | ||
}, | ||
SMTP: &server{ | ||
Host: h.Config.SMTP.Host, | ||
Port: h.Config.SMTP.Port, | ||
STARTTLS: h.Config.SMTP.STARTTLS, | ||
}, | ||
} | ||
|
||
ctx.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) | ||
return ctx.Render(http.StatusOK, "thunderbird", data) | ||
} | ||
|
||
func (h *Handler) AppleMail(ctx echo.Context) error { | ||
var req struct { | ||
Email string `query:"email"` | ||
} | ||
if err := ctx.Bind(&req); err != nil { | ||
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | ||
} | ||
|
||
data := struct { | ||
Email string | ||
Domain string | ||
IMAP *server | ||
SMTP *server | ||
}{ | ||
Email: req.Email, | ||
Domain: h.Config.Domain, | ||
IMAP: &server{ | ||
Host: h.Config.IMAP.Host, | ||
Port: h.Config.IMAP.Port, | ||
}, | ||
SMTP: &server{ | ||
Host: h.Config.SMTP.Host, | ||
Port: h.Config.SMTP.Port, | ||
}, | ||
} | ||
|
||
ctx.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) | ||
return ctx.Render(http.StatusOK, "applemail", data) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package main // import "go-autoconfig" | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"github.com/labstack/echo" | ||
"github.com/labstack/echo/middleware" | ||
"go-autoconfig/config" | ||
"go-autoconfig/handlers" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"text/template" | ||
) | ||
|
||
var path = flag.String( | ||
"config", | ||
"", | ||
"enter path to config file", | ||
) | ||
|
||
func main() { | ||
// Parse at first startup | ||
flag.Parse() | ||
|
||
// Read config | ||
conf, err := config.NewConfig(*path) | ||
if err != nil { | ||
fmt.Printf("Incorrect path or config itself! See help.\n%s\n", err.Error()) | ||
os.Exit(2) | ||
} | ||
|
||
tmpl := &Template{ | ||
templates: template.Must(template.ParseGlob(filepath.Join("templates", "*.tmpl"))), | ||
} | ||
|
||
// Init Echo | ||
e := echo.New() | ||
e.Renderer = tmpl | ||
|
||
// Middleware | ||
e.Use(middleware.Logger()) | ||
e.Use(middleware.Recover()) | ||
|
||
// Routes | ||
h := handlers.Handler{conf} | ||
e.POST("/autodiscover/autodiscover.xml", h.Outlook) | ||
e.GET("/mail/config-v1.1.xml", h.Thunderbird) | ||
e.GET("/email.mobileconfig", h.AppleMail) | ||
|
||
// Start server | ||
e.Logger.Fatal(e.Start(conf.ServiceAddr)) | ||
} | ||
|
||
type Template struct { | ||
templates *template.Template | ||
} | ||
|
||
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error { | ||
return t.templates.ExecuteTemplate(w, name, data) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{{define "thunderbird"}}<?xml version="1.0" encoding="UTF-8"?> | ||
<clientConfig version="1.1"> | ||
<emailProvider id="{{ .Domain }}"> | ||
<domain>{{ .Domain }}</domain> | ||
|
||
<displayName>%EMAILADDRESS%</displayName> | ||
<displayShortName>%EMAILLOCALPART%</displayShortName> | ||
|
||
<incomingServer type="imap"> | ||
<hostname>{{ .IMAP.Host }}</hostname> | ||
<port>{{ .IMAP.Port }}</port> | ||
<socketType>{{ if .IMAP.STARTTLS }}STARTTLS{{ else }}SSL{{ end }}</socketType> | ||
<authentication>password-cleartext</authentication> | ||
<username>%EMAILADDRESS%</username> | ||
</incomingServer> | ||
|
||
<outgoingServer type="smtp"> | ||
<hostname>{{ .SMTP.Host }}</hostname> | ||
<port>{{ .SMTP.Port }}</port> | ||
<socketType>{{ if .SMTP.STARTTLS }}STARTTLS{{ else }}SSL{{ end }}</socketType> | ||
<authentication>password-cleartext</authentication> | ||
<username>%EMAILADDRESS%</username> | ||
</outgoingServer> | ||
</emailProvider> | ||
</clientConfig>{{end}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{{ define "outlook" }}<?xml version="1.0" encoding="utf-8"?> | ||
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006"> | ||
<Response xmlns="{{ .Schema }}"> | ||
<User> | ||
<DisplayName>{{ .Email }}</DisplayName> | ||
</User> | ||
|
||
<Account> | ||
<AccountType>email</AccountType> | ||
<Action>settings</Action> | ||
|
||
<Protocol> | ||
<Type>IMAP</Type> | ||
<TTL>1</TTL> | ||
|
||
<Server>{{ .IMAP.Host }}</Server> | ||
<Port>{{ .IMAP.Port }}</Port> | ||
|
||
<LoginName>{{ .Email }}</LoginName> | ||
|
||
<DomainRequired>on</DomainRequired> | ||
<DomainName>{{ .Domain }}</DomainName> | ||
|
||
<SPA>off</SPA> | ||
{{ if .IMAP.STARTTLS }}<TLS>on</TLS>{{ else }}<SSL>on</SSL>{{ end }} | ||
<AuthRequired>on</AuthRequired> | ||
</Protocol> | ||
</Account> | ||
|
||
<Account> | ||
<AccountType>email</AccountType> | ||
<Action>settings</Action> | ||
|
||
<Protocol> | ||
<Type>SMTP</Type> | ||
<TTL>1</TTL> | ||
|
||
<Server>{{ .SMTP.Host }}</Server> | ||
<Port>{{ .SMTP.Port }}</Port> | ||
|
||
<LoginName>{{ .Email }}</LoginName> | ||
|
||
<DomainRequired>on</DomainRequired> | ||
<DomainName>{{ .Domain }}</DomainName> | ||
|
||
<SPA>off</SPA> | ||
{{ if .SMTP.STARTTLS }}<TLS>on</TLS>{{ else }}<SSL>on</SSL>{{ end }} | ||
<AuthRequired>on</AuthRequired> | ||
</Protocol> | ||
</Account> | ||
</Response> | ||
</Autodiscover>{{ end }} |
Oops, something went wrong.