Skip to content

Commit

Permalink
parse zip
Browse files Browse the repository at this point in the history
  • Loading branch information
diego-m-ob committed Sep 27, 2024
1 parent 5ce21b6 commit affb422
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 33 deletions.
41 changes: 31 additions & 10 deletions pkg/server/import_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ package server
import (
"archive/zip"
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

"github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -41,15 +43,14 @@ func (h importHandlers) postImportReview(c echo.Context) error {
return c.JSON(http.StatusBadRequest, NewErrorResponse(err))
}

if err := request.Validate(); err != nil {
model, err := h.doImport(request, logger)
if err != nil {
return c.JSON(http.StatusBadRequest, NewErrorResponse(err))
}

if _, err := h.doImport(request, logger); err != nil {
return c.JSON(http.StatusBadRequest, NewErrorResponse(err))
response := models.ImportReviewResponse{
Discovery: model.DiscoveryModel,
}

response := models.ImportReviewResponse{}
logger.Info("Imported")

return c.JSON(http.StatusOK, response)
Expand All @@ -61,34 +62,54 @@ func (h importHandlers) postImportRerun(c echo.Context) error {

request := models.ImportRequest{}
if err := c.Bind(&request); err != nil {
logger.WithField("error", err).Error("Failed to bind request")
return c.JSON(http.StatusBadRequest, NewErrorResponse(err))
}

if err := request.Validate(); err != nil {
logger.WithField("error", err).Error("Request validation failed")
return c.JSON(http.StatusBadRequest, NewErrorResponse(err))
}

discovery, err := h.doImport(request, logger)
model, err := h.doImport(request, logger)
if err != nil {
logger.WithField("error", err).Error("Failed to do import")
return c.JSON(http.StatusBadRequest, NewErrorResponse(err))
}

response := models.ImportRerunResponse{
Discovery: discovery,
Discovery: model.DiscoveryModel,
}
logger.Info("Imported")

return c.JSON(http.StatusOK, response)
}

// nolint:unparam
func (h importHandlers) doImport(request models.ImportRequest, logger *logrus.Entry) (discovery.ModelDiscovery, error) {
var discoveryModel discovery.ModelDiscovery
func (h importHandlers) doImport(request models.ImportRequest, logger *logrus.Entry) (discovery.Model, error) {
var discoveryModel discovery.Model
logger.WithField("len(request.Report)", len(request.Report)).Info("Importing ...")

// Decode the base64 string
// Split the string to get only the base64 part
parts := strings.SplitN(request.Report, ",", 2)
if len(parts) != 2 {
logger.Error("Invalid report format")
return discoveryModel, fmt.Errorf("invalid report format")
}
base64Data := parts[1]

// Decode the base64 string
reportBytes, err := base64.StdEncoding.DecodeString(base64Data)
if err != nil {
logger.WithField("error", err).Error("Failed to decode base64 string")
return discoveryModel, fmt.Errorf("failed to decode report: %w", err)
}

// Create a reader for the zip file
zipReader, err := zip.NewReader(bytes.NewReader([]byte(request.Report)), int64(len(request.Report)))
zipReader, err := zip.NewReader(bytes.NewReader(reportBytes), int64(len(request.Report)))
if err != nil {
logger.WithField("error", err).Error("Failed to create zip reader")
return discoveryModel, fmt.Errorf("failed to create zip reader: %w", err)
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/server/models/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
// ImportRequest - Request to `/api/import/review` or `/api/import/rerun` POST.
// TODO(mbana): Needs more work.
type ImportRequest struct {
Report string `json:"report" form:"report"` // The exported report ZIP archive.
Report string `json:"report"` // The exported report ZIP archive.
}

// Validate - used by github.com/go-ozzo/ozzo-validation to validate struct.
Expand All @@ -20,6 +20,7 @@ func (r ImportRequest) Validate() error {

// ImportReviewResponse - Response to `/api/import/review` POST.
type ImportReviewResponse struct {
Discovery discovery.ModelDiscovery
}

// ImportRerunResponse - Response to `/api/import/rerun` POST.
Expand Down
32 changes: 22 additions & 10 deletions web/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,19 @@ export default {
* Call POST `/api/import/review`.
* @param {*} payload See `ImportRequest` in `pkg/server/models/import.go`.
*/
async importReview(payload) {
const response = await apiUtil.post(IMPORT_REVIEW, payload);
async importReview(base64Content) {
const jsonPayload = {
report: base64Content
};

const headers = {
[apiUtil.Headers.HeaderAccept]: 'application/json',
'Content-Type': 'application/json'
};

const response = await apiUtil.post(IMPORT_REVIEW, jsonPayload, null, headers);
const data = await response.json();

// `fetch` does not throw an error even when status is not 200.
// See: https://github.com/whatwg/fetch/issues/18
if (response.status !== 200) {
throw data;
}
Expand All @@ -70,16 +77,21 @@ export default {
* Call POST `/api/import/rerun`.
* @param {*} payload See `ImportRequest` in `pkg/server/models/import.go`.
*/
async importRerun(payload) {
const response = await apiUtil.post(IMPORT_RERUN, payload);
async importRerun(base64Content) {
const jsonPayload = {
report: base64Content
};

const headers = {
[apiUtil.Headers.HeaderAccept]: 'application/json',
'Content-Type': 'application/json'
};

const response = await apiUtil.post(IMPORT_RERUN, jsonPayload, null, headers);
const data = await response.json();

// `fetch` does not throw an error even when status is not 200.
// See: https://github.com/whatwg/fetch/issues/18
if (response.status !== 200) {
throw data;
}

return data;
},
};
16 changes: 6 additions & 10 deletions web/src/store/modules/importer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,19 @@ export default {
console.log('state.is_review=', state.is_review);
// eslint-disable-next-line no-console
console.log('state.is_rerun=', state.is_rerun);
// eslint-disable-next-line no-console
console.log('state.report_zip_archive=', state.report_zip_archive);

if (state.is_review) {
const payload = {
report: state.report_zip_archive,
};
const results = await api.importReview(payload);
const results = await api.importReview(state.report_zip_archive);
commit(mutationTypes.SET_IMPORT_RESPONSE, results);
return Promise.resolve({});
return Promise.resolve(results);
}

if (state.is_rerun) {
const payload = {
report: state.report_zip_archive,
};
const results = await api.importRerun(payload);
const results = await api.importRerun(state.report_zip_archive);
commit(mutationTypes.SET_IMPORT_RESPONSE, results);
return Promise.resolve({});
return Promise.resolve(results);
}

return Promise.resolve({});
Expand Down
5 changes: 3 additions & 2 deletions web/src/views/Wizard/WizardImport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ export default {
const reader = new FileReader();
reader.onload = evt => resolve(evt.target.result);
reader.onerror = evt => reject(new Error(`reading ${file.name}: ${evt.target.result}`));
reader.readAsText(file);
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(file);
});
},
/**
Expand All @@ -138,6 +138,7 @@ export default {
// If file is set, read the file then set the value in the store.
try {
this.report_zip_archive = await this.readFile(this.file);
console.log('report_zip_archive=', this.report_zip_archive);
} catch (err) {
// TODO(mbana): ignoring errors for now just clear out the previously
// selected file so that they have to re-upload.
Expand Down

0 comments on commit affb422

Please sign in to comment.