Add config
This commit is contained in:
parent
d53235d8ef
commit
377962440c
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
certs/*.pem
|
||||
certs/*.key
|
||||
tmp/*
|
||||
ezshare.toml
|
@ -18,4 +18,4 @@ FROM alpine:latest
|
||||
COPY --from=builder-base /app/ezshare /usr/bin/ezshare
|
||||
EXPOSE 50051
|
||||
EXPOSE 8088
|
||||
CMD ["/usr/bin/ezshare", "serve"]
|
||||
CMD ["/usr/bin/ezshare","--config", "/data/ezshare.toml" "serve"]
|
@ -1,25 +0,0 @@
|
||||
//go:build allcerts
|
||||
|
||||
package certs
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed ca.key
|
||||
var CAKey []byte
|
||||
|
||||
//go:embed ca.pem
|
||||
var CACert []byte
|
||||
|
||||
//go:embed srv.key
|
||||
var SrvKey []byte
|
||||
|
||||
//go:embed srv.pem
|
||||
var SrvCert []byte
|
||||
|
||||
//go:embed client.key
|
||||
var ClientKey []byte
|
||||
|
||||
//go:embed client.pem
|
||||
var ClientCert []byte
|
@ -1,23 +0,0 @@
|
||||
//go:build clientcerts
|
||||
|
||||
package certs
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
var CAKey []byte
|
||||
|
||||
//go:embed ca.pem
|
||||
var CACert []byte
|
||||
|
||||
var SrvKey []byte
|
||||
|
||||
//go:embed srv.pem
|
||||
var SrvCert []byte
|
||||
|
||||
//go:embed client.key
|
||||
var ClientKey []byte
|
||||
|
||||
//go:embed client.key
|
||||
var ClientCert []byte
|
@ -1,19 +0,0 @@
|
||||
//go:build !allcerts && !clientcerts
|
||||
|
||||
package certs
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
var CAKey []byte
|
||||
|
||||
var CACert []byte
|
||||
|
||||
var SrvKey []byte
|
||||
|
||||
var SrvCert []byte
|
||||
|
||||
var ClientKey []byte
|
||||
|
||||
var ClientCert []byte
|
@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -88,16 +89,16 @@ func GenCACert() (priv []byte, pub []byte, err error) {
|
||||
return caPrivKeyBytes, caBytes, nil
|
||||
}
|
||||
|
||||
func GenCerts() error {
|
||||
func GenAllCerts(path string) error {
|
||||
// Create CA certs
|
||||
caPriv, caPub, err := GenCACert()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WriteKey(caPriv, "certs/ca.key"); err != nil {
|
||||
if err := WriteKey(caPriv, filepath.Join(path, "ca.key")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WriteCert(caPub, "certs/ca.pem"); err != nil {
|
||||
if err := WriteCert(caPub, filepath.Join(path, "ca.pem")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -106,10 +107,10 @@ func GenCerts() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WriteKey(srvKey, "certs/srv.key"); err != nil {
|
||||
if err := WriteKey(srvKey, filepath.Join(path, "srv.key")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WriteCert(srvCrt, "certs/srv.pem"); err != nil {
|
||||
if err := WriteCert(srvCrt, filepath.Join(path, "srv.pem")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -117,10 +118,10 @@ func GenCerts() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WriteKey(clientKey, "certs/client.key"); err != nil {
|
||||
if err := WriteKey(clientKey, filepath.Join(path, "client.key")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WriteCert(clientCrt, "certs/client.pem"); err != nil {
|
||||
if err := WriteCert(clientCrt, filepath.Join(path, "client.pem")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.benny.dog/torjus/ezshare/pb"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func NewClient(ctx context.Context, addr string) (pb.FileServiceClient, error) {
|
||||
conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client := pb.NewFileServiceClient(conn)
|
||||
return client, nil
|
||||
}
|
@ -15,6 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"gitea.benny.dog/torjus/ezshare/certs"
|
||||
"gitea.benny.dog/torjus/ezshare/config"
|
||||
"gitea.benny.dog/torjus/ezshare/pb"
|
||||
"gitea.benny.dog/torjus/ezshare/server"
|
||||
"gitea.benny.dog/torjus/ezshare/store"
|
||||
@ -26,6 +27,12 @@ import (
|
||||
func main() {
|
||||
app := cli.App{
|
||||
Name: "ezshare",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "Path to config-file.",
|
||||
},
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
{
|
||||
Name: "serve",
|
||||
@ -79,15 +86,21 @@ func main() {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "gencerts",
|
||||
Usage: "Generate certificates",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "out-dir",
|
||||
Usage: "Directory where certificates will be stored.",
|
||||
Name: "cert",
|
||||
Usage: "Certificate commands",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "gen-all",
|
||||
Usage: "Generate CA, Server and Client certificates",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "out-dir",
|
||||
Usage: "Directory where certificates will be stored.",
|
||||
},
|
||||
},
|
||||
Action: ActionGencerts,
|
||||
},
|
||||
},
|
||||
Action: ActionGencerts,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -100,6 +113,25 @@ func main() {
|
||||
}
|
||||
|
||||
func ActionServe(c *cli.Context) error {
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read certificates
|
||||
srvCertBytes, err := cfg.Server.GRPC.Certs.GetCertBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srvKeyBytes, err := cfg.Server.GRPC.Certs.GetKeyBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
caCertBytes, err := cfg.Server.GRPC.CACerts.GetCertBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileStore := store.NewMemoryFileStore()
|
||||
// Setup shutdown-handling
|
||||
rootCtx, rootCancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||
@ -115,7 +147,7 @@ func ActionServe(c *cli.Context) error {
|
||||
|
||||
// Start grpc server
|
||||
go func() {
|
||||
grpcAddr := ":50051"
|
||||
grpcAddr := cfg.Server.GRPC.ListenAddr
|
||||
if c.IsSet("grpc-addr") {
|
||||
grpcAddr = c.String("grpc-addr")
|
||||
}
|
||||
@ -130,14 +162,13 @@ func ActionServe(c *cli.Context) error {
|
||||
log.Printf("Unable to setup grpc listener: %s\n", err)
|
||||
rootCancel()
|
||||
}
|
||||
srvCert, err := tls.X509KeyPair(certs.SrvCert, certs.SrvKey)
|
||||
srvCert, err := tls.X509KeyPair(srvCertBytes, srvKeyBytes)
|
||||
if err != nil {
|
||||
log.Printf("%d %d", len(certs.SrvCert), len(certs.SrvKey))
|
||||
log.Printf("Unable load server certs: %s\n", err)
|
||||
rootCancel()
|
||||
}
|
||||
certPool := x509.NewCertPool()
|
||||
if !certPool.AppendCertsFromPEM(certs.CACert) {
|
||||
if !certPool.AppendCertsFromPEM(caCertBytes) {
|
||||
log.Println("Unable to load CA cert")
|
||||
rootCancel()
|
||||
}
|
||||
@ -242,8 +273,17 @@ func ActionClientGet(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func ActionClientUpload(c *cli.Context) error {
|
||||
addr := c.String("addr")
|
||||
clientCreds, err := getClientCreds()
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr := cfg.Client.DefaultServer
|
||||
if c.IsSet("addr") {
|
||||
addr = c.String("addr")
|
||||
}
|
||||
|
||||
clientCreds, err := cfg.Client.Creds()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -279,22 +319,22 @@ func ActionClientUpload(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func ActionGencerts(c *cli.Context) error {
|
||||
return certs.GenCerts()
|
||||
outDir := "."
|
||||
if c.IsSet("out-dir") {
|
||||
outDir = c.String("out-dir")
|
||||
}
|
||||
return certs.GenAllCerts(outDir)
|
||||
}
|
||||
|
||||
func getClientCreds() (credentials.TransportCredentials, error) {
|
||||
certPool := x509.NewCertPool()
|
||||
if !certPool.AppendCertsFromPEM(certs.CACert) {
|
||||
return nil, fmt.Errorf("unable to load ca cert")
|
||||
func getConfig(c *cli.Context) (*config.Config, error) {
|
||||
if c.IsSet("config") {
|
||||
cfgPath := c.String("config")
|
||||
return config.FromFile(cfgPath)
|
||||
}
|
||||
clientCert, err := tls.X509KeyPair(certs.ClientCert, certs.ClientKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to load client cert: %s", err)
|
||||
cfg, err := config.FromDefaultLocations()
|
||||
if err == nil {
|
||||
fmt.Printf("Config loaded from %s\n", cfg.Location())
|
||||
fmt.Printf("Config: %+v\n", cfg)
|
||||
}
|
||||
config := &tls.Config{
|
||||
Certificates: []tls.Certificate{clientCert},
|
||||
RootCAs: certPool,
|
||||
}
|
||||
return credentials.NewTLS(config), nil
|
||||
|
||||
return cfg, err
|
||||
}
|
||||
|
175
config/config.go
Normal file
175
config/config.go
Normal file
@ -0,0 +1,175 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pelletier/go-toml"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
LogLevel string `toml:"LogLevel"`
|
||||
Server *ServerConfig `toml:"Server"`
|
||||
Client *ClientConfig `toml:"Client"`
|
||||
location string
|
||||
}
|
||||
type CertificatePaths struct {
|
||||
CertificatePath string `toml:"CertificatePath"`
|
||||
CertificateKeyPath string `toml:"CertificateKeyPath"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
GRPC *ServerGRPCConfig `toml:"GRPC"`
|
||||
HTTP *ServerHTTPConfig `toml:"HTTP"`
|
||||
}
|
||||
type ServerStoreConfig struct {
|
||||
Type string `toml:"Type"`
|
||||
FSStoreConfig *FSStoreConfig `toml:"Filesystem"`
|
||||
}
|
||||
type FSStoreConfig struct {
|
||||
Dir string `toml:"Dir"`
|
||||
}
|
||||
type ServerGRPCConfig struct {
|
||||
ListenAddr string `toml:"ListenAddr"`
|
||||
CACerts *CertificatePaths `toml:"CACerts"`
|
||||
Certs *CertificatePaths `toml:"Certs"`
|
||||
}
|
||||
type ServerHTTPConfig struct {
|
||||
ListenAddr string `toml:"ListenAddr"`
|
||||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
DefaultServer string `toml:"DefaultServer"`
|
||||
ServerCertPath string `toml:"ServerCertPath"`
|
||||
Certs *CertificatePaths `toml:"Certs"`
|
||||
}
|
||||
|
||||
func FromDefault() *Config {
|
||||
cfg := &Config{
|
||||
LogLevel: "INFO",
|
||||
Server: &ServerConfig{
|
||||
GRPC: &ServerGRPCConfig{
|
||||
ListenAddr: ":50051",
|
||||
CACerts: &CertificatePaths{},
|
||||
Certs: &CertificatePaths{},
|
||||
},
|
||||
HTTP: &ServerHTTPConfig{
|
||||
ListenAddr: ":8089",
|
||||
},
|
||||
},
|
||||
Client: &ClientConfig{},
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func FromReader(r io.Reader) (*Config, error) {
|
||||
decoder := toml.NewDecoder(r)
|
||||
c := FromDefault()
|
||||
if err := decoder.Decode(c); err != nil {
|
||||
return nil, fmt.Errorf("unable to read config: %w", err)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func FromFile(path string) (*Config, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open config-file: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
cfg, err := FromReader(f)
|
||||
if err == nil {
|
||||
cfg.location = path
|
||||
}
|
||||
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
func FromDefaultLocations() (*Config, error) {
|
||||
defaultLocations := []string{
|
||||
"ezshare.toml",
|
||||
}
|
||||
userConfigDir, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
defaultLocations = append(defaultLocations, filepath.Join(userConfigDir, "ezshare", "ezshare.toml"))
|
||||
}
|
||||
|
||||
for _, location := range defaultLocations {
|
||||
if _, err := os.Stat(location); err == nil {
|
||||
return FromFile(location)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("config not found")
|
||||
}
|
||||
|
||||
func (c *Config) Location() string {
|
||||
return c.location
|
||||
}
|
||||
|
||||
func (cp *CertificatePaths) GetCertBytes() ([]byte, error) {
|
||||
f, err := os.Open(cp.CertificatePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadAll(f)
|
||||
}
|
||||
|
||||
func (cp *CertificatePaths) GetKeyBytes() ([]byte, error) {
|
||||
f, err := os.Open(cp.CertificateKeyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadAll(f)
|
||||
}
|
||||
|
||||
func (cc *ClientConfig) ServerCertBytes() ([]byte, error) {
|
||||
f, err := os.Open(cc.ServerCertPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open server certificate: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read client server certificate: %w", err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (cc *ClientConfig) Creds() (credentials.TransportCredentials, error) {
|
||||
srvCertBytes, err := cc.ServerCertBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientCertBytes, err := cc.Certs.GetCertBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read client cert: %w", err)
|
||||
}
|
||||
clientKeyBytes, err := cc.Certs.GetKeyBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read client cert: %w", err)
|
||||
}
|
||||
certPool := x509.NewCertPool()
|
||||
if !certPool.AppendCertsFromPEM(srvCertBytes) {
|
||||
return nil, fmt.Errorf("unable to load ca cert")
|
||||
}
|
||||
clientCert, err := tls.X509KeyPair(clientCertBytes, clientKeyBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to load client cert: %s", err)
|
||||
}
|
||||
config := &tls.Config{
|
||||
Certificates: []tls.Certificate{clientCert},
|
||||
RootCAs: certPool,
|
||||
}
|
||||
return credentials.NewTLS(config), nil
|
||||
|
||||
}
|
63
ezshare.example.toml
Normal file
63
ezshare.example.toml
Normal file
@ -0,0 +1,63 @@
|
||||
########################
|
||||
# Server configuration #
|
||||
########################
|
||||
[Server]
|
||||
# Set server log-level
|
||||
# Must be one of: DEBUG, INFO, WARN, ERROR
|
||||
# Default: INFO
|
||||
LogLevel = "INFO"
|
||||
|
||||
# Storage configuration
|
||||
[Server.Store]
|
||||
# How server stores file
|
||||
# Must be one of: filesystem, memory
|
||||
# Required
|
||||
Type = "filesystem"
|
||||
|
||||
[Server.Store.Filesystem]
|
||||
# Where files are stored
|
||||
# Required if store-type is filesystem
|
||||
Dir = "/data"
|
||||
|
||||
# GRPC Configuration
|
||||
[Server.GRPC]
|
||||
# Address to listen to
|
||||
# Default: :50051
|
||||
ListenAddr = ":50051"
|
||||
|
||||
# GRPC Certificate Configuration
|
||||
[Server.GRPC.CACerts]
|
||||
# Path of PEM-encoded certificate file
|
||||
CertificatePath = ""
|
||||
# Path of PEM-encoded private key
|
||||
# Must be of type ecdsa
|
||||
CertificateKeyPath = ""
|
||||
|
||||
[Server.GRPC.Certs]
|
||||
# Path of PEM-encoded certificate file
|
||||
CertificatePath = ""
|
||||
# Path of PEM-encoded private key
|
||||
# Must be of type ecdsa
|
||||
CertificateKeyPath = ""
|
||||
|
||||
[Server.HTTP]
|
||||
# Address to listen to
|
||||
# Default: :8089
|
||||
ListenAddr = ":8089"
|
||||
|
||||
|
||||
########################
|
||||
# Client configuration #
|
||||
########################
|
||||
[Client]
|
||||
# Server used if not specified using command-line
|
||||
DefaultServer = "localhost:50051"
|
||||
# Path to PEM-encoder server-certificate
|
||||
ServerCertPath = ""
|
||||
|
||||
[Client.Certs]
|
||||
# Path of PEM-encoded certificate file
|
||||
CertificatePath = ""
|
||||
# Path of PEM-encoded private key
|
||||
# Must be of type ecdsa
|
||||
CertificateKeyPath = ""
|
5
go.mod
5
go.mod
@ -5,6 +5,7 @@ go 1.17
|
||||
require (
|
||||
github.com/go-chi/chi/v5 v5.0.7
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/pelletier/go-toml v1.9.4
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
google.golang.org/grpc v1.42.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
@ -14,8 +15,8 @@ require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c // indirect
|
||||
golang.org/x/net v0.0.0-20211203184738-4852103109b8 // indirect
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9 // indirect
|
||||
)
|
||||
|
10
go.sum
10
go.sum
@ -55,6 +55,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
@ -83,8 +85,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c h1:WtYZ93XtWSO5KlOMgPZu7hXY9WhMZpprvlm5VwvAl8c=
|
||||
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211203184738-4852103109b8 h1:PFkPt/jI9Del3hmFplBtRp8tDhSRpFu7CyRs7VmEC0M=
|
||||
golang.org/x/net v0.0.0-20211203184738-4852103109b8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -122,8 +124,8 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 h1:DN5b3HU13J4sMd/QjDx34U6afpaexKTDdop+26pdjdk=
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9 h1:fU3FNfL/oBU2D5DvGqiuyVqqn40DdxvaTFHq7aivA3k=
|
||||
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
|
@ -1,3 +1,3 @@
|
||||
package ezshare
|
||||
|
||||
const Version = "v0.1.0"
|
||||
const Version = "v0.1.1"
|
||||
|
Loading…
Reference in New Issue
Block a user