diff --git a/api.go b/api.go index b8df713..dd93144 100644 --- a/api.go +++ b/api.go @@ -5,28 +5,24 @@ import ( "net/http" "os" + "flag" + "strconv" + "github.com/franela/play-with-docker/handlers" "github.com/franela/play-with-docker/services" "github.com/franela/play-with-docker/templates" "github.com/gorilla/mux" "github.com/urfave/negroni" - "flag" - "strconv" ) func main() { - var portNumber int flag.IntVar(&portNumber, "port", 3000, "Give a TCP port to run the application") flag.Parse() - welcome, tmplErr := templates.GetWelcomeTemplate() - if tmplErr != nil { - log.Fatal(tmplErr) - } + bypassCaptcha := len(os.Getenv("GOOGLE_RECAPTCHA_DISABLED")) > 0 server := services.CreateWSServer() - server.On("connection", handlers.WS) server.On("error", handlers.WSError) @@ -45,9 +41,19 @@ func main() { r.StrictSlash(false) r.HandleFunc("/ping", http.HandlerFunc(handlers.Ping)).Methods("GET") + r.HandleFunc("/", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - rw.Write(welcome) + if bypassCaptcha { + http.ServeFile(rw, r, "./www/bypass.html") + } else { + welcome, tmplErr := templates.GetWelcomeTemplate() + if tmplErr != nil { + log.Fatal(tmplErr) + } + rw.Write(welcome) + } })).Methods("GET") + r.HandleFunc("/", http.HandlerFunc(handlers.NewSession)).Methods("POST") r.HandleFunc("/sessions/{sessionId}", http.HandlerFunc(handlers.GetSession)).Methods("GET") @@ -57,6 +63,7 @@ func main() { h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./www/index.html") }) + r.HandleFunc("/p/{sessionId}", h).Methods("GET") r.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./www"))) r.HandleFunc("/robots.txt", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { @@ -68,7 +75,7 @@ func main() { n := negroni.Classic() n.UseHandler(r) - log.Println("Listening on port "+ strconv.Itoa(portNumber)) + log.Println("Listening on port " + strconv.Itoa(portNumber)) log.Fatal(http.ListenAndServe("0.0.0.0:"+strconv.Itoa(portNumber), n)) } diff --git a/services/session.go b/services/session.go index 5ac2dbd..71f01e1 100644 --- a/services/session.go +++ b/services/session.go @@ -5,6 +5,7 @@ import ( "log" "math" "os" + "strconv" "sync" "time" @@ -91,18 +92,35 @@ func CloseSession(s *Session) error { return nil } +// Todo: this handles minimum viable product and removes hard-coding of hours value :) +// For future enhance to return time.Duration and parse a string / flag. +func getExpiryHours() int { + hours := 4 + override := os.Getenv("EXPIRY") + if len(override) > 0 { + value, err := strconv.Atoi(override) + if err == nil { + hours = value + } + } + return hours +} + func NewSession() (*Session, error) { + hours := getExpiryHours() + duration := time.Duration(hours) * time.Hour + s := &Session{} s.Id = uuid.NewV4().String() s.Instances = map[string]*Instance{} s.CreatedAt = time.Now() - s.ExpiresAt = s.CreatedAt.Add(4 * time.Hour) + s.ExpiresAt = s.CreatedAt.Add(duration) log.Printf("NewSession id=[%s]\n", s.Id) sessions[s.Id] = s // Schedule cleanup of the session - CloseSessionAfter(s, 4*time.Hour) + CloseSessionAfter(s, duration) if err := CreateNetwork(s.Id); err != nil { log.Println("ERROR NETWORKING") diff --git a/www/assets/app.js b/www/assets/app.js index 9f384e0..9e6d642 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -3,6 +3,14 @@ var app = angular.module('DockerPlay', ['ngMaterial']); + // Automatically redirects user to a new session when bypassing captcha. + // Controller keeps code/logic separate from the HTML + app.controller("BypassController", ['$scope', '$log', '$http', '$location', '$timeout', '$mdDialog', '$window', function($scope, $log, $http, $location, $timeout, $mdDialog, $window) { + setTimeout(function() { + var el = document.querySelector("#submit"); + el.click(); + }, 500); + }]); app.controller('PlayController', ['$scope', '$log', '$http', '$location', '$timeout', '$mdDialog', '$window', function($scope, $log, $http, $location, $timeout, $mdDialog, $window) { $scope.sessionId = window.location.pathname.replace('/p/', ''); diff --git a/www/bypass.html b/www/bypass.html new file mode 100644 index 0000000..2582f20 --- /dev/null +++ b/www/bypass.html @@ -0,0 +1,25 @@ + + + + Docker Playground + + + + +
+

Welcome!

+

We're bypassing the Captcha and redirecting you now..

+
+ +
+
+ + + + + + + + + + diff --git a/www/index.html b/www/index.html index d47330d..c731aa4 100644 --- a/www/index.html +++ b/www/index.html @@ -8,6 +8,7 @@ +
@@ -19,10 +20,12 @@
+

No connection to server. Reconnecting...

+
Instances - - + Add new instance - + + Add new instance @@ -52,12 +53,8 @@
-

- Add instances to your playground. -

-

- Sessions and all their instances are deleted after 4 hours. -

+

Add instances to your playground.

+

Sessions and all their instances are deleted after {{ttl}} hours.

@@ -92,10 +89,7 @@
- -
-
@@ -103,6 +97,7 @@ + diff --git a/www/welcome.html b/www/welcome.html index a628a7c..6a2b0c8 100644 --- a/www/welcome.html +++ b/www/welcome.html @@ -1,6 +1,6 @@ {{define "GOOGLE_RECAPTCHA_SITE_KEY"}} - + Docker Playground