mirror of
https://github.com/directorz/mailfull-go.git
synced 2025-12-20 11:07:02 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46cf349015 | ||
|
|
9be507565d | ||
|
|
58b4e49fe8 | ||
|
|
cb6e9ce2c5 | ||
|
|
db554a1da1 | ||
|
|
708e132ccc | ||
|
|
3a1d4a588c | ||
|
|
50d429ad78 | ||
|
|
0118652074 | ||
|
|
bf4b63556a | ||
|
|
24ee3c26b0 | ||
|
|
49dd05f3bf | ||
|
|
009ee84e63 | ||
|
|
281d5a4a9d | ||
|
|
c2dca41057 | ||
|
|
4f99f11732 |
6
Gomfile
6
Gomfile
@@ -1,6 +0,0 @@
|
||||
gom 'github.com/BurntSushi/toml'
|
||||
gom 'github.com/armon/go-radix'
|
||||
gom 'github.com/bgentry/speakeasy'
|
||||
gom 'github.com/jsimonetti/pwscheme'
|
||||
gom 'github.com/mattn/go-isatty'
|
||||
gom 'github.com/mitchellh/cli'
|
||||
12
Makefile
12
Makefile
@@ -10,20 +10,20 @@ VERSION=$(patsubst "%",%,$(lastword $(shell grep 'const Version' version.go)))
|
||||
default: build
|
||||
|
||||
installdeps:
|
||||
gom install
|
||||
glide install -v
|
||||
|
||||
build:
|
||||
go build -ldflags "-X main.gittag=`git rev-parse --short HEAD`" -v -o build/mailfull_$(GOOS)_$(GOARCH)/mailfull cmd/mailfull/main.go
|
||||
go build -v -ldflags "-X main.gittag=`git rev-parse --short HEAD`" -o build/mailfull_$(GOOS)_$(GOARCH)/mailfull cmd/mailfull/mailfull.go
|
||||
|
||||
build-linux-amd64:
|
||||
docker run --rm -v $(PWD):/go/src/github.com/directorz/mailfull-go -w /go/src/github.com/directorz/mailfull-go \
|
||||
-e GOOS=linux -e GOARCH=amd64 golang:1.7 \
|
||||
go build -ldflags "-X main.gittag=`git rev-parse --short HEAD`" -v -o "build/mailfull_linux_amd64/mailfull" cmd/mailfull/main.go
|
||||
-e GOOS=linux -e GOARCH=amd64 golang:1.7.1 \
|
||||
go build -v -ldflags "-X main.gittag=`git rev-parse --short HEAD`" -o "build/mailfull_linux_amd64/mailfull" cmd/mailfull/mailfull.go
|
||||
|
||||
build-linux-386:
|
||||
docker run --rm -v $(PWD):/go/src/github.com/directorz/mailfull-go -w /go/src/github.com/directorz/mailfull-go \
|
||||
-e GOOS=linux -e GOARCH=386 golang:1.7 \
|
||||
go build -ldflags "-X main.gittag=`git rev-parse --short HEAD`" -v -o "build/mailfull_linux_386/mailfull" cmd/mailfull/main.go
|
||||
-e GOOS=linux -e GOARCH=386 golang:1.7.1 \
|
||||
go build -v -ldflags "-X main.gittag=`git rev-parse --short HEAD`" -o "build/mailfull_linux_386/mailfull" cmd/mailfull/mailfull.go
|
||||
|
||||
release: release-linux-amd64 release-linux-386
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ Features
|
||||
Installation
|
||||
------------
|
||||
|
||||
### Binary
|
||||
|
||||
You can download archive file from [releases page](https://github.com/directorz/mailfull-go/releases) .
|
||||
Download and unpack the archive file, and put the binary file to somewhere you want.
|
||||
|
||||
### go get
|
||||
|
||||
Installed in `$GOPATH/bin`
|
||||
|
||||
@@ -20,7 +20,7 @@ func (c *AliasDomainAddCommand) Synopsis() string {
|
||||
func (c *AliasDomainAddCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s domain target
|
||||
%s %s [-n] domain target
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -30,6 +30,10 @@ Required Args:
|
||||
The domain name that you want to create.
|
||||
target
|
||||
The target domain name.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -39,6 +43,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *AliasDomainAddCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 2 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -64,6 +74,10 @@ func (c *AliasDomainAddCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (c *AliasDomainDelCommand) Synopsis() string {
|
||||
func (c *AliasDomainDelCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s domain
|
||||
%s %s [-n] domain
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -28,6 +28,10 @@ Description:
|
||||
Required Args:
|
||||
domain
|
||||
The domain name that you want to delete.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -37,6 +41,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *AliasDomainDelCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -55,6 +65,10 @@ func (c *AliasDomainDelCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -21,7 +21,7 @@ func (c *AliasUserAddCommand) Synopsis() string {
|
||||
func (c *AliasUserAddCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s address target [target...]
|
||||
%s %s [-n] address target [target...]
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -31,6 +31,10 @@ Required Args:
|
||||
The email address that you want to create.
|
||||
target
|
||||
Target email addresses.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -40,6 +44,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *AliasUserAddCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) < 2 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -73,6 +83,10 @@ func (c *AliasUserAddCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -21,7 +21,7 @@ func (c *AliasUserDelCommand) Synopsis() string {
|
||||
func (c *AliasUserDelCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s address
|
||||
%s %s [-n] address
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -29,6 +29,10 @@ Description:
|
||||
Required Args:
|
||||
address
|
||||
The email address that you want to delete.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -38,6 +42,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *AliasUserDelCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -63,6 +73,10 @@ func (c *AliasUserDelCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -21,7 +21,7 @@ func (c *AliasUserModCommand) Synopsis() string {
|
||||
func (c *AliasUserModCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s address target [target...]
|
||||
%s %s [-n] address target [target...]
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -31,6 +31,10 @@ Required Args:
|
||||
The email address that you want to modify.
|
||||
target
|
||||
Target email addresses.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -40,6 +44,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *AliasUserModCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) < 2 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -82,6 +92,10 @@ func (c *AliasUserModCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (c *CatchAllSetCommand) Synopsis() string {
|
||||
func (c *CatchAllSetCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s domain user
|
||||
%s %s [-n] domain user
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -30,6 +30,10 @@ Required Args:
|
||||
The domain name.
|
||||
user
|
||||
The user name that you want to set as catchall user.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -39,6 +43,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *CatchAllSetCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 2 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -64,6 +74,10 @@ func (c *CatchAllSetCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (c *CatchAllUnsetCommand) Synopsis() string {
|
||||
func (c *CatchAllUnsetCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s domain
|
||||
%s %s [-n] domain
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -28,6 +28,10 @@ Description:
|
||||
Required Args:
|
||||
domain
|
||||
The domain name.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -37,6 +41,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *CatchAllUnsetCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -55,6 +65,10 @@ func (c *CatchAllUnsetCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (c *DomainAddCommand) Synopsis() string {
|
||||
func (c *DomainAddCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s domain
|
||||
%s %s [-n] domain
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -28,6 +28,10 @@ Description:
|
||||
Required Args:
|
||||
domain
|
||||
The domain name that you want to create.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -37,6 +41,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *DomainAddCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -72,6 +82,10 @@ func (c *DomainAddCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (c *DomainDelCommand) Synopsis() string {
|
||||
func (c *DomainDelCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s domain
|
||||
%s %s [-n] domain
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -28,6 +28,10 @@ Description:
|
||||
Required Args:
|
||||
domain
|
||||
The domain name that you want to delete.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -37,6 +41,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *DomainDelCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -55,6 +65,10 @@ func (c *DomainDelCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
97
cmd/mailfull/command/domaindisable.go
Normal file
97
cmd/mailfull/command/domaindisable.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/directorz/mailfull-go"
|
||||
)
|
||||
|
||||
// DomainDisableCommand represents a DomainDisableCommand.
|
||||
type DomainDisableCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
// Synopsis returns a one-line synopsis.
|
||||
func (c *DomainDisableCommand) Synopsis() string {
|
||||
return "Disable a domain temporarily."
|
||||
}
|
||||
|
||||
// Help returns long-form help text.
|
||||
func (c *DomainDisableCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s [-n] domain
|
||||
|
||||
Description:
|
||||
%s
|
||||
|
||||
Required Args:
|
||||
domain
|
||||
The domain name that you want to disable.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
|
||||
return txt[1:]
|
||||
}
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *DomainDisableCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
domainName := args[0]
|
||||
|
||||
repo, err := mailfull.OpenRepository(".")
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
domain, err := repo.Domain(domainName)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
if domain == nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", mailfull.ErrDomainNotExist)
|
||||
return 1
|
||||
}
|
||||
|
||||
domain.SetDisabled(true)
|
||||
|
||||
if err := repo.DomainUpdate(domain); err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
err = repo.GenerateDatabases(mailData)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
97
cmd/mailfull/command/domainenable.go
Normal file
97
cmd/mailfull/command/domainenable.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/directorz/mailfull-go"
|
||||
)
|
||||
|
||||
// DomainEnableCommand represents a DomainEnableCommand.
|
||||
type DomainEnableCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
// Synopsis returns a one-line synopsis.
|
||||
func (c *DomainEnableCommand) Synopsis() string {
|
||||
return "Enable a domain."
|
||||
}
|
||||
|
||||
// Help returns long-form help text.
|
||||
func (c *DomainEnableCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s [-n] domain
|
||||
|
||||
Description:
|
||||
%s
|
||||
|
||||
Required Args:
|
||||
domain
|
||||
The domain name that you want to enable.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
|
||||
return txt[1:]
|
||||
}
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *DomainEnableCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
domainName := args[0]
|
||||
|
||||
repo, err := mailfull.OpenRepository(".")
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
domain, err := repo.Domain(domainName)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
if domain == nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", mailfull.ErrDomainNotExist)
|
||||
return 1
|
||||
}
|
||||
|
||||
domain.SetDisabled(false)
|
||||
|
||||
if err := repo.DomainUpdate(domain); err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
err = repo.GenerateDatabases(mailData)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -25,6 +25,7 @@ Usage:
|
||||
|
||||
Description:
|
||||
%s
|
||||
Disabled domains are marked "!" the beginning.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -48,7 +49,12 @@ func (c *DomainsCommand) Run(args []string) int {
|
||||
sort.Sort(mailfull.DomainSlice(domains))
|
||||
|
||||
for _, domain := range domains {
|
||||
fmt.Fprintf(c.UI.Writer, "%s\n", domain.Name())
|
||||
disableStr := ""
|
||||
if domain.Disabled() {
|
||||
disableStr = "!"
|
||||
}
|
||||
|
||||
fmt.Fprintf(c.UI.Writer, "%s%s\n", disableStr, domain.Name())
|
||||
}
|
||||
|
||||
return 0
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
@@ -11,3 +14,17 @@ type Meta struct {
|
||||
SubCmdName string
|
||||
Version string
|
||||
}
|
||||
|
||||
// noCommitFlag returns true if `pargs` has "-n" flag.
|
||||
// `pargs` is overwrites with non-flag arguments.
|
||||
func noCommitFlag(pargs *[]string) (bool, error) {
|
||||
nFlag := false
|
||||
|
||||
flagSet := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
flagSet.SetOutput(&bytes.Buffer{})
|
||||
flagSet.BoolVar(&nFlag, "n", nFlag, "")
|
||||
err := flagSet.Parse(*pargs)
|
||||
*pargs = flagSet.Args()
|
||||
|
||||
return nFlag, err
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func (c *UserAddCommand) Synopsis() string {
|
||||
func (c *UserAddCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s address
|
||||
%s %s [-n] address
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -29,6 +29,10 @@ Description:
|
||||
Required Args:
|
||||
address
|
||||
The email address that you want to create.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -38,6 +42,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *UserAddCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -70,6 +80,10 @@ func (c *UserAddCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -34,7 +34,7 @@ Required Args:
|
||||
Optional Args:
|
||||
password
|
||||
Specify the password instead of your typing.
|
||||
This option is not recommended because the password will be visible in your shell history.
|
||||
This option is NOT recommended because the password will be visible in your shell history.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
|
||||
@@ -21,7 +21,7 @@ func (c *UserDelCommand) Synopsis() string {
|
||||
func (c *UserDelCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s address
|
||||
%s %s [-n] address
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -29,6 +29,10 @@ Description:
|
||||
Required Args:
|
||||
address
|
||||
The email address that you want to delete.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -38,6 +42,12 @@ Required Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *UserDelCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -69,6 +79,10 @@ func (c *UserDelCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -22,7 +22,7 @@ func (c *UserPasswdCommand) Synopsis() string {
|
||||
func (c *UserPasswdCommand) Help() string {
|
||||
txt := fmt.Sprintf(`
|
||||
Usage:
|
||||
%s %s address [password]
|
||||
%s %s [-n] address [password]
|
||||
|
||||
Description:
|
||||
%s
|
||||
@@ -32,9 +32,11 @@ Required Args:
|
||||
The email address that you want to update the password.
|
||||
|
||||
Optional Args:
|
||||
-n
|
||||
Don't update databases.
|
||||
password
|
||||
Specify the password instead of your typing.
|
||||
This option is not recommended because the password will be visible in your shell history.
|
||||
This option is NOT recommended because the password will be visible in your shell history.
|
||||
`,
|
||||
c.CmdName, c.SubCmdName,
|
||||
c.Synopsis())
|
||||
@@ -44,6 +46,12 @@ Optional Args:
|
||||
|
||||
// Run runs the command and returns the exit status.
|
||||
func (c *UserPasswdCommand) Run(args []string) int {
|
||||
noCommit, err := noCommitFlag(&args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(args) != 1 && len(args) != 2 {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "%v\n", c.Help())
|
||||
return 1
|
||||
@@ -115,6 +123,10 @@ func (c *UserPasswdCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
if noCommit {
|
||||
return 0
|
||||
}
|
||||
|
||||
mailData, err := repo.MailData()
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.UI.ErrorWriter, "[ERR] %v\n", err)
|
||||
|
||||
@@ -62,6 +62,14 @@ func main() {
|
||||
meta.SubCmdName = c.Subcommand()
|
||||
return &command.DomainDelCommand{Meta: meta}, nil
|
||||
},
|
||||
"domaindisable": func() (cli.Command, error) {
|
||||
meta.SubCmdName = c.Subcommand()
|
||||
return &command.DomainDisableCommand{Meta: meta}, nil
|
||||
},
|
||||
"domainenable": func() (cli.Command, error) {
|
||||
meta.SubCmdName = c.Subcommand()
|
||||
return &command.DomainEnableCommand{Meta: meta}, nil
|
||||
},
|
||||
"aliasdomains": func() (cli.Command, error) {
|
||||
meta.SubCmdName = c.Subcommand()
|
||||
return &command.AliasDomainsCommand{Meta: meta}, nil
|
||||
1
const.go
1
const.go
@@ -5,6 +5,7 @@ const (
|
||||
DirNameConfig = ".mailfull"
|
||||
FileNameConfig = "config"
|
||||
|
||||
FileNameDomainDisable = ".vdomaindisable"
|
||||
FileNameAliasDomains = ".valiasdomains"
|
||||
FileNameUsersPassword = ".vpasswd"
|
||||
FileNameUserForwards = ".forward"
|
||||
|
||||
24
database.go
24
database.go
@@ -70,6 +70,10 @@ func (r *Repository) generateDbDomains(md *MailData) error {
|
||||
defer dbDomains.Close()
|
||||
|
||||
for _, domain := range md.Domains {
|
||||
if domain.Disabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(dbDomains, "%s virtual\n", domain.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -95,6 +99,10 @@ func (r *Repository) generateDbDestinations(md *MailData) error {
|
||||
defer dbDestinations.Close()
|
||||
|
||||
for _, domain := range md.Domains {
|
||||
if domain.Disabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
// ho-ge.example.com -> ho_ge.example.com
|
||||
underscoredDomainName := domain.Name()
|
||||
underscoredDomainName = strings.Replace(underscoredDomainName, `-`, `_`, -1)
|
||||
@@ -153,6 +161,10 @@ func (r *Repository) generateDbMaildirs(md *MailData) error {
|
||||
defer dbMaildirs.Close()
|
||||
|
||||
for _, domain := range md.Domains {
|
||||
if domain.Disabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, user := range domain.Users {
|
||||
if _, err := fmt.Fprintf(dbMaildirs, "%s@%s %s/%s/Maildir/\n", user.Name(), domain.Name(), domain.Name(), user.Name()); err != nil {
|
||||
return err
|
||||
@@ -174,6 +186,10 @@ func (r *Repository) generateDbLocaltable(md *MailData) error {
|
||||
defer dbLocaltable.Close()
|
||||
|
||||
for _, domain := range md.Domains {
|
||||
if domain.Disabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
// ho-ge.example.com -> ho_ge\.example\.com
|
||||
escapedDomainName := domain.Name()
|
||||
escapedDomainName = strings.Replace(escapedDomainName, `-`, `_`, -1)
|
||||
@@ -198,6 +214,10 @@ func (r *Repository) generateDbForwards(md *MailData) error {
|
||||
defer dbForwards.Close()
|
||||
|
||||
for _, domain := range md.Domains {
|
||||
if domain.Disabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
// ho-ge.example.com -> ho_ge.example.com
|
||||
underscoredDomainName := domain.Name()
|
||||
underscoredDomainName = strings.Replace(underscoredDomainName, `-`, `_`, -1)
|
||||
@@ -234,6 +254,10 @@ func (r *Repository) generateDbPasswords(md *MailData) error {
|
||||
defer dbPasswords.Close()
|
||||
|
||||
for _, domain := range md.Domains {
|
||||
if domain.Disabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, user := range domain.Users {
|
||||
if _, err := fmt.Fprintf(dbPasswords, "%s@%s:%s\n", user.Name(), domain.Name(), user.HashedPassword()); err != nil {
|
||||
return err
|
||||
|
||||
121
domain.go
121
domain.go
@@ -11,6 +11,7 @@ import (
|
||||
// Domain represents a Domain.
|
||||
type Domain struct {
|
||||
name string
|
||||
disabled bool
|
||||
Users []*User
|
||||
AliasUsers []*AliasUser
|
||||
CatchAllUser *CatchAllUser
|
||||
@@ -25,22 +26,41 @@ func (p DomainSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// NewDomain creates a new Domain instance.
|
||||
func NewDomain(name string) (*Domain, error) {
|
||||
if !validDomainName(name) {
|
||||
return nil, ErrInvalidDomainName
|
||||
}
|
||||
d := &Domain{}
|
||||
|
||||
d := &Domain{
|
||||
name: name,
|
||||
if err := d.setName(name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// setName sets the name.
|
||||
func (d *Domain) setName(name string) error {
|
||||
if !validDomainName(name) {
|
||||
return ErrInvalidDomainName
|
||||
}
|
||||
|
||||
d.name = name
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns name.
|
||||
func (d *Domain) Name() string {
|
||||
return d.name
|
||||
}
|
||||
|
||||
// SetDisabled disables the Domain if the input is true.
|
||||
func (d *Domain) SetDisabled(disabled bool) {
|
||||
d.disabled = disabled
|
||||
}
|
||||
|
||||
// Disabled returns true if the Domain is disabled.
|
||||
func (d *Domain) Disabled() bool {
|
||||
return d.disabled
|
||||
}
|
||||
|
||||
// Domains returns a Domain slice.
|
||||
func (r *Repository) Domains() ([]*Domain, error) {
|
||||
fileInfos, err := ioutil.ReadDir(r.DirMailDataPath)
|
||||
@@ -62,6 +82,12 @@ func (r *Repository) Domains() ([]*Domain, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
disabled, err := r.domainDisabled(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domain.SetDisabled(disabled)
|
||||
|
||||
domains = append(domains, domain)
|
||||
}
|
||||
|
||||
@@ -94,9 +120,38 @@ func (r *Repository) Domain(domainName string) (*Domain, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disabled, err := r.domainDisabled(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domain.SetDisabled(disabled)
|
||||
|
||||
return domain, nil
|
||||
}
|
||||
|
||||
// domainDisabled returns true if the input Domain is disabled.
|
||||
func (r *Repository) domainDisabled(domainName string) (bool, error) {
|
||||
if !validDomainName(domainName) {
|
||||
return false, ErrInvalidDomainName
|
||||
}
|
||||
|
||||
fi, err := os.Stat(filepath.Join(r.DirMailDataPath, domainName, FileNameDomainDisable))
|
||||
|
||||
if err != nil {
|
||||
if err.(*os.PathError).Err == syscall.ENOENT {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
return false, ErrInvalidFormatDomainDisabled
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// DomainCreate creates the input Domain.
|
||||
func (r *Repository) DomainCreate(domain *Domain) error {
|
||||
existDomain, err := r.Domain(domain.Name())
|
||||
@@ -150,6 +205,29 @@ func (r *Repository) DomainCreate(domain *Domain) error {
|
||||
}
|
||||
catchAllUserFile.Close()
|
||||
|
||||
if domain.Disabled() {
|
||||
if err := r.writeDomainDisabledFile(domain.Name(), domain.Disabled()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DomainUpdate updates the input Domain.
|
||||
func (r *Repository) DomainUpdate(domain *Domain) error {
|
||||
existDomain, err := r.Domain(domain.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existDomain == nil {
|
||||
return ErrDomainNotExist
|
||||
}
|
||||
|
||||
if err := r.writeDomainDisabledFile(domain.Name(), domain.Disabled()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -182,3 +260,36 @@ func (r *Repository) DomainRemove(domainName string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeDomainDisabledFile creates/removes the disabled file.
|
||||
func (r *Repository) writeDomainDisabledFile(domainName string, disabled bool) error {
|
||||
if !validDomainName(domainName) {
|
||||
return ErrInvalidDomainName
|
||||
}
|
||||
|
||||
nowDisabled, err := r.domainDisabled(domainName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
domainDisabledFileName := filepath.Join(r.DirMailDataPath, domainName, FileNameDomainDisable)
|
||||
|
||||
if !nowDisabled && disabled {
|
||||
file, err := os.OpenFile(domainDisabledFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.Chown(r.uid, r.gid); err != nil {
|
||||
return err
|
||||
}
|
||||
file.Close()
|
||||
}
|
||||
|
||||
if nowDisabled && !disabled {
|
||||
if err := os.Remove(domainDisabledFileName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
22
glide.lock
generated
Normal file
22
glide.lock
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
hash: 451657f03f297af9163863497cf6c2f60abfe12d88a282f5aab6deb865d91119
|
||||
updated: 2016-09-29T12:05:32.00075722+09:00
|
||||
imports:
|
||||
- name: github.com/armon/go-radix
|
||||
version: 4239b77079c7b5d1243b7b4736304ce8ddb6f0f2
|
||||
- name: github.com/bgentry/speakeasy
|
||||
version: a1ccbf2c40dfc8ce514b5c5c6e6d1429ea6880da
|
||||
- name: github.com/BurntSushi/toml
|
||||
version: 99064174e013895bbd9b025c31100bd1d9b590ca
|
||||
- name: github.com/jsimonetti/pwscheme
|
||||
version: 76804708ecad54773871b35dbaa44f517973e395
|
||||
subpackages:
|
||||
- ssha
|
||||
- name: github.com/mattn/go-isatty
|
||||
version: 66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8
|
||||
- name: github.com/mitchellh/cli
|
||||
version: fcf521421aa29bde1d93b6920dfce826d7932208
|
||||
- name: golang.org/x/sys
|
||||
version: 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
|
||||
subpackages:
|
||||
- unix
|
||||
testImports: []
|
||||
7
glide.yaml
Normal file
7
glide.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
package: github.com/directorz/mailfull-go
|
||||
import:
|
||||
- package: github.com/BurntSushi/toml
|
||||
- package: github.com/jsimonetti/pwscheme
|
||||
subpackages:
|
||||
- ssha
|
||||
- package: github.com/mitchellh/cli
|
||||
@@ -34,6 +34,7 @@ var (
|
||||
ErrAliasUserNotExist = errors.New("AliasUser: not exist")
|
||||
ErrAliasUserAlreadyExist = errors.New("AliasUser: already exist")
|
||||
|
||||
ErrInvalidFormatDomainDisabled = errors.New("Domain: disabled file invalid format")
|
||||
ErrInvalidFormatUsersPassword = errors.New("User: password file invalid format")
|
||||
ErrInvalidFormatAliasDomain = errors.New("AliasDomain: file invalid format")
|
||||
ErrInvalidFormatAliasUsers = errors.New("AliasUsers: file invalid format")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package mailfull
|
||||
|
||||
// Version is a version number.
|
||||
const Version = "v0.0.3"
|
||||
const Version = "v0.0.6"
|
||||
|
||||
Reference in New Issue
Block a user