-
Notifications
You must be signed in to change notification settings - Fork 1
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
Theotime Leveque
committed
Mar 20, 2017
1 parent
76d6e5d
commit b99c13a
Showing
3 changed files
with
278 additions
and
2 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,107 @@ | ||
package share | ||
|
||
import ( | ||
"bytes" | ||
"crypto/aes" | ||
"crypto/cipher" | ||
"crypto/rand" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"mime/multipart" | ||
"net/http" | ||
"os" | ||
) | ||
|
||
// Upload to transfer.sh | ||
func Upload(filename string, targetURL string, key string) (string, error) { | ||
bodyBuf := &bytes.Buffer{} | ||
bodyWriter := multipart.NewWriter(bodyBuf) | ||
|
||
fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename) | ||
if err != nil { | ||
fmt.Println("error writing to buffer") | ||
return "", err | ||
} | ||
|
||
var fh io.Reader | ||
if key == "" { | ||
fh, err = os.Open(filename) | ||
if err != nil { | ||
fmt.Println("error opening file") | ||
return "", err | ||
} | ||
} else { | ||
fh = EncryptFile(filename, []byte(key)) | ||
} | ||
|
||
// iocopy | ||
_, err = io.Copy(fileWriter, fh) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
contentType := bodyWriter.FormDataContentType() | ||
bodyWriter.Close() | ||
|
||
resp, err := http.Post(targetURL, contentType, bodyBuf) | ||
if err != nil { | ||
return "", err | ||
} | ||
defer resp.Body.Close() | ||
respBody, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return "", err | ||
} | ||
fmt.Println(resp.Status) | ||
return string(respBody), nil | ||
} | ||
|
||
// ZipConfigFiles produces a Zip archive | ||
func ZipConfigFiles(filename string) { | ||
|
||
} | ||
|
||
// EncryptFile encrypt and return a file | ||
func EncryptFile(filename string, key []byte) io.Reader { | ||
fileContent, err := ioutil.ReadFile(filename) | ||
|
||
block, err := aes.NewCipher(key) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// The IV needs to be unique, but not secure. Therefore it's common to | ||
// include it at the beginning of the ciphertext. | ||
ciphertext := make([]byte, aes.BlockSize+len(fileContent)) | ||
iv := ciphertext[:aes.BlockSize] | ||
if _, err := io.ReadFull(rand.Reader, iv); err != nil { | ||
panic(err) | ||
} | ||
|
||
stream := cipher.NewCFBEncrypter(block, iv) | ||
stream.XORKeyStream(ciphertext[aes.BlockSize:], fileContent) | ||
return bytes.NewReader(ciphertext) | ||
} | ||
|
||
// GetshareSetFromLinkCmdUsageTemplate returns shareSetFromLinkCmd usage template | ||
func GetshareSetFromLinkCmdUsageTemplate() string { | ||
return `Usage:{{if .Runnable}} | ||
{{if .HasAvailableFlags}}{{appendIfNotPresent .UseLine "<url> <conf_file> [flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{if .HasAvailableSubCommands}} | ||
{{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}} | ||
Aliases: | ||
{{.NameAndAliases}} | ||
{{end}}{{if .HasExample}} | ||
Examples: | ||
{{ .Example }}{{end}}{{if .HasAvailableSubCommands}} | ||
Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} | ||
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} | ||
Flags: | ||
{{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasAvailableInheritedFlags}} | ||
Global Flags: | ||
{{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}} | ||
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} | ||
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} | ||
Use "{{.CommandPath}} [command] --help" for more information about a command.{{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
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,163 @@ | ||
// Copyright © 2016 Theotime LEVEQUE [email protected] | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/thylong/ian/backend/config" | ||
"github.com/thylong/ian/backend/share" | ||
) | ||
|
||
var key = "" | ||
|
||
var encryptShareCmdParam bool | ||
|
||
// var shortLinkShareCmdParam bool | ||
|
||
func init() { | ||
RootCmd.AddCommand(shareCmd) | ||
|
||
shareCmd.PersistentFlags().BoolVarP(&encryptShareCmdParam, "encrypt", "s", false, "Encrypt with private key before uploading") | ||
// shareCmd.PersistentFlags().BoolVarP(&shortLinkShareCmdParam, "bitlink", "b", false, "Get a Bit.ly shorten URL") | ||
|
||
shareSetFromLinkCmd.SetUsageTemplate(share.GetshareSetFromLinkCmdUsageTemplate()) | ||
|
||
shareCmd.AddCommand( | ||
shareConfigCmd, | ||
shareProjectsCmd, | ||
shareEnvCmd, | ||
shareSetFromLinkCmd, | ||
// shareAllCmd, | ||
) | ||
} | ||
|
||
// shareCmd represents the env command | ||
var shareCmd = &cobra.Command{ | ||
Use: "share", | ||
Short: "Share ian configuration", | ||
Long: `Share a public link to a single (or multiple) ian configuration file.`, | ||
} | ||
|
||
var shareConfigCmd = &cobra.Command{ | ||
Use: "config", | ||
Short: "Share a public link to ian config.yml file", | ||
Long: `Share a public link to ian config.yml file.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if encryptShareCmdParam { | ||
key = config.GetUserInput("Enter a secret key: ") | ||
} | ||
link, err := share.Upload(config.ConfigFilesPathes[cmd.Use], "https://transfer.sh/", key) | ||
if err != nil { | ||
fmt.Fprint(os.Stderr, "Sorry, it looks like I cannot upload configuration file... :(") | ||
return | ||
} | ||
fmt.Println(link) | ||
}, | ||
} | ||
|
||
var shareProjectsCmd = &cobra.Command{ | ||
Use: "projects", | ||
Short: "Share a public link to ian projects.yml file", | ||
Long: `Share a public link to ian projects.yml file.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if encryptShareCmdParam { | ||
key = config.GetUserInput("Enter a secret key: ") | ||
} | ||
link, err := share.Upload(config.ConfigFilesPathes[cmd.Use], "https://transfer.sh/", key) | ||
if err != nil { | ||
fmt.Fprint(os.Stderr, "Sorry, it looks like I cannot upload configuration file... :(") | ||
return | ||
} | ||
fmt.Println(link) | ||
}, | ||
} | ||
|
||
var shareEnvCmd = &cobra.Command{ | ||
Use: "env", | ||
Short: "Share a public link to ian env.yml file", | ||
Long: `Share a public link to ian env.yml file.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if encryptShareCmdParam { | ||
key = config.GetUserInput("Enter a secret key: ") | ||
} | ||
link, err := share.Upload(config.ConfigFilesPathes[cmd.Use], "https://transfer.sh/", key) | ||
if err != nil { | ||
fmt.Fprint(os.Stderr, "Sorry, it looks like I cannot upload configuration file... :(") | ||
return | ||
} | ||
fmt.Println(link) | ||
}, | ||
} | ||
|
||
var shareSetFromLinkCmd = &cobra.Command{ | ||
Use: "set", | ||
Short: "Set config from config file link", | ||
Long: `Set config from config file link.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if len(args) < 1 { | ||
fmt.Fprint(os.Stderr, "Not enough argument.\n\n") | ||
cmd.Usage() | ||
os.Exit(1) | ||
} | ||
|
||
_, err := url.ParseRequestURI(args[0]) | ||
if err != nil { | ||
fmt.Fprint(os.Stderr, "Sorry, it looks like the link you provided is invalid.") | ||
} | ||
|
||
resp, err := http.Get(args[0]) | ||
if err != nil { | ||
fmt.Fprint(os.Stderr, "Sorry, the link is unreachable.") | ||
} | ||
defer resp.Body.Close() | ||
|
||
if strings.HasSuffix(string(strings.TrimSuffix(args[0], "/")), "_e") { | ||
// DecryptFile | ||
} | ||
|
||
confFileName := strings.TrimSuffix(args[1], ".yml") | ||
fmt.Print(confFileName) | ||
if confFilePath, ok := config.ConfigFilesPathes[confFileName]; ok { | ||
f, err := os.OpenFile(confFilePath, os.O_TRUNC|os.O_WRONLY, 0600) | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
defer f.Close() | ||
|
||
if _, err := io.Copy(f, resp.Body); err != nil { | ||
fmt.Fprintf(os.Stderr, "Error: %s", err.Error()) | ||
os.Exit(1) | ||
} | ||
return | ||
} | ||
fmt.Fprint(os.Stderr, "Sorry, something went wrong.") | ||
}, | ||
} | ||
|
||
var shareAllCmd = &cobra.Command{ | ||
Use: "all", | ||
Short: "Share a public link to ian a zip containing all files", | ||
Long: `Share a public link to ian env.yml file.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
}, | ||
} |