-
Notifications
You must be signed in to change notification settings - Fork 0
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
Showing
43 changed files
with
4,400 additions
and
376 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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package web | ||
package api | ||
|
||
import ( | ||
"github.com/labstack/echo/v4" | ||
|
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package web | ||
package api | ||
|
||
import ( | ||
"github.com/golang-jwt/jwt/v5" | ||
|
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,39 @@ | ||
package api | ||
|
||
import ( | ||
"autossl/application" | ||
"github.com/labstack/echo/v4" | ||
) | ||
|
||
func SSLRoutes(e *echo.Echo) { | ||
e.POST("/import", upload) | ||
e.GET("/dl/:code", download) | ||
e.HEAD("/dl/:code", downloadHead) | ||
e.GET("/list", list) | ||
e.POST("/generate", generate) | ||
e.DELETE("/:code", remove) | ||
} | ||
|
||
func upload(c echo.Context) error { | ||
return application.Upload(c) | ||
} | ||
|
||
func download(c echo.Context) error { | ||
return application.Download(c) | ||
} | ||
|
||
func downloadHead(c echo.Context) error { | ||
return application.DownloadHead(c) | ||
} | ||
|
||
func list(c echo.Context) error { | ||
return application.ListCert(c) | ||
} | ||
|
||
func generate(c echo.Context) error { | ||
return application.Generate(c) | ||
} | ||
|
||
func remove(c echo.Context) error { | ||
return application.DeleteCert(c) | ||
} |
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,99 @@ | ||
package application | ||
|
||
import ( | ||
"autossl/domain/model" | ||
"autossl/domain/service" | ||
"autossl/infrastructure/exception" | ||
"autossl/infrastructure/util" | ||
"github.com/labstack/echo/v4" | ||
"net/http" | ||
"path/filepath" | ||
) | ||
|
||
func Generate(c echo.Context) error { | ||
var certCommand *model.CertCommand | ||
if err := c.Bind(&certCommand); err != nil { | ||
return err | ||
} | ||
|
||
// Find the certificate by domain | ||
exist := service.ExistCert(certCommand.Domain) | ||
if exist { | ||
err := exception.CertificateExistsErr(certCommand.Domain) | ||
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | ||
} | ||
|
||
// Create ssl | ||
code := util.GenerateID() | ||
err := service.CreateCert(certCommand.Domain, code) | ||
if err != nil { | ||
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | ||
} | ||
|
||
return c.NoContent(http.StatusOK) | ||
} | ||
|
||
func ListCert(c echo.Context) error { | ||
list, err := service.ListCert() | ||
if err != nil { | ||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) | ||
} | ||
return c.JSON(http.StatusOK, list) | ||
} | ||
|
||
func DeleteCert(c echo.Context) error { | ||
code := c.Param("code") | ||
|
||
err := service.DeleteCert(code) | ||
if err != nil { | ||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) | ||
} | ||
return c.NoContent(http.StatusNoContent) | ||
} | ||
|
||
func Upload(c echo.Context) error { | ||
certFile, err := c.FormFile("cert") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
keyFile, err := c.FormFile("key") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
domainName := c.FormValue("domain") | ||
|
||
err = service.ImportCert(domainName, certFile, keyFile) | ||
if err != nil { | ||
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | ||
} | ||
|
||
return c.NoContent(http.StatusOK) | ||
} | ||
|
||
func Download(c echo.Context) error { | ||
code := c.Param("code") | ||
filePath := filepath.Join(service.CertPath, code) | ||
|
||
etag, err := service.Etag(filePath) | ||
if err != nil { | ||
return err | ||
} | ||
c.Response().Header().Set("ETag", etag) | ||
|
||
return c.File(filePath) | ||
} | ||
|
||
func DownloadHead(c echo.Context) error { | ||
code := c.Param("code") | ||
filePath := filepath.Join(service.CertPath, code) | ||
|
||
etag, err := service.Etag(filePath) | ||
if err != nil { | ||
return err | ||
} | ||
c.Response().Header().Set("ETag", etag) | ||
|
||
return c.NoContent(http.StatusOK) | ||
} |
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package module | ||
package config | ||
|
||
import "github.com/labstack/echo/v4" | ||
|
||
|
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package module | ||
package config | ||
|
||
import ( | ||
"github.com/labstack/echo/v4" | ||
|
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 @@ | ||
package model | ||
|
||
type CertCommand struct { | ||
Domain string `json:"domain"` | ||
Algorithm string `json:"algorithm"` | ||
} | ||
|
||
type Cert struct { | ||
Code string `json:"code"` | ||
Domain string `json:"domain"` | ||
Cert string `json:"cert"` | ||
Key string `json:"key"` | ||
} |
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,12 @@ | ||
package repository | ||
|
||
import ( | ||
"autossl/domain/model" | ||
) | ||
|
||
type CertRepository interface { | ||
Create(cert *model.Cert) error | ||
FindByDomain(domain string) (*model.Cert, error) | ||
List() ([]*model.Cert, error) | ||
Delete(code string) error | ||
} |
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,186 @@ | ||
package service | ||
|
||
import ( | ||
"autossl/domain/model" | ||
"autossl/infrastructure/acme" | ||
"autossl/infrastructure/database" | ||
"autossl/infrastructure/exception" | ||
"autossl/infrastructure/repository" | ||
"autossl/infrastructure/util" | ||
"crypto/md5" | ||
"fmt" | ||
"io" | ||
"mime/multipart" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
var CertPath = "./data/cert" | ||
|
||
func ExistCert(domain string) bool { | ||
repo := &repository.CertRepo{ | ||
Db: database.Init(), | ||
} | ||
|
||
byDomain, err := repo.FindByDomain(domain) | ||
if err != nil { | ||
return false | ||
} | ||
return byDomain != nil | ||
} | ||
|
||
func CreateCert(domain string, code string) error { | ||
err := os.MkdirAll(CertPath, 0755) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = acme.Issue(domain) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = acme.Install(domain, code) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
repo := &repository.CertRepo{ | ||
Db: database.Init(), | ||
} | ||
cert := &model.Cert{ | ||
Code: code, | ||
Domain: domain, | ||
} | ||
err = repo.Create(cert) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func ImportCert(domainName string, certFile *multipart.FileHeader, keyFile *multipart.FileHeader) error { | ||
// checked cert exist | ||
if ExistCert(domainName) { | ||
return exception.CertificateExistsErr(domainName) | ||
} | ||
|
||
code := util.GenerateID() | ||
err := CreateCert(domainName, code) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = uploadFile(code, certFile, keyFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func ListCert() ([]*model.Cert, error) { | ||
repo := &repository.CertRepo{ | ||
Db: database.Init(), | ||
} | ||
list, err := repo.List() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
dm := os.Getenv("DOMAIN") | ||
url := dm + "/dl/" | ||
for _, cert := range list { | ||
certLink := url + cert.Code + ".crt" | ||
keyLink := url + cert.Code + ".key" | ||
cert.Cert = certLink | ||
cert.Key = keyLink | ||
} | ||
|
||
return list, nil | ||
} | ||
|
||
func DeleteCert(code string) error { | ||
repo := &repository.CertRepo{ | ||
Db: database.Init(), | ||
} | ||
err := repo.Delete(code) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = deleteFiles(code) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func Etag(filePath string) (string, error) { | ||
etag := "" | ||
file, err := os.Open(filePath) | ||
if err != nil { | ||
return etag, err | ||
} | ||
defer file.Close() | ||
|
||
hash := md5.New() | ||
if _, err := io.Copy(hash, file); err != nil { | ||
return etag, err | ||
} | ||
etag = fmt.Sprintf("%x", hash.Sum(nil)) | ||
return etag, nil | ||
} | ||
|
||
func deleteFiles(code string) error { | ||
certPath := filepath.Join(CertPath, code+".crt") | ||
keyPath := filepath.Join(CertPath, code+".key") | ||
|
||
filePaths := []string{certPath, keyPath} | ||
|
||
for _, filePath := range filePaths { | ||
err := os.Remove(filePath) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func uploadFile(code string, certFile *multipart.FileHeader, keyFile *multipart.FileHeader) error { | ||
certSrc, err := certFile.Open() | ||
if err != nil { | ||
return err | ||
} | ||
defer certSrc.Close() | ||
|
||
keySrc, err := keyFile.Open() | ||
if err != nil { | ||
return err | ||
} | ||
defer keySrc.Close() | ||
|
||
_ = os.MkdirAll(CertPath, 0755) | ||
certDst, err := os.Create(filepath.Join(CertPath, code+".crt")) | ||
if err != nil { | ||
return err | ||
} | ||
defer certDst.Close() | ||
|
||
keyDst, err := os.Create(filepath.Join(CertPath, code+".key")) | ||
if err != nil { | ||
return err | ||
} | ||
defer keyDst.Close() | ||
|
||
if _, err = io.Copy(certDst, certSrc); err != nil { | ||
return err | ||
} | ||
|
||
if _, err = io.Copy(keyDst, keySrc); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
Oops, something went wrong.