func addLogs(ws *websocket.Conn) { var err error defer func() { msg := &errMsg{} if err != nil { msg.Error = err.Error() log.Errorf("failure in logs webservice: %s", err) } websocket.JSON.Send(ws, msg) ws.Close() }() req := ws.Request() t := context.GetAuthToken(req) if t == nil { err = errors.Errorf("wslogs: no token") return } if t.GetAppName() != app.InternalAppName { err = errors.Errorf("wslogs: invalid token app name: %q", t.GetAppName()) return } err = scanLogs(ws) if err != nil { return } }
func addLogs(ws *websocket.Conn) { var err error defer func() { data := map[string]interface{}{} if err != nil { data["error"] = err.Error() log.Error(err.Error()) } else { data["error"] = nil } msg, _ := json.Marshal(data) ws.Write(msg) ws.Close() }() req := ws.Request() t := context.GetAuthToken(req) if t == nil { err = fmt.Errorf("wslogs: no token") return } if t.GetAppName() != app.InternalAppName { err = fmt.Errorf("wslogs: invalid token app name: %q", t.GetAppName()) return } err = scanLogs(ws) if err != nil { return } }
func (fn authorizationRequiredHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t := context.GetAuthToken(r) if t == nil { context.AddRequestError(r, tokenRequiredErr) } else { context.AddRequestError(r, fn(w, r, t)) } }
func (fn AuthorizationRequiredHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t := context.GetAuthToken(r) if t == nil { w.Header().Set("WWW-Authenticate", "Bearer realm=\"tsuru\" scope=\"tsuru\"") context.AddRequestError(r, tokenRequiredErr) } else { context.AddRequestError(r, fn(w, r, t)) } }
func addLogs(ws *websocket.Conn) { var err error defer func() { data := map[string]interface{}{} if err != nil { data["error"] = err.Error() log.Error(err.Error()) } else { data["error"] = nil } msg, _ := json.Marshal(data) ws.Write(msg) ws.Close() }() req := ws.Request() t := context.GetAuthToken(req) if t == nil { err = fmt.Errorf("wslogs: no token") return } if t.GetAppName() != app.InternalAppName { err = fmt.Errorf("wslogs: invalid token app name: %q", t.GetAppName()) return } logCh, errCh := app.LogReceiver() scanner := bufio.NewScanner(ws) for scanner.Scan() { var entry app.Applog data := bytes.TrimSpace(scanner.Bytes()) if len(data) == 0 { continue } err = json.Unmarshal(data, &entry) if err != nil { close(logCh) err = fmt.Errorf("wslogs: parsing log line %q: %s", string(data), err) return } select { case logCh <- &entry: case err := <-errCh: close(logCh) err = fmt.Errorf("wslogs: storing log: %s", err) return } } close(logCh) err = scanner.Err() if err != nil { err = fmt.Errorf("wslogs: waiting for log data: %s", err) return } err = <-errCh if err != nil { err = fmt.Errorf("wslogs: storing log: %s", err) } }
func addLogs(ws *websocket.Conn) { var err error defer func() { data := map[string]interface{}{} if err != nil { data["error"] = err.Error() log.Error(err.Error()) } else { data["error"] = nil } msg, _ := json.Marshal(data) ws.Write(msg) ws.Close() }() req := ws.Request() t := context.GetAuthToken(req) if t == nil { err = fmt.Errorf("wslogs: no token") return } if t.GetAppName() != app.InternalAppName { err = fmt.Errorf("wslogs: invalid token app name: %q", t.GetAppName()) return } dispatcher := app.NewlogDispatcher() scanner := bufio.NewScanner(ws) for scanner.Scan() { var entry app.Applog data := bytes.TrimSpace(scanner.Bytes()) if len(data) == 0 { continue } err = json.Unmarshal(data, &entry) if err != nil { dispatcher.Stop() err = fmt.Errorf("wslogs: parsing log line %q: %s", string(data), err) return } err = dispatcher.Send(&entry) if err != nil { // Do not disconnect by returning here, dispatcher will already // retry db connection and we gain nothing by ending the WS // connection. log.Errorf("wslogs: error storing log: %s", err) } } err = dispatcher.Stop() if err != nil { err = fmt.Errorf("wslogs: error storing log: %s", err) return } err = scanner.Err() if err != nil { err = fmt.Errorf("wslogs: waiting for log data: %s", err) return } }
func remoteShellHandler(ws *websocket.Conn) { var httpErr *errors.HTTP defer func() { defer ws.Close() if httpErr != nil { var msg string switch httpErr.Code { case http.StatusUnauthorized: msg = "no token provided or session expired, please login again\n" default: msg = httpErr.Message + "\n" } ws.Write([]byte("Error: " + msg)) } }() r := ws.Request() token := context.GetAuthToken(r) if token == nil { httpErr = &errors.HTTP{ Code: http.StatusUnauthorized, Message: "no token provided", } return } appName := r.URL.Query().Get(":appname") app, err := getAppFromContext(appName, r) if err != nil { if herr, ok := err.(*errors.HTTP); ok { httpErr = herr } else { httpErr = &errors.HTTP{ Code: http.StatusInternalServerError, Message: err.Error(), } } return } unitID := r.URL.Query().Get("unit") width, _ := strconv.Atoi(r.URL.Query().Get("width")) height, _ := strconv.Atoi(r.URL.Query().Get("height")) term := r.URL.Query().Get("term") opts := provision.ShellOptions{ Conn: ws, Width: width, Height: height, Unit: unitID, Term: term, } err = app.Shell(opts) if err != nil { httpErr = &errors.HTTP{ Code: http.StatusInternalServerError, Message: err.Error(), } } }
func (fn AdminRequiredHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { t := context.GetAuthToken(r) if t == nil { context.AddRequestError(r, tokenRequiredErr) } else if user, err := t.User(); err != nil || !user.IsAdmin() { context.AddRequestError(r, adminRequiredErr) } else { context.AddRequestError(r, fn(w, r, t)) } }
func (s *S) TestAuthTokenMiddlewareWithoutToken(c *check.C) { recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/", nil) c.Assert(err, check.IsNil) h, log := doHandler() authTokenMiddleware(recorder, request, h) c.Assert(log.called, check.Equals, true) t := context.GetAuthToken(request) c.Assert(t, check.IsNil) }
func (s *S) TestAuthTokenMiddlewareWithInvalidToken(c *gocheck.C) { recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/", nil) c.Assert(err, gocheck.IsNil) request.Header.Set("Authorization", "bearer ifyougotozah'ha'dumyoulldie") h, log := doHandler() authTokenMiddleware(recorder, request, h) c.Assert(log.called, gocheck.Equals, true) t := context.GetAuthToken(request) c.Assert(t, gocheck.IsNil) }
func (s *S) TestAuthTokenMiddlewareWithToken(c *check.C) { recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/", nil) c.Assert(err, check.IsNil) request.Header.Set("Authorization", "bearer "+s.token.GetValue()) h, log := doHandler() authTokenMiddleware(recorder, request, h) c.Assert(log.called, check.Equals, true) t := context.GetAuthToken(request) c.Assert(t.GetValue(), check.Equals, s.token.GetValue()) c.Assert(t.GetUserName(), check.Equals, s.token.GetUserName()) }
func (s *S) TestAuthTokenMiddlewareWithIncorrectAppToken(c *gocheck.C) { token, err := nativeScheme.AppLogin("xyz") c.Assert(err, gocheck.IsNil) defer s.conn.Tokens().Remove(bson.M{"token": token.GetValue()}) recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/?:app=abc", nil) c.Assert(err, gocheck.IsNil) request.Header.Set("Authorization", "bearer "+token.GetValue()) h, log := doHandler() authTokenMiddleware(recorder, request, h) t := context.GetAuthToken(request) c.Assert(t, gocheck.IsNil) c.Assert(log.called, gocheck.Equals, true) }
func (s *S) TestAuthTokenMiddlewareWithInvalidAPIToken(c *check.C) { user := auth.User{Email: "*****@*****.**", APIKey: "347r3487rh3489hr34897rh487hr0377rg308rg32"} err := s.conn.Users().Insert(&user) c.Assert(err, check.IsNil) defer s.conn.Users().Remove(bson.M{"email": user.Email}) recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/", nil) c.Assert(err, check.IsNil) request.Header.Set("Authorization", "bearer 12eh923d8ydh238eun`1po2ueh1`p2") h, log := doHandler() authTokenMiddleware(recorder, request, h) c.Assert(log.called, check.Equals, true) t := context.GetAuthToken(request) c.Assert(t, check.IsNil) }
func (s *S) TestAuthTokenMiddlewareUserTokenForApp(c *check.C) { a := app.App{Name: "something", Teams: []string{s.team.Name}} err := s.conn.Apps().Insert(a) c.Assert(err, check.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/?:app=something", nil) c.Assert(err, check.IsNil) request.Header.Set("Authorization", "bearer "+s.token.GetValue()) h, log := doHandler() authTokenMiddleware(recorder, request, h) c.Assert(log.called, check.Equals, true) t := context.GetAuthToken(request) c.Assert(t.GetValue(), check.Equals, s.token.GetValue()) c.Assert(t.GetUserName(), check.Equals, s.token.GetUserName()) }
func (s *S) TestAuthTokenMiddlewareWithIncorrectAppToken(c *check.C) { token, err := nativeScheme.AppLogin("xyz") c.Assert(err, check.IsNil) defer s.conn.Tokens().Remove(bson.M{"token": token.GetValue()}) recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/?:app=abc", nil) c.Assert(err, check.IsNil) request.Header.Set("Authorization", "bearer "+token.GetValue()) h, log := doHandler() authTokenMiddleware(recorder, request, h) t := context.GetAuthToken(request) c.Assert(t, check.IsNil) c.Assert(log.called, check.Equals, false) err = context.GetRequestError(request) c.Assert(err, check.NotNil) e, ok := err.(*errors.HTTP) c.Assert(ok, check.Equals, true) c.Assert(e.Code, check.Equals, http.StatusForbidden) }
func remoteShellHandler(ws *websocket.Conn) { var httpErr *errors.HTTP defer func() { defer ws.Close() if httpErr != nil { var msg string switch httpErr.Code { case http.StatusUnauthorized: msg = "no token provided or session expired, please login again\n" default: msg = httpErr.Message + "\n" } ws.Write([]byte("Error: " + msg)) } }() r := ws.Request() token := context.GetAuthToken(r) if token == nil { httpErr = &errors.HTTP{ Code: http.StatusUnauthorized, Message: "no token provided", } return } appName := r.URL.Query().Get(":appname") a, err := getAppFromContext(appName, r) if err != nil { if herr, ok := err.(*errors.HTTP); ok { httpErr = herr } else { httpErr = &errors.HTTP{ Code: http.StatusInternalServerError, Message: err.Error(), } } return } allowed := permission.Check(token, permission.PermAppRunShell, contextsForApp(&a)...) if !allowed { httpErr = permission.ErrUnauthorized return } buf := &optionalWriterCloser{} var term *terminal.Terminal unitID := r.URL.Query().Get("unit") width, _ := strconv.Atoi(r.URL.Query().Get("width")) height, _ := strconv.Atoi(r.URL.Query().Get("height")) clientTerm := r.URL.Query().Get("term") evt, err := event.New(&event.Opts{ Target: appTarget(appName), Kind: permission.PermAppRunShell, Owner: token, CustomData: event.FormToCustomData(r.Form), Allowed: event.Allowed(permission.PermAppReadEvents, contextsForApp(&a)...), DisableLock: true, }) if err != nil { httpErr = &errors.HTTP{ Code: http.StatusInternalServerError, Message: err.Error(), } return } defer func() { var finalErr error if httpErr != nil { finalErr = httpErr } for term != nil { buf.disableWrite = true var line string line, err = term.ReadLine() if err != nil { break } fmt.Fprintf(evt, "> %s\n", line) } evt.Done(finalErr) }() term = terminal.NewTerminal(buf, "") opts := provision.ShellOptions{ Conn: &cmdLogger{base: ws, term: term}, Width: width, Height: height, Unit: unitID, Term: clientTerm, } err = a.Shell(opts) if err != nil { httpErr = &errors.HTTP{ Code: http.StatusInternalServerError, Message: err.Error(), } } }
func (m *appLockMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { if r.Method == "GET" { next(w, r) return } currentHandler := context.GetDelayedHandler(r) if currentHandler != nil { currentHandlerPtr := reflect.ValueOf(currentHandler).Pointer() for _, h := range m.excludedHandlers { if reflect.ValueOf(h).Pointer() == currentHandlerPtr { next(w, r) return } } } appName := r.URL.Query().Get(":app") if appName == "" { appName = r.URL.Query().Get(":appname") } if appName == "" { next(w, r) return } t := context.GetAuthToken(r) var owner string if t != nil { if t.IsAppToken() { owner = t.GetAppName() } else { owner = t.GetUserName() } } _, err := app.GetByName(appName) if err == app.ErrAppNotFound { context.AddRequestError(r, &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}) return } ok, err := app.AcquireApplicationLockWait(appName, owner, fmt.Sprintf("%s %s", r.Method, r.URL.Path), lockWaitDuration) if err != nil { context.AddRequestError(r, fmt.Errorf("Error trying to acquire application lock: %s", err)) return } if ok { defer func() { if !context.IsPreventUnlock(r) { app.ReleaseApplicationLock(appName) } }() next(w, r) return } a, err := app.GetByName(appName) httpErr := &errors.HTTP{Code: http.StatusInternalServerError} if err != nil { if err == app.ErrAppNotFound { httpErr.Code = http.StatusNotFound httpErr.Message = err.Error() } else { httpErr.Message = fmt.Sprintf("Error to get application: %s", err) } } else { httpErr.Code = http.StatusConflict if a.Lock.Locked { httpErr.Message = fmt.Sprintf("%s", &a.Lock) } else { httpErr.Message = "Not locked anymore, please try again." } } context.AddRequestError(r, httpErr) }