diff --git a/gitrpc/operations.go b/gitrpc/operations.go index c35f349cc..f0e4f53e1 100644 --- a/gitrpc/operations.go +++ b/gitrpc/operations.go @@ -7,7 +7,6 @@ package gitrpc import ( "bytes" "context" - "encoding/base64" "errors" "fmt" "io" @@ -30,11 +29,10 @@ func (FileAction) Enum() []interface{} { // CommitFileAction holds file operation data. type CommitFileAction struct { - Action FileAction - Path string - Payload []byte - Encoding string - SHA string + Action FileAction + Path string + Payload []byte + SHA string } // CommitFilesParams holds the data for file operations. @@ -100,10 +98,7 @@ func (c *Client) CommitFiles(ctx context.Context, params *CommitFilesParams) (Co // send file content n := 0 buffer := make([]byte, FileTransferChunkSize) - reader := io.Reader(bytes.NewReader(action.Payload)) - if action.Encoding == "base64" { - reader = base64.NewDecoder(base64.StdEncoding, reader) - } + reader := bytes.NewReader(action.Payload) for { n, err = reader.Read(buffer) if errors.Is(err, io.EOF) { diff --git a/internal/api/controller/repo/commit.go b/internal/api/controller/repo/commit.go index 4fe86d202..13699aca3 100644 --- a/internal/api/controller/repo/commit.go +++ b/internal/api/controller/repo/commit.go @@ -6,6 +6,7 @@ package repo import ( "context" + "encoding/base64" "fmt" "github.com/harness/gitness/gitrpc" @@ -17,11 +18,11 @@ import ( // CommitFileAction holds file operation data. type CommitFileAction struct { - Action gitrpc.FileAction `json:"action"` - Path string `json:"path"` - Payload string `json:"payload"` - Encoding string `json:"encoding"` - SHA string `json:"sha"` + Action gitrpc.FileAction `json:"action"` + Path string `json:"path"` + Payload string `json:"payload"` + Encoding enum.ContentEncodingType `json:"encoding"` + SHA string `json:"sha"` } // CommitFilesOptions holds the data for file operations. @@ -51,12 +52,25 @@ func (c *Controller) CommitFiles(ctx context.Context, session *auth.Session, actions := make([]gitrpc.CommitFileAction, len(in.Actions)) for i, action := range in.Actions { + var rawPayload []byte + switch action.Encoding { + case enum.ContentEncodingTypeBase64: + rawPayload, err = base64.StdEncoding.DecodeString(action.Payload) + if err != nil { + return CommitFilesResponse{}, fmt.Errorf("failed to decode base64 payload: %w", err) + } + case enum.ContentEncodingTypeUTF8: + fallthrough + default: + // by default we treat content as is + rawPayload = []byte(action.Payload) + } + actions[i] = gitrpc.CommitFileAction{ - Action: action.Action, - Path: action.Path, - Payload: []byte(action.Payload), - Encoding: action.Encoding, - SHA: action.SHA, + Action: action.Action, + Path: action.Path, + Payload: rawPayload, + SHA: action.SHA, } } diff --git a/internal/api/controller/repo/get_content.go b/internal/api/controller/repo/get_content.go index 02de02869..9a0866001 100644 --- a/internal/api/controller/repo/get_content.go +++ b/internal/api/controller/repo/get_content.go @@ -45,21 +45,15 @@ type GetContentOutput struct { Content Content `json:"content"` } -type FileEncodingType string - -const ( - FileEncodingTypeBase64 FileEncodingType = "base64" -) - // Content restricts the possible types of content returned by the api. type Content interface { isContent() } type FileContent struct { - Encoding FileEncodingType `json:"encoding"` - Data string `json:"data"` - Size int64 `json:"size"` + Encoding enum.ContentEncodingType `json:"encoding"` + Data string `json:"data"` + Size int64 `json:"size"` } func (c *FileContent) isContent() {} @@ -175,14 +169,12 @@ func (c *Controller) getFileContent(ctx context.Context, readParams gitrpc.ReadP SizeLimit: maxGetContentFileSize, }) if err != nil { - // TODO: handle not found error - // This requires gitrpc to also return notfound though! return nil, fmt.Errorf("failed to get file content: %w", err) } return &FileContent{ Size: output.Blob.Size, - Encoding: FileEncodingTypeBase64, + Encoding: enum.ContentEncodingTypeBase64, Data: base64.StdEncoding.EncodeToString(output.Blob.Content), }, nil } diff --git a/types/enum/encoding.go b/types/enum/encoding.go new file mode 100644 index 000000000..d1ed78afa --- /dev/null +++ b/types/enum/encoding.go @@ -0,0 +1,23 @@ +// Copyright 2022 Harness Inc. All rights reserved. +// Use of this source code is governed by the Polyform Free Trial License +// that can be found in the LICENSE.md file for this repository. + +package enum + +// ContentEncodingType describes the encoding of content. +type ContentEncodingType string + +const ( + // ContentEncodingTypeUTF8 describes utf-8 encoded content. + ContentEncodingTypeUTF8 ContentEncodingType = "utf8" + + // ContentEncodingTypeBase64 describes base64 encoded content. + ContentEncodingTypeBase64 ContentEncodingType = "base64" +) + +func (ContentEncodingType) Enum() []interface{} { return toInterfaceSlice(contentEncodingTypes) } + +var contentEncodingTypes = sortEnum([]ContentEncodingType{ + ContentEncodingTypeUTF8, + ContentEncodingTypeBase64, +}) diff --git a/web/src/services/code/index.tsx b/web/src/services/code/index.tsx index 256558b4d..0529755f4 100644 --- a/web/src/services/code/index.tsx +++ b/web/src/services/code/index.tsx @@ -7,6 +7,8 @@ import { getConfig } from '../config' export const SPEC_VERSION = '0.0.0' export type EnumAccessGrant = number +export type EnumContentEncodingType = 'base64' | 'utf8' + export type EnumMergeCheckStatus = string export type EnumMergeMethod = 'merge' | 'rebase' | 'squash' @@ -268,7 +270,7 @@ export interface RepoCommitDivergenceRequest { export interface RepoCommitFileAction { action?: GitrpcFileAction - encoding?: string + encoding?: EnumContentEncodingType path?: string payload?: string sha?: string @@ -303,12 +305,10 @@ export type RepoContentType = string export interface RepoFileContent { data?: string - encoding?: RepoFileEncodingType + encoding?: EnumContentEncodingType size?: number } -export type RepoFileEncodingType = string - export interface RepoMergeCheck { mergeable?: boolean } diff --git a/web/src/services/code/swagger.yaml b/web/src/services/code/swagger.yaml index 62a792683..0a201c94d 100644 --- a/web/src/services/code/swagger.yaml +++ b/web/src/services/code/swagger.yaml @@ -3547,6 +3547,11 @@ components: schemas: EnumAccessGrant: type: integer + EnumContentEncodingType: + enum: + - base64 + - utf8 + type: string EnumMergeCheckStatus: type: string EnumMergeMethod: @@ -4011,7 +4016,7 @@ components: action: $ref: '#/components/schemas/GitrpcFileAction' encoding: - type: string + $ref: '#/components/schemas/EnumContentEncodingType' path: type: string payload: @@ -4062,12 +4067,10 @@ components: data: type: string encoding: - $ref: '#/components/schemas/RepoFileEncodingType' + $ref: '#/components/schemas/EnumContentEncodingType' size: type: integer type: object - RepoFileEncodingType: - type: string RepoMergeCheck: properties: mergeable: