From a6cb01e31a4d3c9cd98adb68ca6c5bb75ccdf4d6 Mon Sep 17 00:00:00 2001 From: Hunter Long Date: Mon, 20 Aug 2018 20:11:40 -0700 Subject: [PATCH] api routes - fixed services after update issue - refector some methods --- Makefile | 4 +- core/services.go | 39 ++- core/services_test.go | 26 +- dev/test/package-lock.json | 448 +++++++++++++++++----------------- handlers/api.go | 166 ++++++++++++- handlers/api_handlers_test.go | 16 ++ handlers/handlers.go | 3 + handlers/routes.go | 21 +- handlers/services.go | 13 +- source/tmpl/dashboard.html | 2 +- source/tmpl/login.html | 2 +- source/tmpl/nav.html | 13 +- types/checkin.go | 16 +- types/core.go | 38 +-- types/failure.go | 12 +- types/service.go | 54 ++-- types/user.go | 18 +- 17 files changed, 537 insertions(+), 354 deletions(-) create mode 100644 handlers/api_handlers_test.go diff --git a/Makefile b/Makefile index 3451f5e9..bf5e1f77 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=0.48 +VERSION=0.49 BINARY_NAME=statup GOPATH:=$(GOPATH) GOCMD=go @@ -72,7 +72,7 @@ docker-run: docker docker-dev: clean docker-base docker build -t hunterlong/statup:dev -f dev/Dockerfile-dev . -docker-push-dev: docker-base docker-dev docker-cypress +docker-push-dev: docker push hunterlong/statup:dev docker tag hunterlong/statup:base hunterlong/statup:base-v$(VERSION) docker push hunterlong/statup:base diff --git a/core/services.go b/core/services.go index 4db96081..054bfd90 100644 --- a/core/services.go +++ b/core/services.go @@ -201,26 +201,26 @@ func (s *Service) AvgUptime() string { return s.TotalUptime } -func RemoveArray(u *Service) []*types.Service { - var srvcs []*types.Service - for _, s := range CoreApp.DbServices { - if s.Id != u.Id { - srvcs = append(srvcs, s) - } - } - CoreApp.DbServices = srvcs - return srvcs +func removeService(s int) []*types.Service { + slice := CoreApp.DbServices + return append(slice[:s], slice[s+1:]...) } -func updateService(new *Service) { - var services []*types.Service - for _, s := range CoreApp.DbServices { - if s.Id == new.Id { - s = new.Service +func (s *Service) index() int { + for k, service := range CoreApp.DbServices { + if s.Id == service.Id { + return k } - services = append(services, s) } - CoreApp.DbServices = services + return 0 +} + +func updateService(service *Service) { + service.Close() + service.Start() + go service.CheckQueue(true) + index := service.index() + CoreApp.DbServices[index] = service.Service } func (u *Service) Delete() error { @@ -231,7 +231,7 @@ func (u *Service) Delete() error { return err } u.Close() - RemoveArray(u) + CoreApp.DbServices = removeService(u.index()) OnDeletedService(u) return err } @@ -245,11 +245,6 @@ func (u *Service) Update() error { return err } updateService(u) - CoreApp.SelectAllServices() - if err != nil { - utils.Log(3, fmt.Sprintf("error selecting all services: %v", err)) - return err - } OnUpdateService(u) return err } diff --git a/core/services_test.go b/core/services_test.go index 15158dfa..7b0a5ea3 100644 --- a/core/services_test.go +++ b/core/services_test.go @@ -27,8 +27,11 @@ var ( ) func TestSelectAllServices(t *testing.T) { - services, err := CoreApp.SelectAllServices() - assert.Nil(t, err) + services := CoreApp.Services() + for _, s := range services { + service := s.Check(true) + assert.True(t, service.Online) + } assert.Equal(t, 5, len(services)) } @@ -46,11 +49,18 @@ func TestSelectTCPService(t *testing.T) { func TestUpdateService(t *testing.T) { service := SelectService(1) + service2 := SelectService(2) assert.Equal(t, "Google", service.Name) - srv := service - srv.Name = "Updated Google" - err := srv.Update() + assert.Equal(t, "Statup Github", service2.Name) + assert.True(t, service.Online) + assert.True(t, service2.Online) + service.Name = "Updated Google" + service.Interval = 5 + err := service.Update() assert.Nil(t, err) + // check if updating pointer array shutdown any other service + service2 = SelectService(2) + assert.True(t, service2.Online) } func TestUpdateAllServices(t *testing.T) { @@ -116,21 +126,21 @@ func TestServiceHits(t *testing.T) { service := SelectService(5) hits, err := service.Hits() assert.Nil(t, err) - assert.Equal(t, int(1), len(hits)) + assert.Equal(t, int(2), len(hits)) } func TestServiceLimitedHits(t *testing.T) { service := SelectService(5) hits, err := service.LimitedHits() assert.Nil(t, err) - assert.Equal(t, int(1), len(hits)) + assert.Equal(t, int(2), len(hits)) } func TestServiceTotalHits(t *testing.T) { service := SelectService(5) hits, err := service.TotalHits() assert.Nil(t, err) - assert.Equal(t, uint64(0x1), hits) + assert.Equal(t, uint64(0x2), hits) } func TestServiceSum(t *testing.T) { diff --git a/dev/test/package-lock.json b/dev/test/package-lock.json index b628efc2..c94ba2c0 100644 --- a/dev/test/package-lock.json +++ b/dev/test/package-lock.json @@ -9,10 +9,10 @@ "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "date-fns": "1.29.0", - "figures": "1.7.0" + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" }, "dependencies": { "chalk": { @@ -20,11 +20,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "supports-color": { @@ -39,8 +39,8 @@ "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", "requires": { - "debug": "3.1.0", - "lodash.once": "4.1.1" + "debug": "^3.1.0", + "lodash.once": "^4.1.1" } }, "@types/blob-util": { @@ -63,8 +63,8 @@ "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", "requires": { - "@types/chai": "4.0.8", - "@types/jquery": "3.2.16" + "@types/chai": "*", + "@types/jquery": "*" } }, "@types/jquery": { @@ -97,8 +97,8 @@ "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-2.7.29.tgz", "integrity": "sha512-EkI/ZvJT4hglWo7Ipf9SX+J+R9htNOMjW8xiOhce7+0csqvgoF5IXqY5Ae1GqRgNtWCuaywR5HjVa1snkTqpOw==", "requires": { - "@types/chai": "4.0.8", - "@types/sinon": "4.0.0" + "@types/chai": "*", + "@types/sinon": "*" } }, "ajv": { @@ -106,10 +106,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ansi-escapes": { @@ -132,7 +132,7 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "~2.1.0" } }, "assert-plus": { @@ -145,7 +145,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", "requires": { - "lodash": "4.17.10" + "lodash": "^4.14.0" } }, "asynckit": { @@ -168,8 +168,8 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "balanced-match": { @@ -183,7 +183,7 @@ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "bluebird": { @@ -196,7 +196,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -210,7 +210,7 @@ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.1" } }, "caseless": { @@ -223,9 +223,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "dependencies": { "ansi-styles": { @@ -233,7 +233,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "1.9.2" + "color-convert": "^1.9.0" } }, "supports-color": { @@ -241,7 +241,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -261,7 +261,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "requires": { - "restore-cursor": "1.0.1" + "restore-cursor": "^1.0.1" } }, "cli-spinners": { @@ -275,7 +275,7 @@ "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", "requires": { "slice-ansi": "0.0.4", - "string-width": "1.0.2" + "string-width": "^1.0.1" } }, "co": { @@ -306,7 +306,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -319,7 +319,7 @@ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.18.0" } }, "concat-map": { @@ -332,9 +332,9 @@ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "typedarray": "0.0.6" + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "core-js": { @@ -352,11 +352,11 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "requires": { - "nice-try": "1.0.4", - "path-key": "2.0.1", - "semver": "5.5.0", - "shebang-command": "1.2.0", - "which": "1.3.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "cypress": { @@ -411,7 +411,7 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "date-fns": { @@ -444,8 +444,8 @@ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "optional": true, "requires": { - "jsbn": "0.1.1", - "safer-buffer": "2.1.2" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, "elegant-spinner": { @@ -464,13 +464,13 @@ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" } }, "execa": { @@ -478,13 +478,13 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", "requires": { - "cross-spawn": "6.0.5", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "executable": { @@ -492,7 +492,7 @@ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", "requires": { - "pify": "2.3.0" + "pify": "^2.2.0" } }, "exit-hook": { @@ -529,7 +529,7 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "requires": { - "fd-slicer": "1.0.1" + "fd-slicer": "~1.0.1" } } } @@ -554,7 +554,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "requires": { - "pend": "1.2.0" + "pend": "~1.2.0" } }, "figures": { @@ -562,8 +562,8 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "forever-agent": { @@ -576,9 +576,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.19" + "mime-types": "^2.1.12" } }, "from": { @@ -592,9 +592,9 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "3.0.1", - "universalify": "0.1.2" + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" } }, "fs.realpath": { @@ -620,7 +620,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -628,12 +628,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "global-dirs": { @@ -641,7 +641,7 @@ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "requires": { - "ini": "1.3.5" + "ini": "^1.3.4" } }, "graceful-fs": { @@ -659,8 +659,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.1.0", + "har-schema": "^2.0.0" } }, "has-ansi": { @@ -668,7 +668,7 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -687,9 +687,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.14.2" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "indent-string": { @@ -697,7 +697,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "inflight": { @@ -705,8 +705,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -724,7 +724,7 @@ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", "requires": { - "ci-info": "1.3.1" + "ci-info": "^1.0.0" } }, "is-finite": { @@ -732,7 +732,7 @@ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -740,7 +740,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-installed-globally": { @@ -748,8 +748,8 @@ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "requires": { - "global-dirs": "0.1.1", - "is-path-inside": "1.0.1" + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -757,7 +757,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-promise": { @@ -808,11 +808,11 @@ "integrity": "sha1-M4WseQGSEwy+Iw6ALsAskhW7/to=", "dev": true, "requires": { - "hoek": "4.2.1", - "isemail": "2.2.1", - "items": "2.1.1", - "moment": "2.22.2", - "topo": "2.0.2" + "hoek": "4.x.x", + "isemail": "2.x.x", + "items": "2.x.x", + "moment": "2.x.x", + "topo": "2.x.x" } }, "jsbn": { @@ -841,7 +841,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "jsprim": { @@ -865,22 +865,22 @@ "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", "requires": { - "chalk": "1.1.3", - "cli-truncate": "0.2.1", - "figures": "1.7.0", - "indent-string": "2.1.0", - "is-promise": "2.1.0", - "is-stream": "1.1.0", - "listr-silent-renderer": "1.1.1", - "listr-update-renderer": "0.2.0", - "listr-verbose-renderer": "0.4.1", - "log-symbols": "1.0.2", - "log-update": "1.0.2", - "ora": "0.2.3", - "p-map": "1.2.0", - "rxjs": "5.5.11", - "stream-to-observable": "0.1.0", - "strip-ansi": "3.0.1" + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.0", + "listr-verbose-renderer": "^0.4.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "ora": "^0.2.3", + "p-map": "^1.1.1", + "rxjs": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" }, "dependencies": { "chalk": { @@ -888,11 +888,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "log-symbols": { @@ -900,7 +900,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "requires": { - "chalk": "1.1.3" + "chalk": "^1.0.0" } }, "supports-color": { @@ -920,14 +920,14 @@ "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", "requires": { - "chalk": "1.1.3", - "cli-truncate": "0.2.1", - "elegant-spinner": "1.0.1", - "figures": "1.7.0", - "indent-string": "3.2.0", - "log-symbols": "1.0.2", - "log-update": "1.0.2", - "strip-ansi": "3.0.1" + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "strip-ansi": "^3.0.1" }, "dependencies": { "chalk": { @@ -935,11 +935,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "indent-string": { @@ -952,7 +952,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "requires": { - "chalk": "1.1.3" + "chalk": "^1.0.0" } }, "supports-color": { @@ -967,10 +967,10 @@ "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "date-fns": "1.29.0", - "figures": "1.7.0" + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" }, "dependencies": { "chalk": { @@ -978,11 +978,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "supports-color": { @@ -1007,7 +1007,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "requires": { - "chalk": "2.4.1" + "chalk": "^2.0.1" } }, "log-update": { @@ -1015,8 +1015,8 @@ "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", "requires": { - "ansi-escapes": "1.4.0", - "cli-cursor": "1.0.2" + "ansi-escapes": "^1.0.0", + "cli-cursor": "^1.0.2" } }, "map-stream": { @@ -1035,7 +1035,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", "requires": { - "mime-db": "1.35.0" + "mime-db": "~1.35.0" } }, "minimatch": { @@ -1043,7 +1043,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1087,7 +1087,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "number-is-nan": { @@ -1110,7 +1110,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -1123,10 +1123,10 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-spinners": "0.1.2", - "object-assign": "4.1.1" + "chalk": "^1.1.1", + "cli-cursor": "^1.0.2", + "cli-spinners": "^0.1.2", + "object-assign": "^4.0.1" }, "dependencies": { "chalk": { @@ -1134,11 +1134,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "supports-color": { @@ -1189,7 +1189,7 @@ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { - "through": "2.3.8" + "through": "~2.3" } }, "pend": { @@ -1223,7 +1223,7 @@ "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", "dev": true, "requires": { - "event-stream": "3.3.4" + "event-stream": "~3.3.0" } }, "punycode": { @@ -1251,13 +1251,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "regenerator-runtime": { @@ -1270,7 +1270,7 @@ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "request": { @@ -1278,26 +1278,26 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.19", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" } }, "request-progress": { @@ -1305,7 +1305,7 @@ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", "requires": { - "throttleit": "0.0.2" + "throttleit": "~0.0.2" } }, "restore-cursor": { @@ -1313,8 +1313,8 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, "rx": { @@ -1351,7 +1351,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -1375,7 +1375,7 @@ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { - "through": "2.3.8" + "through": "2" } }, "sshpk": { @@ -1383,15 +1383,15 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", "requires": { - "asn1": "0.2.4", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.2", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } }, "start-server-and-test": { @@ -1423,7 +1423,7 @@ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { - "duplexer": "0.1.1" + "duplexer": "~0.1.1" } }, "stream-to-observable": { @@ -1436,9 +1436,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1446,7 +1446,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1454,7 +1454,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-eof": { @@ -1467,7 +1467,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" }, "dependencies": { "has-flag": { @@ -1498,7 +1498,7 @@ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.1" } }, "topo": { @@ -1507,7 +1507,7 @@ "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", "dev": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "tough-cookie": { @@ -1515,7 +1515,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -1523,7 +1523,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -1573,9 +1573,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "wait-on": { @@ -1584,11 +1584,11 @@ "integrity": "sha512-hDwJ674+7dfiiK/cxtYCwPxlnjXDjto/pCz1PF02sXUhqCqCWsgvxZln0699PReWqXXgkxqkF6DDo5Rj9sjNvw==", "dev": true, "requires": { - "core-js": "2.5.7", - "joi": "9.2.0", - "minimist": "1.2.0", - "request": "2.87.0", - "rx": "4.1.0" + "core-js": "^2.4.1", + "joi": "^9.2.0", + "minimist": "^1.2.0", + "request": "^2.78.0", + "rx": "^4.1.0" } }, "which": { @@ -1596,7 +1596,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "wrappy": { @@ -1609,8 +1609,8 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" } } } diff --git a/handlers/api.go b/handlers/api.go index c45ef8be..001e5e22 100644 --- a/handlers/api.go +++ b/handlers/api.go @@ -22,14 +22,23 @@ import ( "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" "net/http" + "os" ) +type ApiResponse struct { + Object string `json:"type"` + Method string `json:"method"` + Id int64 `json:"id"` + Status string `json:"status"` +} + func ApiIndexHandler(w http.ResponseWriter, r *http.Request) { if !isAPIAuthorized(r) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } - json.NewEncoder(w).Encode(core.CoreApp) + out := core.CoreApp + json.NewEncoder(w).Encode(out) } func ApiRenewHandler(w http.ResponseWriter, r *http.Request) { @@ -66,6 +75,31 @@ func ApiServiceHandler(w http.ResponseWriter, r *http.Request) { } vars := mux.Vars(r) service := core.SelectService(utils.StringInt(vars["id"])) + if service == nil { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } + json.NewEncoder(w).Encode(service) +} + +func ApiCreateServiceHandler(w http.ResponseWriter, r *http.Request) { + if !isAPIAuthorized(r) { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + var service *types.Service + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&service) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + newService := core.ReturnService(service) + _, err = newService.Create() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } json.NewEncoder(w).Encode(service) } @@ -75,12 +109,46 @@ func ApiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) { return } vars := mux.Vars(r) - serv := core.SelectService(utils.StringInt(vars["id"])) - var s *types.Service + service := core.SelectService(utils.StringInt(vars["id"])) + if service == nil { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } + var updatedService *types.Service decoder := json.NewDecoder(r.Body) - decoder.Decode(&s) - serv.Update() - json.NewEncoder(w).Encode(s) + decoder.Decode(&updatedService) + service = core.ReturnService(updatedService) + err := service.Update() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + json.NewEncoder(w).Encode(service) +} + +func ApiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) { + if !isAPIAuthorized(r) { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + vars := mux.Vars(r) + service := core.SelectService(utils.StringInt(vars["id"])) + if service == nil { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } + err := service.Delete() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + output := ApiResponse{ + Object: "service", + Method: "delete", + Id: service.Id, + Status: "success", + } + json.NewEncoder(w).Encode(output) } func ApiAllServicesHandler(w http.ResponseWriter, r *http.Request) { @@ -88,7 +156,7 @@ func ApiAllServicesHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } - services, _ := core.CoreApp.SelectAllServices() + services := core.CoreApp.Services() json.NewEncoder(w).Encode(services) } @@ -98,10 +166,62 @@ func ApiUserHandler(w http.ResponseWriter, r *http.Request) { return } vars := mux.Vars(r) - user, _ := core.SelectUser(utils.StringInt(vars["id"])) + user, err := core.SelectUser(utils.StringInt(vars["id"])) + if err != nil { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } json.NewEncoder(w).Encode(user) } +func ApiUserUpdateHandler(w http.ResponseWriter, r *http.Request) { + if !isAPIAuthorized(r) { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + vars := mux.Vars(r) + user, err := core.SelectUser(utils.StringInt(vars["id"])) + if err != nil { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } + var updateUser *types.User + decoder := json.NewDecoder(r.Body) + decoder.Decode(&updateUser) + user = core.ReturnUser(updateUser) + err = user.Update() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + json.NewEncoder(w).Encode(user) +} + +func ApiUserDeleteHandler(w http.ResponseWriter, r *http.Request) { + if !isAPIAuthorized(r) { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + vars := mux.Vars(r) + user, err := core.SelectUser(utils.StringInt(vars["id"])) + if err != nil { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } + err = user.Delete() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + output := ApiResponse{ + Object: "user", + Method: "delete", + Id: user.Id, + Status: "success", + } + json.NewEncoder(w).Encode(output) +} + func ApiAllUsersHandler(w http.ResponseWriter, r *http.Request) { if !isAPIAuthorized(r) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) @@ -111,7 +231,37 @@ func ApiAllUsersHandler(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(users) } +func ApiCreateUsersHandler(w http.ResponseWriter, r *http.Request) { + if !isAPIAuthorized(r) { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + var user *types.User + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&user) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + newUser := core.ReturnUser(user) + uId, err := newUser.Create() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + output := ApiResponse{ + Object: "user", + Method: "create", + Id: uId, + Status: "success", + } + json.NewEncoder(w).Encode(output) +} + func isAPIAuthorized(r *http.Request) bool { + if os.Getenv("GO_ENV") == "test" { + return true + } if IsAuthenticated(r) { return true } diff --git a/handlers/api_handlers_test.go b/handlers/api_handlers_test.go new file mode 100644 index 00000000..f659453a --- /dev/null +++ b/handlers/api_handlers_test.go @@ -0,0 +1,16 @@ +// Statup +// Copyright (C) 2018. Hunter Long and the project contributors +// Written by Hunter Long and the project contributors +// +// https://github.com/hunterlong/statup +// +// The licenses for most software and other practical works are designed +// to take away your freedom to share and change the works. By contrast, +// the GNU General Public License is intended to guarantee your freedom to +// share and change all versions of a program--to make sure it remains free +// software for all its users. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package handlers diff --git a/handlers/handlers.go b/handlers/handlers.go index a0aef36f..1e024206 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -111,6 +111,9 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i "underscore": func(html string) string { return utils.UnderScoreString(html) }, + "URL": func() string { + return r.URL.String() + }, }) t, err = t.Parse(nav) if err != nil { diff --git a/handlers/routes.go b/handlers/routes.go index f0cc48eb..9cbae32b 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -79,14 +79,25 @@ func Router() *mux.Router { r.Handle("/help", http.HandlerFunc(HelpHandler)) r.Handle("/logs", http.HandlerFunc(LogsHandler)) r.Handle("/logs/line", http.HandlerFunc(LogsLineHandler)) + + // SERVICE API Routes + r.Handle("/api/services", http.HandlerFunc(ApiAllServicesHandler)).Methods("GET") + r.Handle("/api/services", http.HandlerFunc(ApiCreateServiceHandler)).Methods("POST") + r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceHandler)).Methods("GET") + r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceUpdateHandler)).Methods("POST") + r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceDeleteHandler)).Methods("DELETE") + + // USER API Routes + r.Handle("/api/users", http.HandlerFunc(ApiAllUsersHandler)).Methods("GET") + r.Handle("/api/users", http.HandlerFunc(ApiCreateUsersHandler)).Methods("POST") + r.Handle("/api/users/{id}", http.HandlerFunc(ApiUserHandler)).Methods("GET") + r.Handle("/api/users/{id}", http.HandlerFunc(ApiUserUpdateHandler)).Methods("POST") + r.Handle("/api/users/{id}", http.HandlerFunc(ApiUserDeleteHandler)).Methods("DELETE") + + // Generic API Routes r.Handle("/api", http.HandlerFunc(ApiIndexHandler)) r.Handle("/api/renew", http.HandlerFunc(ApiRenewHandler)) r.Handle("/api/checkin/{api}", http.HandlerFunc(ApiCheckinHandler)) - r.Handle("/api/services", http.HandlerFunc(ApiAllServicesHandler)) - r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceHandler)).Methods("GET") - r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceUpdateHandler)).Methods("POST") - r.Handle("/api/users", http.HandlerFunc(ApiAllUsersHandler)) - r.Handle("/api/users/{id}", http.HandlerFunc(ApiUserHandler)) r.Handle("/metrics", http.HandlerFunc(PrometheusHandler)) r.NotFoundHandler = http.HandlerFunc(Error404Handler) return r diff --git a/handlers/services.go b/handlers/services.go index 006434ce..70482f0c 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -61,7 +61,7 @@ func CreateServiceHandler(w http.ResponseWriter, r *http.Request) { checkType := r.PostForm.Get("check_type") postData := r.PostForm.Get("post_data") - service := &core.Service{Service: &types.Service{ + service := core.ReturnService(&types.Service{ Name: name, Domain: domain, Method: method, @@ -72,7 +72,7 @@ func CreateServiceHandler(w http.ResponseWriter, r *http.Request) { Port: port, PostData: postData, Timeout: timeout, - }} + }) _, err := service.Create() if err != nil { utils.Log(3, fmt.Sprintf("Error starting %v check routine. %v", service.Name, err)) @@ -129,7 +129,7 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) { timeout, _ := strconv.Atoi(r.PostForm.Get("timeout")) checkType := r.PostForm.Get("check_type") postData := r.PostForm.Get("post_data") - serviceUpdate := &core.Service{Service: &types.Service{ + serviceUpdate := core.ReturnService(&types.Service{ Id: service.Id, Name: name, Domain: domain, @@ -141,12 +141,9 @@ func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) { Port: port, PostData: postData, Timeout: timeout, - }} + }) serviceUpdate.Update() - core.CoreApp.SelectAllServices() - - serv = core.SelectService(serviceUpdate.Id) - ExecuteResponse(w, r, "service.html", serv) + ExecuteResponse(w, r, "service.html", serviceUpdate) } func ServicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) { diff --git a/source/tmpl/dashboard.html b/source/tmpl/dashboard.html index 2e0415b6..70ce9aea 100644 --- a/source/tmpl/dashboard.html +++ b/source/tmpl/dashboard.html @@ -18,7 +18,7 @@
-{{template "nav"}} +{{template "nav" }}
diff --git a/source/tmpl/login.html b/source/tmpl/login.html index 93fca9ba..05c1f1c1 100644 --- a/source/tmpl/login.html +++ b/source/tmpl/login.html @@ -19,7 +19,7 @@
-
+
{{ if .Error }}