From e13aff389b93390faef636743e167918e2092d0b Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Fri, 16 Feb 2018 21:43:31 +0100 Subject: [PATCH] Add swagger documentation --- docs/docs-packr.go | 15 + docs/package.go | 38 ++ docs/spec.json | 1172 ++++++++++++++++++++++++++++++++++++++++++++ docs/swagger.go | 17 + router/router.go | 606 ++++++++++++++++++++++- 5 files changed, 1847 insertions(+), 1 deletion(-) create mode 100644 docs/docs-packr.go create mode 100644 docs/package.go create mode 100644 docs/spec.json create mode 100644 docs/swagger.go diff --git a/docs/docs-packr.go b/docs/docs-packr.go new file mode 100644 index 0000000..7c7f5c8 --- /dev/null +++ b/docs/docs-packr.go @@ -0,0 +1,15 @@ +package docs + +import "github.com/gobuffalo/packr" + +// !!! GENERATED FILE !!! +// Do NOT hand edit this file!! +// It is recommended that you DO NOT check into this file into SCM. +// We STRONGLY recommend you delete this file after you have built your +// Go binary. You can use the "packr clean" command to clean up this, +// and any other packr generated files. +func init() { + packr.PackJSONBytes("./", "package.go", "\"Ly8gUGFja2FnZSBkb2NzIEdvdGlmeSBSRVNULUFQSS4NCi8vDQovLyBUaGlzIGlzIHRoZSBkb2N1bWVudGF0aW9uIG9mIHRoZSBHb3RpZnkgUkVTVC1BUEkuDQovLw0KLy8gICAgIFNjaGVtZXM6IGh0dHAsIGh0dHBzDQovLyAgICAgSG9zdDogbG9jYWxob3N0DQovLyAgICAgVmVyc2lvbjogMS4wLjANCi8vICAgICBMaWNlbnNlOiBNSVQgaHR0cHM6Ly9naXRodWIuY29tL2dvdGlmeS9zZXJ2ZXIvYmxvYi9tYXN0ZXIvTElDRU5TRQ0KLy8gICAgIENvbnRhY3Q6IGh0dHBzOi8vZ2l0aHViLmNvbS9nb3RpZnkvc2VydmVyL2lzc3Vlcw0KLy8NCi8vICAgICBDb25zdW1lczoNCi8vICAgICAtIGFwcGxpY2F0aW9uL2pzb24NCi8vDQovLyAgICAgUHJvZHVjZXM6DQovLyAgICAgLSBhcHBsaWNhdGlvbi9qc29uDQovLw0KLy8gICAgIFNlY3VyaXR5RGVmaW5pdGlvbnM6DQovLyAgICAgICAgYXBwVG9rZW5RdWVyeToNCi8vICAgICAgICAgICB0eXBlOiBhcGlLZXkNCi8vICAgICAgICAgICBuYW1lOiB0b2tlbg0KLy8gICAgICAgICAgIGluOiBxdWVyeQ0KLy8gICAgICAgIGNsaWVudFRva2VuUXVlcnk6DQovLyAgICAgICAgICAgdHlwZTogYXBpS2V5DQovLyAgICAgICAgICAgbmFtZTogdG9rZW4NCi8vICAgICAgICAgICBpbjogcXVlcnkNCi8vIAkgICAgICBhcHBUb2tlbkhlYWRlcjoNCi8vICAgICAgICAgICB0eXBlOiBhcGlLZXkNCi8vICAgICAgICAgICBuYW1lOiBYLUdvdGlmeS1LZXkNCi8vICAgICAgICAgICBpbjogaGVhZGVyDQovLyAJICAgICAgY2xpZW50VG9rZW5IZWFkZXI6DQovLyAgICAgICAgICAgdHlwZTogYXBpS2V5DQovLyAgICAgICAgICAgbmFtZTogWC1Hb3RpZnktS2V5DQovLyAgICAgICAgICAgaW46IGhlYWRlcg0KLy8gICAgICAgIGJhc2ljQXV0aDoNCi8vICAgICAgICAgICB0eXBlOiBiYXNpYw0KLy8NCi8vIHN3YWdnZXI6bWV0YQ0KcGFja2FnZSBkb2NzDQo=\"") + packr.PackJSONBytes("./", "spec.json", "\"ewogICJjb25zdW1lcyI6IFsKICAgICJhcHBsaWNhdGlvbi9qc29uIgogIF0sCiAgInByb2R1Y2VzIjogWwogICAgImFwcGxpY2F0aW9uL2pzb24iCiAgXSwKICAic2NoZW1lcyI6IFsKICAgICJodHRwIiwKICAgICJodHRwcyIKICBdLAogICJzd2FnZ2VyIjogIjIuMCIsCiAgImluZm8iOiB7CiAgICAiZGVzY3JpcHRpb24iOiAiVGhpcyBpcyB0aGUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgR290aWZ5IFJFU1QtQVBJLiIsCiAgICAidGl0bGUiOiAiR290aWZ5IFJFU1QtQVBJLiIsCiAgICAiY29udGFjdCI6IHsKICAgICAgInVybCI6ICJodHRwczovL2dpdGh1Yi5jb20vZ290aWZ5L3NlcnZlci9pc3N1ZXMiCiAgICB9LAogICAgImxpY2Vuc2UiOiB7CiAgICAgICJuYW1lIjogIk1JVCIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9naXRodWIuY29tL2dvdGlmeS9zZXJ2ZXIvYmxvYi9tYXN0ZXIvTElDRU5TRSIKICAgIH0sCiAgICAidmVyc2lvbiI6ICIxLjAuMCIKICB9LAogICJob3N0IjogImxvY2FsaG9zdCIsCiAgInBhdGhzIjogewogICAgIi9hcHBsaWNhdGlvbiI6IHsKICAgICAgImdldCI6IHsKICAgICAgICAic2VjdXJpdHkiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlbkhlYWRlciI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5RdWVyeSI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiYmFzaWNBdXRoIjogW10KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJjb25zdW1lcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJ0b2tlbiIKICAgICAgICBdLAogICAgICAgICJzdW1tYXJ5IjogIlJldHVybiBhbGwgYXBwbGljYXRpb25zLiIsCiAgICAgICAgIm9wZXJhdGlvbklkIjogImdldEFwcHMiLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0FwcGxpY2F0aW9uIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAzIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9yYmlkZGVuIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICAicG9zdCI6IHsKICAgICAgICAic2VjdXJpdHkiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlbkhlYWRlciI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5RdWVyeSI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiYmFzaWNBdXRoIjogW10KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJjb25zdW1lcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJ0b2tlbiIKICAgICAgICBdLAogICAgICAgICJzdW1tYXJ5IjogIkNyZWF0ZSBhbiBhcHBsaWNhdGlvbi4iLAogICAgICAgICJvcGVyYXRpb25JZCI6ICJjcmVhdGVBcHAiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAidGhlIGFwcGxpY2F0aW9uIHRvIGFkZCIsCiAgICAgICAgICAgICJuYW1lIjogImJvZHkiLAogICAgICAgICAgICAiaW4iOiAiYm9keSIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IHRydWUsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9BcHBsaWNhdGlvbiIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9BcHBsaWNhdGlvbiIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAzIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9yYmlkZGVuIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgIi9hcHBsaWNhdGlvbi97aWR9IjogewogICAgICAiZGVsZXRlIjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJiYXNpY0F1dGgiOiBbXQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgImNvbnN1bWVzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgInRva2VuIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiRGVsZXRlIGFuIGFwcGxpY2F0aW9uLiIsCiAgICAgICAgIm9wZXJhdGlvbklkIjogImRlbGV0ZUFwcCIsCiAgICAgICAgInBhcmFtZXRlcnMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJ0aGUgYXBwbGljYXRpb24gaWQiLAogICAgICAgICAgICAibmFtZSI6ICJpZCIsCiAgICAgICAgICAgICJpbiI6ICJwYXRoIiwKICAgICAgICAgICAgInJlcXVpcmVkIjogdHJ1ZQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIKICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICIvYXBwbGljYXRpb24ve2lkfS9tZXNzYWdlIjogewogICAgICAiZ2V0IjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJiYXNpY0F1dGgiOiBbXQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJtZXNzYWdlIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiUmV0dXJuIGFsbCBtZXNzYWdlcyBmcm9tIGEgc3BlY2lmaWMgYXBwbGljYXRpb24uIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAiZ2V0QXBwTWVzc2FnZXMiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAidGhlIGFwcGxpY2F0aW9uIGlkIiwKICAgICAgICAgICAgIm5hbWUiOiAiaWQiLAogICAgICAgICAgICAiaW4iOiAicGF0aCIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IHRydWUKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL01lc3NhZ2UiCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVuYXV0aG9yaXplZCIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDMiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJGb3JiaWRkZW4iLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgICJkZWxldGUiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgIm1lc3NhZ2UiCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJEZWxldGUgYWxsIG1lc3NhZ2VzIGZyb20gYSBzcGVjaWZpYyBhcHBsaWNhdGlvbi4iLAogICAgICAgICJvcGVyYXRpb25JZCI6ICJkZWxldGVBcHBNZXNzYWdlcyIsCiAgICAgICAgInBhcmFtZXRlcnMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJ0aGUgYXBwbGljYXRpb24gaWQiLAogICAgICAgICAgICAibmFtZSI6ICJpZCIsCiAgICAgICAgICAgICJpbiI6ICJwYXRoIiwKICAgICAgICAgICAgInJlcXVpcmVkIjogdHJ1ZQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIKICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICIvY2xpZW50IjogewogICAgICAiZ2V0IjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJiYXNpY0F1dGgiOiBbXQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgImNvbnN1bWVzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgInRva2VuIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiUmV0dXJuIGFsbCBjbGllbnRzLiIsCiAgICAgICAgIm9wZXJhdGlvbklkIjogImdldENsaWVudHMiLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0NsaWVudCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgInBvc3QiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY29uc3VtZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJwcm9kdWNlcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInRhZ3MiOiBbCiAgICAgICAgICAidG9rZW4iCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJDcmVhdGUgYSBjbGllbnQuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAiY3JlYXRlQ2xpZW50IiwKICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogInRoZSBjbGllbnQgdG8gYWRkIiwKICAgICAgICAgICAgIm5hbWUiOiAiYm9keSIsCiAgICAgICAgICAgICJpbiI6ICJib2R5IiwKICAgICAgICAgICAgInJlcXVpcmVkIjogdHJ1ZSwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0NsaWVudCIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9DbGllbnQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICIvY2xpZW50L3tpZH0iOiB7CiAgICAgICJkZWxldGUiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY29uc3VtZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJwcm9kdWNlcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInRhZ3MiOiBbCiAgICAgICAgICAidG9rZW4iCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJEZWxldGUgYSBjbGllbnQuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAiZGVsZXRlQ2xpZW50IiwKICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogInRoZSBjbGllbnQgaWQiLAogICAgICAgICAgICAibmFtZSI6ICJpZCIsCiAgICAgICAgICAgICJpbiI6ICJwYXRoIiwKICAgICAgICAgICAgInJlcXVpcmVkIjogdHJ1ZQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIKICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICIvY3VycmVudC91c2VyIjogewogICAgICAiZ2V0IjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJiYXNpY0F1dGgiOiBbXQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJ1c2VyIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiUmV0dXJuIHRoZSBjdXJyZW50IHVzZXIuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAiY3VycmVudFVzZXIiLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvVXNlciIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAzIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9yYmlkZGVuIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgIi9jdXJyZW50L3VzZXIvcGFzc3dvcmQiOiB7CiAgICAgICJwb3N0IjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJiYXNpY0F1dGgiOiBbXQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgImNvbnN1bWVzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgInVzZXIiCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJVcGRhdGUgdGhlIHBhc3N3b3JkIG9mIHRoZSBjdXJyZW50IHVzZXIuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAidXBkYXRlQ3VycmVudFVzZXIiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAidGhlIHVzZXIiLAogICAgICAgICAgICAibmFtZSI6ICJib2R5IiwKICAgICAgICAgICAgImluIjogImJvZHkiLAogICAgICAgICAgICAicmVxdWlyZWQiOiB0cnVlLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvVXNlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIKICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICIvbWVzc2FnZSI6IHsKICAgICAgImdldCI6IHsKICAgICAgICAic2VjdXJpdHkiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlbkhlYWRlciI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5RdWVyeSI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiYmFzaWNBdXRoIjogW10KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJwcm9kdWNlcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInRhZ3MiOiBbCiAgICAgICAgICAibWVzc2FnZSIKICAgICAgICBdLAogICAgICAgICJzdW1tYXJ5IjogIlJldHVybiBhbGwgbWVzc2FnZXMuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAiZ2V0TWVzc2FnZXMiLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL01lc3NhZ2UiCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVuYXV0aG9yaXplZCIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDMiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJGb3JiaWRkZW4iLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgICJwb3N0IjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImFwcFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJhcHBUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJjb25zdW1lcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJtZXNzYWdlIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiQ3JlYXRlIGEgbWVzc2FnZS4iLAogICAgICAgICJvcGVyYXRpb25JZCI6ICJjcmVhdGVNZXNzYWdlIiwKICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogInRoZSBtZXNzYWdlIHRvIGFkZCIsCiAgICAgICAgICAgICJuYW1lIjogImJvZHkiLAogICAgICAgICAgICAiaW4iOiAiYm9keSIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IHRydWUsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9NZXNzYWdlIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicmVzcG9uc2VzIjogewogICAgICAgICAgIjIwMCI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9rIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICAgICAgICAgIml0ZW1zIjogewogICAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9NZXNzYWdlIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgICJkZWxldGUiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgIm1lc3NhZ2UiCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJEZWxldGUgYWxsIG1lc3NhZ2VzLiIsCiAgICAgICAgIm9wZXJhdGlvbklkIjogImRlbGV0ZU1lc3NhZ2VzIiwKICAgICAgICAicmVzcG9uc2VzIjogewogICAgICAgICAgIjIwMCI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9rIgogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAzIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9yYmlkZGVuIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgIi9tZXNzYWdlL3tpZH0iOiB7CiAgICAgICJkZWxldGUiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgIm1lc3NhZ2UiCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJEZWxldGVzIGEgbWVzc2FnZSB3aXRoIGFuIGlkLiIsCiAgICAgICAgIm9wZXJhdGlvbklkIjogImRlbGV0ZU1lc3NhZ2UiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAidHlwZSI6ICJpbnRlZ2VyIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogInRoZSBtZXNzYWdlIGlkIiwKICAgICAgICAgICAgIm5hbWUiOiAiaWQiLAogICAgICAgICAgICAiaW4iOiAicGF0aCIsCiAgICAgICAgICAgICJyZXF1aXJlZCI6IHRydWUKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siCiAgICAgICAgICB9LAogICAgICAgICAgIjQwMSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVuYXV0aG9yaXplZCIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDMiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJGb3JiaWRkZW4iLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0sCiAgICAiL3N0cmVhbSI6IHsKICAgICAgImdldCI6IHsKICAgICAgICAic2VjdXJpdHkiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlbkhlYWRlciI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5RdWVyeSI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiYmFzaWNBdXRoIjogW10KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJwcm9kdWNlcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInRhZ3MiOiBbCiAgICAgICAgICAibWVzc2FnZSIKICAgICAgICBdLAogICAgICAgICJzdW1tYXJ5IjogIldlYnNvY2tldCwgcmV0dXJuIG5ld2x5IGNyZWF0ZWQgbWVzc2FnZXMuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAic3RyZWFtTWVzc2FnZXMiLAogICAgICAgICJyZXNwb25zZXMiOiB7CiAgICAgICAgICAiMjAwIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2siLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvTWVzc2FnZSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAzIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9yYmlkZGVuIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgIi91c2VyIjogewogICAgICAiZ2V0IjogewogICAgICAgICJzZWN1cml0eSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuSGVhZGVyIjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlblF1ZXJ5IjogW10KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJiYXNpY0F1dGgiOiBbXQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJ1c2VyIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiUmV0dXJuIGFsbCB1c2Vycy4iLAogICAgICAgICJvcGVyYXRpb25JZCI6ICJnZXRVc2VycyIsCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgInR5cGUiOiAiYXJyYXkiLAogICAgICAgICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvVXNlciIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgInBvc3QiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY29uc3VtZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJwcm9kdWNlcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInRhZ3MiOiBbCiAgICAgICAgICAidXNlciIKICAgICAgICBdLAogICAgICAgICJzdW1tYXJ5IjogIkNyZWF0ZSBhIHVzZXIuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAiY3JlYXRlVXNlciIsCiAgICAgICAgInBhcmFtZXRlcnMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJ0aGUgdXNlciB0byBhZGQiLAogICAgICAgICAgICAibmFtZSI6ICJib2R5IiwKICAgICAgICAgICAgImluIjogImJvZHkiLAogICAgICAgICAgICAicmVxdWlyZWQiOiB0cnVlLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvVXNlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9Vc2VyIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVuYXV0aG9yaXplZCIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDMiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJGb3JiaWRkZW4iLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0sCiAgICAiL3VzZXIve2lkfSI6IHsKICAgICAgImdldCI6IHsKICAgICAgICAic2VjdXJpdHkiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjbGllbnRUb2tlbkhlYWRlciI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5RdWVyeSI6IFtdCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiYmFzaWNBdXRoIjogW10KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJjb25zdW1lcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInByb2R1Y2VzIjogWwogICAgICAgICAgImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgXSwKICAgICAgICAidGFncyI6IFsKICAgICAgICAgICJ1c2VyIgogICAgICAgIF0sCiAgICAgICAgInN1bW1hcnkiOiAiR2V0IGEgdXNlci4iLAogICAgICAgICJvcGVyYXRpb25JZCI6ICJnZXRVc2VyIiwKICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJ0aGUgdXNlciBpZCIsCiAgICAgICAgICAgICJuYW1lIjogImlkIiwKICAgICAgICAgICAgImluIjogInBhdGgiLAogICAgICAgICAgICAicmVxdWlyZWQiOiB0cnVlCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicmVzcG9uc2VzIjogewogICAgICAgICAgIjIwMCI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9rIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL1VzZXIiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAxIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5hdXRob3JpemVkIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMyI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvcmJpZGRlbiIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgInBvc3QiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY29uc3VtZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJwcm9kdWNlcyI6IFsKICAgICAgICAgICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIF0sCiAgICAgICAgInRhZ3MiOiBbCiAgICAgICAgICAidXNlciIKICAgICAgICBdLAogICAgICAgICJzdW1tYXJ5IjogIlVwZGF0ZSBhIHVzZXIuIiwKICAgICAgICAib3BlcmF0aW9uSWQiOiAidXBkYXRlVXNlciIsCiAgICAgICAgInBhcmFtZXRlcnMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJ0eXBlIjogImludGVnZXIiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAidGhlIHVzZXIgaWQiLAogICAgICAgICAgICAibmFtZSI6ICJpZCIsCiAgICAgICAgICAgICJpbiI6ICJwYXRoIiwKICAgICAgICAgICAgInJlcXVpcmVkIjogdHJ1ZQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogInRoZSB1cGRhdGVkIHVzZXIiLAogICAgICAgICAgICAibmFtZSI6ICJib2R5IiwKICAgICAgICAgICAgImluIjogImJvZHkiLAogICAgICAgICAgICAicmVxdWlyZWQiOiB0cnVlLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvVXNlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInJlc3BvbnNlcyI6IHsKICAgICAgICAgICIyMDAiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJPayIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9Vc2VyIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIjQwMSI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlVuYXV0aG9yaXplZCIsCiAgICAgICAgICAgICJzY2hlbWEiOiB7CiAgICAgICAgICAgICAgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9FcnJvciIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICI0MDMiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJGb3JiaWRkZW4iLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgICJkZWxldGUiOiB7CiAgICAgICAgInNlY3VyaXR5IjogWwogICAgICAgICAgewogICAgICAgICAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNsaWVudFRva2VuUXVlcnkiOiBbXQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImJhc2ljQXV0aCI6IFtdCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicHJvZHVjZXMiOiBbCiAgICAgICAgICAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICBdLAogICAgICAgICJ0YWdzIjogWwogICAgICAgICAgInVzZXIiCiAgICAgICAgXSwKICAgICAgICAic3VtbWFyeSI6ICJEZWxldGVzIGEgdXNlci4iLAogICAgICAgICJvcGVyYXRpb25JZCI6ICJkZWxldGVVc2VyIiwKICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJ0aGUgdXNlciBpZCIsCiAgICAgICAgICAgICJuYW1lIjogImlkIiwKICAgICAgICAgICAgImluIjogInBhdGgiLAogICAgICAgICAgICAicmVxdWlyZWQiOiB0cnVlCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicmVzcG9uc2VzIjogewogICAgICAgICAgIjIwMCI6IHsKICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIk9rIgogICAgICAgICAgfSwKICAgICAgICAgICI0MDEiOiB7CiAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJVbmF1dGhvcml6ZWQiLAogICAgICAgICAgICAic2NoZW1hIjogewogICAgICAgICAgICAgICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvRXJyb3IiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiNDAzIjogewogICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9yYmlkZGVuIiwKICAgICAgICAgICAgInNjaGVtYSI6IHsKICAgICAgICAgICAgICAiJHJlZiI6ICIjL2RlZmluaXRpb25zL0Vycm9yIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfSwKICAiZGVmaW5pdGlvbnMiOiB7CiAgICAiQXBwbGljYXRpb24iOiB7CiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgQXBwbGljYXRpb24gaG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgYW4gYXBwIHdoaWNoIGNhbiBzZW5kIG5vdGlmaWNhdGlvbnMuIiwKICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgInRpdGxlIjogIkFwcGxpY2F0aW9uIE1vZGVsIiwKICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgIklEIjogewogICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImRlc2NyaXB0aW9uIjogewogICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICJ4LWdvLW5hbWUiOiAiRGVzY3JpcHRpb24iCiAgICAgICAgfSwKICAgICAgICAibmFtZSI6IHsKICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAieC1nby1uYW1lIjogIk5hbWUiCiAgICAgICAgfQogICAgICB9LAogICAgICAieC1nby1wYWNrYWdlIjogImdpdGh1Yi5jb20vZ290aWZ5L3NlcnZlci9tb2RlbCIKICAgIH0sCiAgICAiQ2xpZW50IjogewogICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIENsaWVudCBob2xkcyBpbmZvcm1hdGlvbiBhYm91dCBhIGRldmljZSB3aGljaCBjYW4gcmVjZWl2ZSBub3RpZmljYXRpb25zIChhbmQgb3RoZXIgc3R1ZmYpLiIsCiAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICJ0aXRsZSI6ICJDbGllbnQgTW9kZWwiLAogICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAiSUQiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgfSwKICAgICAgICAibmFtZSI6IHsKICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAieC1nby1uYW1lIjogIk5hbWUiCiAgICAgICAgfQogICAgICB9LAogICAgICAieC1nby1wYWNrYWdlIjogImdpdGh1Yi5jb20vZ290aWZ5L3NlcnZlci9tb2RlbCIKICAgIH0sCiAgICAiRXJyb3IiOiB7CiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgRXJyb3IgY29udGFpbnMgZXJyb3IgcmVsZXZhbnQgaW5mb3JtYXRpb24uIiwKICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgInRpdGxlIjogIkVycm9yIE1vZGVsIiwKICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImVycm9yIjogewogICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICJ4LWdvLW5hbWUiOiAiRXJyb3IiCiAgICAgICAgfSwKICAgICAgICAiZXJyb3JDb2RlIjogewogICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAiZm9ybWF0IjogImludDY0IiwKICAgICAgICAgICJ4LWdvLW5hbWUiOiAiRXJyb3JDb2RlIgogICAgICAgIH0sCiAgICAgICAgImVycm9yRGVzY3JpcHRpb24iOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJFcnJvckRlc2NyaXB0aW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgIngtZ28tcGFja2FnZSI6ICJnaXRodWIuY29tL2dvdGlmeS9zZXJ2ZXIvbW9kZWwiCiAgICB9LAogICAgIk1lc3NhZ2UiOiB7CiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgTWVzc2FnZSBob2xkcyBpbmZvcm1hdGlvbiBhYm91dCBhIG1lc3NhZ2Ugd2hpY2ggd2FzIHNlbnQgYnkgYW4gQXBwbGljYXRpb24uIiwKICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgInRpdGxlIjogIk1lc3NhZ2UgTW9kZWwiLAogICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAiYXBwaWQiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJBcHBsaWNhdGlvbklEIgogICAgICAgIH0sCiAgICAgICAgImRhdGUiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgImZvcm1hdCI6ICJkYXRlLXRpbWUiLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJEYXRlIgogICAgICAgIH0sCiAgICAgICAgImlkIjogewogICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAiZm9ybWF0IjogInVpbnQ2NCIsCiAgICAgICAgICAieC1nby1uYW1lIjogIklEIgogICAgICAgIH0sCiAgICAgICAgIm1lc3NhZ2UiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJNZXNzYWdlIgogICAgICAgIH0sCiAgICAgICAgInByaW9yaXR5IjogewogICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAiZm9ybWF0IjogImludDY0IiwKICAgICAgICAgICJ4LWdvLW5hbWUiOiAiUHJpb3JpdHkiCiAgICAgICAgfSwKICAgICAgICAidGl0bGUiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJUaXRsZSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ4LWdvLXBhY2thZ2UiOiAiZ2l0aHViLmNvbS9nb3RpZnkvc2VydmVyL21vZGVsIgogICAgfSwKICAgICJVc2VyIjogewogICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIFVzZXIgaG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNyZWRlbnRpYWxzIGFuZCBvdGhlciBzdHVmZi4iLAogICAgICAidHlwZSI6ICJvYmplY3QiLAogICAgICAidGl0bGUiOiAiVXNlckV4dGVybmFsIE1vZGVsIiwKICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImFkbWluIjogewogICAgICAgICAgInR5cGUiOiAiYm9vbGVhbiIsCiAgICAgICAgICAieC1nby1uYW1lIjogIkFkbWluIgogICAgICAgIH0sCiAgICAgICAgImlkIjogewogICAgICAgICAgInR5cGUiOiAiaW50ZWdlciIsCiAgICAgICAgICAiZm9ybWF0IjogInVpbnQ2NCIsCiAgICAgICAgICAieC1nby1uYW1lIjogIklEIgogICAgICAgIH0sCiAgICAgICAgIm5hbWUiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJOYW1lIgogICAgICAgIH0sCiAgICAgICAgInBhc3MiOiB7CiAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgIngtZ28tbmFtZSI6ICJQYXNzIgogICAgICAgIH0KICAgICAgfSwKICAgICAgIngtZ28tbmFtZSI6ICJVc2VyRXh0ZXJuYWwiLAogICAgICAieC1nby1wYWNrYWdlIjogImdpdGh1Yi5jb20vZ290aWZ5L3NlcnZlci9tb2RlbCIKICAgIH0KICB9LAogICJzZWN1cml0eURlZmluaXRpb25zIjogewogICAgImFwcFRva2VuSGVhZGVyIjogewogICAgICAidHlwZSI6ICJhcGlLZXkiLAogICAgICAibmFtZSI6ICJYLUdvdGlmeS1LZXkiLAogICAgICAiaW4iOiAiaGVhZGVyIgogICAgfSwKICAgICJhcHBUb2tlblF1ZXJ5IjogewogICAgICAidHlwZSI6ICJhcGlLZXkiLAogICAgICAibmFtZSI6ICJ0b2tlbiIsCiAgICAgICJpbiI6ICJxdWVyeSIKICAgIH0sCiAgICAiYmFzaWNBdXRoIjogewogICAgICAidHlwZSI6ICJiYXNpYyIKICAgIH0sCiAgICAiY2xpZW50VG9rZW5IZWFkZXIiOiB7CiAgICAgICJ0eXBlIjogImFwaUtleSIsCiAgICAgICJuYW1lIjogIlgtR290aWZ5LUtleSIsCiAgICAgICJpbiI6ICJoZWFkZXIiCiAgICB9LAogICAgImNsaWVudFRva2VuUXVlcnkiOiB7CiAgICAgICJ0eXBlIjogImFwaUtleSIsCiAgICAgICJuYW1lIjogInRva2VuIiwKICAgICAgImluIjogInF1ZXJ5IgogICAgfQogIH0KfQ==\"") + packr.PackJSONBytes("./", "swagger.go", "\"cGFja2FnZSBkb2NzDQoNCmltcG9ydCAoDQoJImdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbiINCgkiZ2l0aHViLmNvbS9nb2J1ZmZhbG8vcGFja3IiDQoJInN0cmluZ3MiDQopDQoNCi8vIFNlcnZlIHNlcnZlcyB0aGUgZG9jdW1lbnRhdGlvbi4NCmZ1bmMgU2VydmUoY3R4ICpnaW4uQ29udGV4dCkgew0KCWN0eC5Xcml0ZXIuV3JpdGVTdHJpbmcoZ2V0KGN0eC5SZXF1ZXN0LlVSTC5Ib3N0KSkNCn0NCg0KZnVuYyBnZXQoaG9zdCBzdHJpbmcpIHN0cmluZyB7DQoJYm94IDo9IHBhY2tyLk5ld0JveCgiLi8iKQ0KCXJldHVybiBzdHJpbmdzLlJlcGxhY2UoYm94LlN0cmluZygic3BlYy5qc29uIiksICJsb2NhbGhvc3QiLCBob3N0LCAxKQ0KfQ0K\"") + } diff --git a/docs/package.go b/docs/package.go new file mode 100644 index 0000000..90998c3 --- /dev/null +++ b/docs/package.go @@ -0,0 +1,38 @@ +// Package docs Gotify REST-API. +// +// This is the documentation of the Gotify REST-API. +// +// Schemes: http, https +// Host: localhost +// Version: 1.0.0 +// License: MIT https://github.com/gotify/server/blob/master/LICENSE +// Contact: https://github.com/gotify/server/issues +// +// Consumes: +// - application/json +// +// Produces: +// - application/json +// +// SecurityDefinitions: +// appTokenQuery: +// type: apiKey +// name: token +// in: query +// clientTokenQuery: +// type: apiKey +// name: token +// in: query +// appTokenHeader: +// type: apiKey +// name: X-Gotify-Key +// in: header +// clientTokenHeader: +// type: apiKey +// name: X-Gotify-Key +// in: header +// basicAuth: +// type: basic +// +// swagger:meta +package docs diff --git a/docs/spec.json b/docs/spec.json new file mode 100644 index 0000000..36033b1 --- /dev/null +++ b/docs/spec.json @@ -0,0 +1,1172 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "http", + "https" + ], + "swagger": "2.0", + "info": { + "description": "This is the documentation of the Gotify REST-API.", + "title": "Gotify REST-API.", + "contact": { + "url": "https://github.com/gotify/server/issues" + }, + "license": { + "name": "MIT", + "url": "https://github.com/gotify/server/blob/master/LICENSE" + }, + "version": "1.0.0" + }, + "host": "localhost", + "paths": { + "/application": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "token" + ], + "summary": "Return all applications.", + "operationId": "getApps", + "responses": { + "200": { + "description": "Ok", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Application" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "post": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "token" + ], + "summary": "Create an application.", + "operationId": "createApp", + "parameters": [ + { + "description": "the application to add", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Application" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/Application" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/application/{id}": { + "delete": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "token" + ], + "summary": "Delete an application.", + "operationId": "deleteApp", + "parameters": [ + { + "type": "string", + "description": "the application id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/application/{id}/message": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Return all messages from a specific application.", + "operationId": "getAppMessages", + "parameters": [ + { + "type": "string", + "description": "the application id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Message" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "delete": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Delete all messages from a specific application.", + "operationId": "deleteAppMessages", + "parameters": [ + { + "type": "string", + "description": "the application id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/client": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "token" + ], + "summary": "Return all clients.", + "operationId": "getClients", + "responses": { + "200": { + "description": "Ok", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Client" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "post": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "token" + ], + "summary": "Create a client.", + "operationId": "createClient", + "parameters": [ + { + "description": "the client to add", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Client" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/Client" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/client/{id}": { + "delete": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "token" + ], + "summary": "Delete a client.", + "operationId": "deleteClient", + "parameters": [ + { + "type": "string", + "description": "the client id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/current/user": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Return the current user.", + "operationId": "currentUser", + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/User" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/current/user/password": { + "post": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Update the password of the current user.", + "operationId": "updateCurrentUser", + "parameters": [ + { + "description": "the user", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/message": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Return all messages.", + "operationId": "getMessages", + "responses": { + "200": { + "description": "Ok", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Message" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "post": { + "security": [ + { + "appTokenHeader": [] + }, + { + "appTokenQuery": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Create a message.", + "operationId": "createMessage", + "parameters": [ + { + "description": "the message to add", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Message" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Message" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "delete": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Delete all messages.", + "operationId": "deleteMessages", + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/message/{id}": { + "delete": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Deletes a message with an id.", + "operationId": "deleteMessage", + "parameters": [ + { + "type": "integer", + "description": "the message id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/stream": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Websocket, return newly created messages.", + "operationId": "streamMessages", + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/Message" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/user": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Return all users.", + "operationId": "getUsers", + "responses": { + "200": { + "description": "Ok", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "post": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Create a user.", + "operationId": "createUser", + "parameters": [ + { + "description": "the user to add", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/User" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/user/{id}": { + "get": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Get a user.", + "operationId": "getUser", + "parameters": [ + { + "type": "integer", + "description": "the user id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/User" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "post": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Update a user.", + "operationId": "updateUser", + "parameters": [ + { + "type": "integer", + "description": "the user id", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "the updated user", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "schema": { + "$ref": "#/definitions/User" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "delete": { + "security": [ + { + "clientTokenHeader": [] + }, + { + "clientTokenQuery": [] + }, + { + "basicAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Deletes a user.", + "operationId": "deleteUser", + "parameters": [ + { + "type": "integer", + "description": "the user id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Ok" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + } + }, + "definitions": { + "Application": { + "description": "The Application holds information about an app which can send notifications.", + "type": "object", + "title": "Application Model", + "properties": { + "ID": { + "type": "string" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "github.com/gotify/server/model" + }, + "Client": { + "description": "The Client holds information about a device which can receive notifications (and other stuff).", + "type": "object", + "title": "Client Model", + "properties": { + "ID": { + "type": "string" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "github.com/gotify/server/model" + }, + "Error": { + "description": "The Error contains error relevant information.", + "type": "object", + "title": "Error Model", + "properties": { + "error": { + "type": "string", + "x-go-name": "Error" + }, + "errorCode": { + "type": "integer", + "format": "int64", + "x-go-name": "ErrorCode" + }, + "errorDescription": { + "type": "string", + "x-go-name": "ErrorDescription" + } + }, + "x-go-package": "github.com/gotify/server/model" + }, + "Message": { + "description": "The Message holds information about a message which was sent by an Application.", + "type": "object", + "title": "Message Model", + "properties": { + "appid": { + "type": "string", + "x-go-name": "ApplicationID" + }, + "date": { + "type": "string", + "format": "date-time", + "x-go-name": "Date" + }, + "id": { + "type": "integer", + "format": "uint64", + "x-go-name": "ID" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "priority": { + "type": "integer", + "format": "int64", + "x-go-name": "Priority" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "github.com/gotify/server/model" + }, + "User": { + "description": "The User holds information about the credentials and other stuff.", + "type": "object", + "title": "UserExternal Model", + "properties": { + "admin": { + "type": "boolean", + "x-go-name": "Admin" + }, + "id": { + "type": "integer", + "format": "uint64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "pass": { + "type": "string", + "x-go-name": "Pass" + } + }, + "x-go-name": "UserExternal", + "x-go-package": "github.com/gotify/server/model" + } + }, + "securityDefinitions": { + "appTokenHeader": { + "type": "apiKey", + "name": "X-Gotify-Key", + "in": "header" + }, + "appTokenQuery": { + "type": "apiKey", + "name": "token", + "in": "query" + }, + "basicAuth": { + "type": "basic" + }, + "clientTokenHeader": { + "type": "apiKey", + "name": "X-Gotify-Key", + "in": "header" + }, + "clientTokenQuery": { + "type": "apiKey", + "name": "token", + "in": "query" + } + } +} \ No newline at end of file diff --git a/docs/swagger.go b/docs/swagger.go new file mode 100644 index 0000000..a52bd3a --- /dev/null +++ b/docs/swagger.go @@ -0,0 +1,17 @@ +package docs + +import ( + "github.com/gin-gonic/gin" + "github.com/gobuffalo/packr" + "strings" +) + +// Serve serves the documentation. +func Serve(ctx *gin.Context) { + ctx.Writer.WriteString(get(ctx.Request.URL.Host)) +} + +func get(host string) string { + box := packr.NewBox("./") + return strings.Replace(box.String("spec.json"), "localhost", host, 1) +} diff --git a/router/router.go b/router/router.go index db4fb06..84a6098 100644 --- a/router/router.go +++ b/router/router.go @@ -8,6 +8,11 @@ import ( "github.com/gotify/server/auth" "github.com/gotify/server/database" "github.com/gotify/server/error" + "github.com/jmattheis/go-packr-swagger-ui" + + "net/http" + + "github.com/gotify/server/docs" "github.com/gotify/server/stream" ) @@ -20,15 +25,47 @@ func Create(db *database.GormDatabase) (*gin.Engine, func()) { userHandler := api.UserAPI{DB: db} g := gin.New() + g.Use(gin.Logger(), gin.Recovery(), error.Handler()) g.NoRoute(error.NotFound()) - g.GET("/") + g.GET("/swagger", docs.Serve) + g.GET("/docs/*any", gin.WrapH(http.StripPrefix("/docs/", http.FileServer(swaggerui.GetBox())))) g.Use(func(ctx *gin.Context) { ctx.Header("Content-Type", "application/json") }) + // swagger:operation POST /message message createMessage + // + // Create a message. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - appTokenHeader: [] + // - appTokenQuery: [] + // parameters: + // - name: body + // in: body + // description: the message to add + // required: true + // schema: + // $ref: "#/definitions/Message" + // responses: + // 200: + // description: Ok + // schema: + // type: array + // items: + // $ref: "#/definitions/Message" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" g.Group("/").Use(authentication.RequireApplicationToken()).POST("/message", messageHandler.CreateMessage) clientAuth := g.Group("") @@ -36,33 +73,440 @@ func Create(db *database.GormDatabase) (*gin.Engine, func()) { clientAuth.Use(authentication.RequireClient()) app := clientAuth.Group("/application") { + // swagger:operation GET /application token getApps + // + // Return all applications. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // schema: + // type: array + // items: + // $ref: "#/definitions/Application" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" app.GET("", tokenHandler.GetApplications) + + // swagger:operation POST /application token createApp + // + // Create an application. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: body + // in: body + // description: the application to add + // required: true + // schema: + // $ref: "#/definitions/Application" + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/Application" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" app.POST("", tokenHandler.CreateApplication) + + // swagger:operation DELETE /application/{id} token deleteApp + // + // Delete an application. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: id + // in: path + // description: the application id + // required: true + // type: string + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" app.DELETE("/:id", tokenHandler.DeleteApplication) + tokenMessage := app.Group("/:id/message") { + // swagger:operation GET /application/{id}/message message getAppMessages + // + // Return all messages from a specific application. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: id + // in: path + // description: the application id + // required: true + // type: string + // responses: + // 200: + // description: Ok + // schema: + // type: array + // items: + // $ref: "#/definitions/Message" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" tokenMessage.GET("", messageHandler.GetMessagesWithApplication) + + // swagger:operation DELETE /application/{id}/message message deleteAppMessages + // + // Delete all messages from a specific application. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: id + // in: path + // description: the application id + // required: true + // type: string + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" tokenMessage.DELETE("", messageHandler.DeleteMessageWithApplication) } } client := clientAuth.Group("/client") { + // swagger:operation GET /client token getClients + // + // Return all clients. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // schema: + // type: array + // items: + // $ref: "#/definitions/Client" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" client.GET("", tokenHandler.GetClients) + + // swagger:operation POST /client token createClient + // + // Create a client. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: body + // in: body + // description: the client to add + // required: true + // schema: + // $ref: "#/definitions/Client" + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/Client" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" client.POST("", tokenHandler.CreateClient) + + // swagger:operation DELETE /client/{id} token deleteClient + // + // Delete a client. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: id + // in: path + // description: the client id + // required: true + // type: string + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" client.DELETE("/:id", tokenHandler.DeleteClient) } message := clientAuth.Group("/message") { + // swagger:operation GET /message message getMessages + // + // Return all messages. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // schema: + // type: array + // items: + // $ref: "#/definitions/Message" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" message.GET("", messageHandler.GetMessages) + + // swagger:operation DELETE /message message deleteMessages + // + // Delete all messages. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" message.DELETE("", messageHandler.DeleteMessages) + + // swagger:operation DELETE /message/{id} message deleteMessage + // + // Deletes a message with an id. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: id + // in: path + // description: the message id + // required: true + // type: integer + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" message.DELETE("/:id", messageHandler.DeleteMessage) } + // swagger:operation GET /stream message streamMessages + // + // Websocket, return newly created messages. + // + // --- + // schema: ws, wss + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/Message" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" clientAuth.GET("/stream", streamHandler.Handle) + // swagger:operation GET /current/user user currentUser + // + // Return the current user. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/User" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" clientAuth.GET("current/user", userHandler.GetCurrentUser) + + // swagger:operation POST /current/user/password user updateCurrentUser + // + // Update the password of the current user. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: body + // in: body + // description: the user + // required: true + // schema: + // $ref: "#/definitions/User" + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" clientAuth.POST("current/user/password", userHandler.ChangePassword) } @@ -70,11 +514,171 @@ func Create(db *database.GormDatabase) (*gin.Engine, func()) { { authAdmin.Use(authentication.RequireAdmin()) + // swagger:operation GET /user user getUsers + // + // Return all users. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // responses: + // 200: + // description: Ok + // schema: + // type: array + // items: + // $ref: "#/definitions/User" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" authAdmin.GET("", userHandler.GetUsers) + + // swagger:operation POST /user user createUser + // + // Create a user. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: body + // in: body + // description: the user to add + // required: true + // schema: + // $ref: "#/definitions/User" + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/User" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" authAdmin.POST("", userHandler.CreateUser) + // swagger:operation DELETE /user/{id} user deleteUser + // + // Deletes a user. + // + // --- + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: id + // in: path + // description: the user id + // required: true + // type: integer + // responses: + // 200: + // description: Ok + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" authAdmin.DELETE("/:id", userHandler.DeleteUserByID) + + // swagger:operation GET /user/{id} user getUser + // + // Get a user. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: id + // in: path + // description: the user id + // required: true + // type: integer + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/User" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" authAdmin.GET("/:id", userHandler.GetUserByID) + + // swagger:operation POST /user/{id} user updateUser + // + // Update a user. + // + // --- + // consumes: + // - application/json + // produces: + // - application/json + // security: + // - clientTokenHeader: [] + // - clientTokenQuery: [] + // - basicAuth: [] + // parameters: + // - name: id + // in: path + // description: the user id + // required: true + // type: integer + // - name: body + // in: body + // description: the updated user + // required: true + // schema: + // $ref: "#/definitions/User" + // responses: + // 200: + // description: Ok + // schema: + // $ref: "#/definitions/User" + // 401: + // description: Unauthorized + // schema: + // $ref: "#/definitions/Error" + // 403: + // description: Forbidden + // schema: + // $ref: "#/definitions/Error" authAdmin.POST("/:id", userHandler.UpdateUserByID) } return g, streamHandler.Close