Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement swagger docs and fix path validation #434

Merged
merged 7 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,15 @@ func getAPICmd() *cobra.Command {
// Data for this should be stored in the ServicesManager struct
r.HandleFunc("/listen/{path}/{strategy}/{name}", PostRelayerListenHandler(sm)).Methods("POST")

fs := http.FileServer(http.Dir("./swagger-ui"))
r.PathPrefix("/").Handler(fs)

fmt.Println("listening on", config.Global.APIListenPort)

if err := http.ListenAndServe(config.Global.APIListenPort, r); err != nil {
return err
}

fmt.Println("listening on", config.Global.APIListenPort)
return nil
},
}
Expand Down
11 changes: 9 additions & 2 deletions cmd/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,10 @@ type addChainRequest struct {
GasAdjustment string `json:"gas-adjustment"`
GasPrices string `json:"gas-prices"`
TrustingPeriod string `json:"trusting-period"`
FilePath string `json:"file"`
URL string `json:"url"`
// required: false
FilePath string `json:"file"`
// required: false
URL string `json:"url"`
}

// PostChainHandler handles the route
Expand Down Expand Up @@ -678,6 +680,11 @@ func PutChainHandler(w http.ResponseWriter, r *http.Request) {
// DeleteChainHandler handles the route
func DeleteChainHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
_, err := config.Chains.Get(vars["name"])
if err != nil {
helpers.WriteErrorResponse(http.StatusBadRequest, err, w)
return
}
if err := overWriteConfig(config.DeleteChain(vars["name"])); err != nil {
helpers.WriteErrorResponse(http.StatusInternalServerError, err, w)
return
Expand Down
139 changes: 139 additions & 0 deletions cmd/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Package cmd Relayer Rest Server.
//
// A REST interface for state queries.
//
// Schemes: http
// Basepath: /
// Version: 1.0.0
// Host: localhost:5183
//
// Consumes:
// - application/json
//
// Produces:
// - application/json
//
//
// swagger:meta
package cmd

import (
"github.com/cosmos/relayer/relayer"
)

// swagger:response errorResponse
type errResWrapper struct {
// in:body
Error struct {
Err string `json:"err" yaml:"err"`
}
}

// swagger:route GET /version Version version
// Get version.
// responses:
// 200: versionResponse

// swagger:response versionResponse
type versionResWrapper struct {
// in:body
VersionInfo versionInfo
}

// swagger:route GET /config Config config
// Get config.
// responses:
// 200: configResponse

// swagger:response configResponse
type configResWrapper struct {
// Returns config of relayer
// in:body
Config *Config
}

// swagger:route GET /chains Chains getChains
// Get chains list.
// responses:
// 200: getChainsResponse

// swagger:response getChainsResponse
type getChainsResWrapper struct {
// Returns chains list.
// in:body
Chains relayer.Chains
}

// swagger:route GET /chains/{name} Chains getChain
// Get single chain details.
// responses:
// 200: getChainResponse
// 400: errorResponse

// swagger:parameters getChain addChain updateChain deleteChain getChainStatus
type chainParamsWrapper struct {
// in:path
Name string `json:"name" yaml:"name"`
}

// swagger:response getChainResponse
type getChainResWrapper struct {
// Returns chain details
// in:body
Chain *relayer.Chain
}

// swagger:route POST /chains/{name} Chains addChain
// Add a chain.
//
// file and url parameters in body are optional and can't use both at once.
// responses:
// 201: chainResponse
// 400: errorResponse
// 500: errorResponse

// swagger:parameters addChain
type addChainParamsWrapper struct {
// required:true
// in:body
Body addChainRequest `json:"body" yaml:"body"`
}

// swagger:response chainResponse
type chainResWrapper struct {
// in:body
Res string `json:"res" yaml:"res"`
}

// swagger:route PUT /chains/{name} Chains updateChain
// Update chain config values.
// responses:
// 200: chainResponse
// 400: errorResponse
// 500: errorResponse

// swagger:parameters updateChain
type updateChainParamsWrapper struct {
// required:true
// in:body
Body editChainRequest `json:"body" yaml:"body"`
}

// swagger:route DELETE /chains/{name} Chains deleteChain
// Delete Chain.
// responses:
// 200: chainResponse
// 400: errorResponse
// 500: errorResponse

// swagger:route GET /chains/{name}/status Chains getChainStatus
// Get status of a chain.
// responses:
// 200: chainStatusRes
// 400: errorResponse

// swagger:response chainStatusRes
type chainStatusResWrapper struct {
// in:body
Status chainStatusResponse
}
Binary file added swagger-ui/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added swagger-ui/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions swagger-ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.35.1/swagger-ui.css" >
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}

*,
*:before,
*:after
{
box-sizing: inherit;
}

body
{
margin:0;
background: #fafafa;
}
</style>
</head>

<body>
<div id="swagger-ui"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.35.1/swagger-ui-bundle.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.35.1/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {

// Build a system
const ui = SwaggerUIBundle({
url: "./swagger.yaml",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})

window.ui = ui
}
</script>
</body>
</html>
67 changes: 67 additions & 0 deletions swagger-ui/oauth2-redirect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!doctype html>
<html lang="en-US">
<body onload="run()">
</body>
</html>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;

if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}

arr = qp.split("&")
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value)
}
) : {}

isValid = qp.state === sentState

if ((
oauth2.auth.schema.get("flow") === "accessCode"||
oauth2.auth.schema.get("flow") === "authorizationCode"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}

if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}

oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
</script>
Loading