github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/lib/http/api.go (about)

     1  package http
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/qri-io/qri/dsref"
     9  )
    10  
    11  // APIEndpoint is a simple alias to have a consistent definition
    12  // of our API endpoints
    13  type APIEndpoint string
    14  
    15  // String allows for less casting in general code
    16  func (ae APIEndpoint) String() string {
    17  	return string(ae)
    18  }
    19  
    20  // NoTrailingSlash returns the path without a traling slash
    21  func (ae APIEndpoint) NoTrailingSlash() string {
    22  	s := string(ae)
    23  	s = strings.TrimSuffix(s, "/")
    24  	return s
    25  }
    26  
    27  // WithSuffix returns a new endpoint with added path suffix
    28  func (ae APIEndpoint) WithSuffix(suffix string) APIEndpoint {
    29  	return APIEndpoint(fmt.Sprintf("%s/%s", ae, suffix))
    30  }
    31  
    32  const (
    33  	// aggregate endpoints
    34  
    35  	// AEList lists all datasets in your collection
    36  	AEList APIEndpoint = "/list"
    37  	// AECollectionGet returns info on a head dataset in your collection
    38  	AECollectionGet APIEndpoint = "/collection/get"
    39  	// AEDiff is an endpoint for generating dataset diffs
    40  	AEDiff APIEndpoint = "/diff"
    41  	// AEChanges is an endpoint for generating dataset change reports
    42  	AEChanges APIEndpoint = "/changes"
    43  
    44  	// auth endpoints
    45  
    46  	// AECreateAuthToken creates an auth token for a user
    47  	AECreateAuthToken APIEndpoint = "/access/token"
    48  
    49  	// automation endpoints
    50  
    51  	// AEApply invokes a transform apply
    52  	AEApply APIEndpoint = "/auto/apply"
    53  	// AEDeploy creates, updates, or deploys a workflow
    54  	AEDeploy APIEndpoint = "/auto/deploy"
    55  	// AERun manually runs a workflow
    56  	AERun APIEndpoint = "/auto/run"
    57  	// AERunInfo fetches the full run info for a workflow run
    58  	AERunInfo APIEndpoint = "/auto/runinfo"
    59  	// AECancel cancels a run
    60  	AECancel APIEndpoint = "/auto/cancel"
    61  	// AEWorkflow fetches a workflow
    62  	AEWorkflow APIEndpoint = "/auto/workflow"
    63  	// AERemoveWorkflow removes a workflow
    64  	AERemoveWorkflow APIEndpoint = "/auto/remove"
    65  	// AEAnalyzeTransform performs static analysis on a starlark transform script
    66  	AEAnalyzeTransform APIEndpoint = "/auto/analyze-transform"
    67  
    68  	// dataset endpoints
    69  
    70  	// AEGet is an endpoint for fetch individual dataset components
    71  	AEGet APIEndpoint = "/ds/get"
    72  	// AEActivity is an endpoint that returns a dataset activity list
    73  	AEActivity APIEndpoint = "/ds/activity"
    74  	// AERename is an endpoint for renaming datasets
    75  	AERename APIEndpoint = "/ds/rename"
    76  	// AESave is an endpoint for saving a dataset
    77  	AESave APIEndpoint = "/ds/save"
    78  	// AEPull facilittates dataset pull requests from a remote
    79  	AEPull APIEndpoint = "/ds/pull"
    80  	// AEPush facilitates dataset push requests to a remote
    81  	AEPush APIEndpoint = "/ds/push"
    82  	// AERender renders the current dataset ref
    83  	AERender APIEndpoint = "/ds/render"
    84  	// AERemove exposes the dataset remove mechanics
    85  	AERemove APIEndpoint = "/ds/remove"
    86  	// AEValidate is an endpoint for validating datasets
    87  	AEValidate APIEndpoint = "/ds/validate"
    88  	// AEManifest generates a manifest for a dataset path
    89  	AEManifest APIEndpoint = "/ds/manifest"
    90  	// AEManifestMissing generates a manifest of blocks that are not present on this repo for a given manifest
    91  	AEManifestMissing APIEndpoint = "/ds/manifest/missing"
    92  	// AEDAGInfo generates a dag.Info for a dataset path
    93  	AEDAGInfo APIEndpoint = "/ds/daginfo"
    94  	// AEWhatChanged gets what changed at a specific version in history
    95  	AEWhatChanged APIEndpoint = "/ds/whatchanged"
    96  
    97  	// peer endpoints
    98  
    99  	// AEPeer fetches a specific peer
   100  	AEPeer APIEndpoint = "/peer"
   101  	// AEConnect initiates an explicit connection to a peer
   102  	AEConnect APIEndpoint = "/peer/connect"
   103  	// AEDisconnect closes an explicit connection to a peer
   104  	AEDisconnect APIEndpoint = "/peer/disconnect"
   105  	// AEPeers fetches all the peers
   106  	AEPeers APIEndpoint = "/peer/list"
   107  
   108  	// profile endpoints
   109  
   110  	// AEGetProfile is an alias for the me endpoint
   111  	AEGetProfile APIEndpoint = "/profile"
   112  	// AESetProfile is an endpoint to set the profile
   113  	AESetProfile APIEndpoint = "/profile/set"
   114  	// AESetProfilePhoto is an endpoint to set the profile photo
   115  	AESetProfilePhoto APIEndpoint = "/profile/photo"
   116  	// AESetPosterPhoto is an endpoint to set the profile poster
   117  	AESetPosterPhoto APIEndpoint = "/profile/poster"
   118  
   119  	// remote client endpoints
   120  
   121  	// AEFeeds fetches and index of named feeds
   122  	AEFeeds APIEndpoint = "/remote/feeds"
   123  	// AEPreview fetches a dataset preview from the registry
   124  	AEPreview APIEndpoint = "/remote/preview"
   125  	// AERemoteRemove removes a dataset from a given remote
   126  	AERemoteRemove APIEndpoint = "/remote/remove"
   127  	// AERegistryNew creates a new user on the registry
   128  	AERegistryNew APIEndpoint = "/remote/registry/profile/new"
   129  	// AERegistryProve links an the current peer with an existing
   130  	// user on the registry
   131  	AERegistryProve APIEndpoint = "/remote/registry/profile/prove"
   132  	// AESearch returns a list of dataset search results
   133  	AESearch APIEndpoint = "/registry/search"
   134  	// AERegistryGetFollowing returns a list of datasets a user follows
   135  	AERegistryGetFollowing APIEndpoint = "/registry/follow/list"
   136  	// AERegistryFollow updates the follow status of the current user for a given dataset
   137  	AERegistryFollow APIEndpoint = "/registry/follow"
   138  
   139  	// sync endpoints
   140  
   141  	// AERemoteDSync exposes the dsync mechanics
   142  	AERemoteDSync APIEndpoint = "/remote/dsync"
   143  	// AERemoteLogSync exposes the logsync mechanics
   144  	AERemoteLogSync APIEndpoint = "/remote/logsync"
   145  	// AERemoteRefs exposes the remote ref resolution mechanics
   146  	AERemoteRefs APIEndpoint = "/remote/refs"
   147  
   148  	// other endpoints
   149  
   150  	// AEConnections lists qri & IPFS connections
   151  	AEConnections APIEndpoint = "/connections"
   152  	// AEConnectedQriProfiles lists qri profile connections
   153  	AEConnectedQriProfiles APIEndpoint = "/connections/qri"
   154  
   155  	// DenyHTTP will disable HTTP access to a method
   156  	DenyHTTP = APIEndpoint("")
   157  )
   158  
   159  // DsRefFromPath parses a path and returns a dsref.Ref
   160  func DsRefFromPath(prefix, path string) (dsref.Ref, error) {
   161  	refstr := PathToQriPath(prefix, path)
   162  	return dsref.ParsePeerRef(refstr)
   163  }
   164  
   165  // PathToQriPath converts a http path to a
   166  // qri path
   167  func PathToQriPath(prefix, path string) string {
   168  	path = strings.TrimPrefix(path, prefix)
   169  	paramIndex := strings.Index(path, "?")
   170  	if paramIndex != -1 {
   171  		path = path[:paramIndex]
   172  	}
   173  	// TODO(dustmop): If a user has a dataset named "at", this breaks
   174  	path = strings.Replace(path, "/at/", "@/", 1)
   175  	path = strings.TrimPrefix(path, "/")
   176  	return path
   177  }
   178  
   179  // DatasetRefFromReq examines the path element of a request URL
   180  // to
   181  func DatasetRefFromReq(prefix string, r *http.Request) (dsref.Ref, error) {
   182  	if r.URL.String() == "" || r.URL.Path == "" {
   183  		return dsref.Ref{}, nil
   184  	}
   185  	return DsRefFromPath(prefix, r.URL.Path)
   186  }