Skip to content

Commit

Permalink
refactoring: testifysec/archivista-api as a pkg
Browse files Browse the repository at this point in the history
The current "github.com/testifysec/archivista-api" was detached from
the Archivista from the historical strategy by TestifySec.

TestifySec donated the Archivista project to the in-toto project,
which makes more sense to the API package being part of the
Archivista source code.

This commit adds "github.com/testifysec/archivista-api" as pkg in
Archivista.

Closes #113

Signed-off-by: Kairo de Araujo <kairo.araujo@testifysec.com>
  • Loading branch information
kairoaraujo committed Dec 12, 2023
1 parent a63661d commit 9245b73
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 7 deletions.
6 changes: 3 additions & 3 deletions cmd/archivistactl/cmd/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"strings"

"github.com/spf13/cobra"
archivistaapi "github.com/testifysec/archivista-api"
"github.com/testifysec/archivista/pkg/api"
)

var (
Expand Down Expand Up @@ -50,7 +50,7 @@ var (
out = file
}

return archivistaapi.DownloadWithWriter(cmd.Context(), archivistaUrl, args[0], out)
return api.DownloadWithWriter(cmd.Context(), archivistaUrl, args[0], out)
},
}

Expand All @@ -60,7 +60,7 @@ var (
SilenceUsage: true,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
results, err := archivistaapi.GraphQlQuery[retrieveSubjectResults](cmd.Context(), archivistaUrl, retrieveSubjectsQuery, retrieveSubjectVars{Gitoid: args[0]})
results, err := api.GraphQlQuery[retrieveSubjectResults](cmd.Context(), archivistaUrl, retrieveSubjectsQuery, retrieveSubjectVars{Gitoid: args[0]})
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/archivistactl/cmd/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"strings"

"github.com/spf13/cobra"
archivistaapi "github.com/testifysec/archivista-api"
"github.com/testifysec/archivista/pkg/api"
)

var (
Expand Down Expand Up @@ -49,7 +49,7 @@ Digests are expected to be in the form algorithm:digest, for instance: sha256:45
return err
}

results, err := archivistaapi.GraphQlQuery[searchResults](cmd.Context(), archivistaUrl, searchQuery, searchVars{Algorithm: algo, Digest: digest})
results, err := api.GraphQlQuery[searchResults](cmd.Context(), archivistaUrl, searchQuery, searchVars{Algorithm: algo, Digest: digest})
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/archivistactl/cmd/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"os"

"github.com/spf13/cobra"
archivistaapi "github.com/testifysec/archivista-api"
"github.com/testifysec/archivista/pkg/api"
)

var (
Expand Down Expand Up @@ -54,7 +54,7 @@ func storeAttestationByPath(ctx context.Context, baseUrl, path string) (string,
}

defer file.Close()
resp, err := archivistaapi.StoreWithReader(ctx, baseUrl, file)
resp, err := api.StoreWithReader(ctx, baseUrl, file)
if err != nil {
return "", err
}
Expand Down
74 changes: 74 additions & 0 deletions pkg/api/download.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2023 The Witness Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"

"github.com/testifysec/go-witness/dsse"
)

func Download(ctx context.Context, baseUrl string, gitoid string) (dsse.Envelope, error) {
buf := &bytes.Buffer{}
if err := DownloadWithWriter(ctx, baseUrl, gitoid, buf); err != nil {
return dsse.Envelope{}, err
}

env := dsse.Envelope{}
dec := json.NewDecoder(buf)
if err := dec.Decode(&env); err != nil {
return env, err
}

return env, nil
}

func DownloadWithWriter(ctx context.Context, baseUrl, gitoid string, dst io.Writer) error {
downloadUrl, err := url.JoinPath(baseUrl, "download", gitoid)
if err != nil {
return err
}

req, err := http.NewRequestWithContext(ctx, "GET", downloadUrl, nil)
if err != nil {
return err
}

req.Header.Set("Content-Type", "application/json")
hc := &http.Client{}
resp, err := hc.Do(req)
if err != nil {
return nil
}

defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
errMsg, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

return errors.New(string(errMsg))
}

_, err = io.Copy(dst, resp.Body)
return err
}
92 changes: 92 additions & 0 deletions pkg/api/graphql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2023 The Witness Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
)

type graphQLError struct {
Message string `json:"message"`
}

type graphQLResponse[T any] struct {
Data T `json:"data,omitempty"`
Errors []graphQLError `json:"errors,omitempty"`
}

type graphQLRequestBody[TVars any] struct {
Query string `json:"query"`
Variables TVars `json:"variables,omitempty"`
}

func GraphQlQuery[TRes any, TVars any](ctx context.Context, baseUrl, query string, vars TVars) (TRes, error) {
var response TRes
queryUrl, err := url.JoinPath(baseUrl, "query")
if err != nil {
return response, err
}

requestBody := graphQLRequestBody[TVars]{
Query: query,
Variables: vars,
}

reqBody, err := json.Marshal(requestBody)
if err != nil {
return response, err
}

req, err := http.NewRequestWithContext(ctx, "POST", queryUrl, bytes.NewReader(reqBody))
if err != nil {
return response, err
}

req.Header.Set("Content-Type", "application/json")
hc := &http.Client{}
res, err := hc.Do(req)
if err != nil {
return response, err
}

defer res.Body.Close()
if res.StatusCode != http.StatusOK {
errMsg, err := io.ReadAll(res.Body)
if err != nil {
return response, err
}

return response, errors.New(string(errMsg))
}

dec := json.NewDecoder(res.Body)
gqlRes := graphQLResponse[TRes]{}
if err := dec.Decode(&gqlRes); err != nil {
return response, err
}

if len(gqlRes.Errors) > 0 {
return response, fmt.Errorf("graph ql query failed: %v", gqlRes.Errors)
}

return gqlRes.Data, nil
}
77 changes: 77 additions & 0 deletions pkg/api/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2023 The Witness Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"

"github.com/testifysec/go-witness/dsse"
)

type StoreResponse struct {
Gitoid string `json:"gitoid"`
}

func Store(ctx context.Context, baseUrl string, envelope dsse.Envelope) (StoreResponse, error) {
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
if err := enc.Encode(envelope); err != nil {
return StoreResponse{}, err
}

return StoreWithReader(ctx, baseUrl, buf)
}

func StoreWithReader(ctx context.Context, baseUrl string, r io.Reader) (StoreResponse, error) {
uploadPath, err := url.JoinPath(baseUrl, "upload")
if err != nil {
return StoreResponse{}, err
}

req, err := http.NewRequestWithContext(ctx, "POST", uploadPath, r)
if err != nil {
return StoreResponse{}, err
}

req.Header.Set("Content-Type", "application/json")
hc := &http.Client{}
resp, err := hc.Do(req)
if err != nil {
return StoreResponse{}, err
}

defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return StoreResponse{}, err
}

if resp.StatusCode != http.StatusOK {
return StoreResponse{}, errors.New(string(bodyBytes))
}

storeResp := StoreResponse{}
if err := json.Unmarshal(bodyBytes, &storeResp); err != nil {
return StoreResponse{}, err
}

return storeResp, nil
}

0 comments on commit 9245b73

Please sign in to comment.