Skip to content

Commit

Permalink
feat: use sqlite database
Browse files Browse the repository at this point in the history
  • Loading branch information
pupilcc committed Jul 30, 2024
1 parent ecce7ca commit 0a80a2a
Show file tree
Hide file tree
Showing 43 changed files with 4,400 additions and 376 deletions.
2 changes: 1 addition & 1 deletion web/index.go → api/index.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package web
package api

import (
"github.com/labstack/echo/v4"
Expand Down
2 changes: 1 addition & 1 deletion web/login.go → api/login.go
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"
Expand Down
39 changes: 39 additions & 0 deletions api/ssl.go
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)
}
99 changes: 99 additions & 0 deletions application/ssl.go
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)
}
5 changes: 0 additions & 5 deletions common/response/message.go

This file was deleted.

2 changes: 1 addition & 1 deletion module/jwt.go → config/jwt.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package module
package config

import "github.com/labstack/echo/v4"

Expand Down
2 changes: 1 addition & 1 deletion module/logger.go → config/logger.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package module
package config

import (
"github.com/labstack/echo/v4"
Expand Down
13 changes: 13 additions & 0 deletions domain/model/cert.go
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"`
}
12 changes: 12 additions & 0 deletions domain/repository/cert_repository.go
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
}
186 changes: 186 additions & 0 deletions domain/service/cert_service.go
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
}
Loading

0 comments on commit 0a80a2a

Please sign in to comment.