You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

346 lines
7.6 KiB

  1. package cmd
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strings"
  7. "git.kiska.pw/kiska/transfer.sh/server"
  8. "github.com/fatih/color"
  9. "github.com/minio/cli"
  10. "google.golang.org/api/googleapi"
  11. )
  12. var Version = "0.1"
  13. var helpTemplate = `NAME:
  14. {{.Name}} - {{.Usage}}
  15. DESCRIPTION:
  16. {{.Description}}
  17. USAGE:
  18. {{.Name}} {{if .Flags}}[flags] {{end}}command{{if .Flags}}{{end}} [arguments...]
  19. COMMANDS:
  20. {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
  21. {{end}}{{if .Flags}}
  22. FLAGS:
  23. {{range .Flags}}{{.}}
  24. {{end}}{{end}}
  25. VERSION:
  26. ` + Version +
  27. `{{ "\n"}}`
  28. var globalFlags = []cli.Flag{
  29. cli.StringFlag{
  30. Name: "listener",
  31. Usage: "127.0.0.1:8080",
  32. Value: "127.0.0.1:8080",
  33. },
  34. // redirect to https?
  35. // hostnames
  36. cli.StringFlag{
  37. Name: "profile-listener",
  38. Usage: "127.0.0.1:6060",
  39. Value: "",
  40. },
  41. cli.BoolFlag{
  42. Name: "force-https",
  43. Usage: "",
  44. },
  45. cli.StringFlag{
  46. Name: "tls-listener",
  47. Usage: "127.0.0.1:8443",
  48. Value: "",
  49. },
  50. cli.BoolFlag{
  51. Name: "tls-listener-only",
  52. Usage: "",
  53. },
  54. cli.StringFlag{
  55. Name: "tls-cert-file",
  56. Value: "",
  57. },
  58. cli.StringFlag{
  59. Name: "tls-private-key",
  60. Value: "",
  61. },
  62. cli.StringFlag{
  63. Name: "temp-path",
  64. Usage: "path to temp files",
  65. Value: os.TempDir(),
  66. },
  67. cli.StringFlag{
  68. Name: "web-path",
  69. Usage: "path to static web files",
  70. Value: "",
  71. },
  72. cli.StringFlag{
  73. Name: "ga-key",
  74. Usage: "key for google analytics (front end)",
  75. Value: "",
  76. },
  77. cli.StringFlag{
  78. Name: "uservoice-key",
  79. Usage: "key for user voice (front end)",
  80. Value: "",
  81. },
  82. cli.StringFlag{
  83. Name: "provider",
  84. Usage: "s3|gdrive|local",
  85. Value: "",
  86. },
  87. cli.StringFlag{
  88. Name: "s3-endpoint",
  89. Usage: "",
  90. Value: "http://s3-eu-west-1.amazonaws.com",
  91. EnvVar: "S3_ENDPOINT",
  92. },
  93. cli.StringFlag{
  94. Name: "aws-access-key",
  95. Usage: "",
  96. Value: "",
  97. EnvVar: "AWS_ACCESS_KEY",
  98. },
  99. cli.StringFlag{
  100. Name: "aws-secret-key",
  101. Usage: "",
  102. Value: "",
  103. EnvVar: "AWS_SECRET_KEY",
  104. },
  105. cli.StringFlag{
  106. Name: "bucket",
  107. Usage: "",
  108. Value: "",
  109. EnvVar: "BUCKET",
  110. },
  111. cli.BoolFlag{
  112. Name: "s3-no-multipart",
  113. Usage: "Disables S3 Multipart Puts",
  114. },
  115. cli.StringFlag{
  116. Name: "gdrive-client-json-filepath",
  117. Usage: "",
  118. Value: "",
  119. },
  120. cli.StringFlag{
  121. Name: "gdrive-local-config-path",
  122. Usage: "",
  123. Value: "",
  124. },
  125. cli.IntFlag{
  126. Name: "gdrive-chunk-size",
  127. Usage: "",
  128. Value: googleapi.DefaultUploadChunkSize / 1024 / 1024,
  129. },
  130. cli.IntFlag{
  131. Name: "rate-limit",
  132. Usage: "requests per minute",
  133. Value: 0,
  134. EnvVar: "",
  135. },
  136. cli.StringFlag{
  137. Name: "lets-encrypt-hosts",
  138. Usage: "host1, host2",
  139. Value: "",
  140. EnvVar: "HOSTS",
  141. },
  142. cli.StringFlag{
  143. Name: "log",
  144. Usage: "/var/log/transfersh.log",
  145. Value: "",
  146. },
  147. cli.StringFlag{
  148. Name: "basedir",
  149. Usage: "path to storage",
  150. Value: "",
  151. },
  152. cli.StringFlag{
  153. Name: "clamav-host",
  154. Usage: "clamav-host",
  155. Value: "",
  156. EnvVar: "CLAMAV_HOST",
  157. },
  158. cli.StringFlag{
  159. Name: "virustotal-key",
  160. Usage: "virustotal-key",
  161. Value: "",
  162. EnvVar: "VIRUSTOTAL_KEY",
  163. },
  164. cli.BoolFlag{
  165. Name: "profiler",
  166. Usage: "enable profiling",
  167. },
  168. cli.StringFlag{
  169. Name: "http-auth-user",
  170. Usage: "user for http basic auth",
  171. Value: "",
  172. },
  173. cli.StringFlag{
  174. Name: "http-auth-pass",
  175. Usage: "pass for http basic auth",
  176. Value: "",
  177. },
  178. }
  179. type Cmd struct {
  180. *cli.App
  181. }
  182. func VersionAction(c *cli.Context) {
  183. fmt.Println(color.YellowString(fmt.Sprintf("transfer.sh: Easy file sharing from the command line")))
  184. }
  185. func New() *Cmd {
  186. logger := log.New(os.Stdout, "[transfer.sh]", log.LstdFlags)
  187. app := cli.NewApp()
  188. app.Name = "transfer.sh"
  189. app.Author = ""
  190. app.Usage = "transfer.sh"
  191. app.Description = `Easy file sharing from the command line`
  192. app.Flags = globalFlags
  193. app.CustomAppHelpTemplate = helpTemplate
  194. app.Commands = []cli.Command{
  195. {
  196. Name: "version",
  197. Action: VersionAction,
  198. },
  199. }
  200. app.Before = func(c *cli.Context) error {
  201. return nil
  202. }
  203. app.Action = func(c *cli.Context) {
  204. options := []server.OptionFn{}
  205. if v := c.String("listener"); v != "" {
  206. options = append(options, server.Listener(v))
  207. }
  208. if v := c.String("tls-listener"); v == "" {
  209. } else if c.Bool("tls-listener-only") {
  210. options = append(options, server.TLSListener(v, true))
  211. } else {
  212. options = append(options, server.TLSListener(v, false))
  213. }
  214. if v := c.String("profile-listener"); v != "" {
  215. options = append(options, server.ProfileListener(v))
  216. }
  217. if v := c.String("web-path"); v != "" {
  218. options = append(options, server.WebPath(v))
  219. }
  220. if v := c.String("ga-key"); v != "" {
  221. options = append(options, server.GoogleAnalytics(v))
  222. }
  223. if v := c.String("uservoice-key"); v != "" {
  224. options = append(options, server.UserVoice(v))
  225. }
  226. if v := c.String("temp-path"); v != "" {
  227. options = append(options, server.TempPath(v))
  228. }
  229. if v := c.String("log"); v != "" {
  230. options = append(options, server.LogFile(logger, v))
  231. } else {
  232. options = append(options, server.Logger(logger))
  233. }
  234. if v := c.String("lets-encrypt-hosts"); v != "" {
  235. options = append(options, server.UseLetsEncrypt(strings.Split(v, ",")))
  236. }
  237. if v := c.String("virustotal-key"); v != "" {
  238. options = append(options, server.VirustotalKey(v))
  239. }
  240. if v := c.String("clamav-host"); v != "" {
  241. options = append(options, server.ClamavHost(v))
  242. }
  243. if v := c.Int("rate-limit"); v > 0 {
  244. options = append(options, server.RateLimit(v))
  245. }
  246. if cert := c.String("tls-cert-file"); cert == "" {
  247. } else if pk := c.String("tls-private-key"); pk == "" {
  248. } else {
  249. options = append(options, server.TLSConfig(cert, pk))
  250. }
  251. if c.Bool("profiler") {
  252. options = append(options, server.EnableProfiler())
  253. }
  254. if c.Bool("force-https") {
  255. options = append(options, server.ForceHTTPs())
  256. }
  257. if httpAuthUser := c.String("http-auth-user"); httpAuthUser == "" {
  258. } else if httpAuthPass := c.String("http-auth-pass"); httpAuthPass == "" {
  259. } else {
  260. options = append(options, server.HttpAuthCredentials(httpAuthUser, httpAuthPass))
  261. }
  262. switch provider := c.String("provider"); provider {
  263. case "s3":
  264. if accessKey := c.String("aws-access-key"); accessKey == "" {
  265. panic("access-key not set.")
  266. } else if secretKey := c.String("aws-secret-key"); secretKey == "" {
  267. panic("secret-key not set.")
  268. } else if bucket := c.String("bucket"); bucket == "" {
  269. panic("bucket not set.")
  270. } else if storage, err := server.NewS3Storage(accessKey, secretKey, bucket, c.String("s3-endpoint"), logger, c.Bool("s3-no-multipart")); err != nil {
  271. panic(err)
  272. } else {
  273. options = append(options, server.UseStorage(storage))
  274. }
  275. case "gdrive":
  276. chunkSize := c.Int("gdrive-chunk-size")
  277. if clientJsonFilepath := c.String("gdrive-client-json-filepath"); clientJsonFilepath == "" {
  278. panic("client-json-filepath not set.")
  279. } else if localConfigPath := c.String("gdrive-local-config-path"); localConfigPath == "" {
  280. panic("local-config-path not set.")
  281. } else if basedir := c.String("basedir"); basedir == "" {
  282. panic("basedir not set.")
  283. } else if storage, err := server.NewGDriveStorage(clientJsonFilepath, localConfigPath, basedir, chunkSize, logger); err != nil {
  284. panic(err)
  285. } else {
  286. options = append(options, server.UseStorage(storage))
  287. }
  288. case "local":
  289. if v := c.String("basedir"); v == "" {
  290. panic("basedir not set.")
  291. } else if storage, err := server.NewLocalStorage(v, logger); err != nil {
  292. panic(err)
  293. } else {
  294. options = append(options, server.UseStorage(storage))
  295. }
  296. default:
  297. panic("Provider not set or invalid.")
  298. }
  299. srvr, err := server.New(
  300. options...,
  301. )
  302. if err != nil {
  303. logger.Println(color.RedString("Error starting server: %s", err.Error()))
  304. return
  305. }
  306. srvr.Run()
  307. }
  308. return &Cmd{
  309. App: app,
  310. }
  311. }