Пример #1
0
func (c *controller) ListTree(user *entities.User, pathSpec string) ([]*entities.ObjectInfo, error) {
	storagePath := c.getStoragePath(user, pathSpec)
	finfo, err := os.Stat(storagePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, codes.NewErr(codes.NotFound, err.Error())
		}
		return nil, err
	}
	if !finfo.IsDir() {
		return nil, codes.NewErr(codes.BadInputData, "object is not a tree")
	}
	fd, err := os.Open(storagePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, codes.NewErr(codes.NotFound, err.Error())
		}
		return nil, err
	}
	finfos, err := fd.Readdir(-1) // read all files inside the directory.
	if err != nil {
		return nil, err
	}
	var oinfos []*entities.ObjectInfo
	for _, fi := range finfos {
		p := filepath.Join(pathSpec, filepath.Base(fi.Name()))
		oinfos = append(oinfos, c.getObjectInfo(p, fi))
	}
	return oinfos, nil
}
Пример #2
0
// UploadBLOB saves a blob to disk.
// This operation has 4 phases:
// 1) Write the blob to a temporary directory.
// 2) Optional: calculate the checksum of the blob if server-checksum is enabled.
// 3) Optional: if a client-checksum is provided, check if it matches with the server-checksum.
// 4) Move the blob from the temporary directory to user directory.
func (c *controller) UploadBLOB(user *entities.User, pathSpec string, r io.Reader, clientchecksum string) error {
	tempFileName, err := c.saveToTempFile(r)
	if err != nil {
		return err
	}

	// 2) Optional: calculate the checksum of the blob.
	if c.conf.GetDirectives().Data.Simple.Checksum != "" {
		serverchecksum, err := c.computeChecksum(tempFileName)
		if err != nil {
			return err
		}

		// 3) Optional: verify if server-checksum matches client-checksum.
		if c.conf.GetDirectives().Data.Simple.VerifyClientChecksum {
			if serverchecksum != clientchecksum {
				msg := fmt.Sprintf("checksums differ. serverchksum:%q clientchksum:%q",
					serverchecksum, clientchecksum)
				return codes.NewErr(codes.BadChecksum, msg)
			}
		}
	}

	// 4) Move the blob from the temporary directory to user directory.
	storagePath := c.getStoragePath(user, pathSpec)
	if err := os.Rename(tempFileName, storagePath); err != nil {
		if os.IsNotExist(err) {
			return codes.NewErr(codes.NotFound, err.Error())
		}
		return err
	}

	return c.metaDataController.SetDBMetaData(c.metaDataController.GetVirtualPath(user, pathSpec), clientchecksum, c.metaDataController.GetVirtualPath(user, "/"))
}
Пример #3
0
func (c *controller) MoveObject(user *entities.User, sourcePathSpec, targetPathSpec string) error {
	sourceStoragePath := c.getStoragePath(user, sourcePathSpec)
	targetStoragePath := c.getStoragePath(user, targetPathSpec)
	err := os.Rename(sourceStoragePath, targetStoragePath)
	if err != nil {
		if os.IsNotExist(err) {
			return codes.NewErr(codes.NotFound, err.Error())
		} else if _, ok := err.(*os.LinkError); ok {
			return codes.NewErr(codes.BadInputData, err.Error())
		}
		return err
	}
	return nil
}
Пример #4
0
// Authenticate authenticates an user using an username and a password.
func (s *svc) Token(w http.ResponseWriter, r *http.Request) {
	log := keys.MustGetLog(r)

	if r.Body == nil {
		log.WithError(errors.New("body is nil")).Info("cannot read body")
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	authReq := &TokenRequest{}
	if err := json.NewDecoder(r.Body).Decode(authReq); err != nil {
		e := codes.NewErr(codes.BadInputData, "")
		log.WithError(e).Error(codes.BadInputData.String())
		w.WriteHeader(http.StatusBadRequest)
		if err := json.NewEncoder(w).Encode(e); err != nil {
			log.WithError(err).Error("cannot encode")
		}
		return
	}

	token, err := s.authenticationController.Authenticate(authReq.Username, authReq.Password)
	if err != nil {
		s.handleTokenError(err, w, r)
		return
	}
	log.WithField("user", authReq.Username).Info("token generated")

	res := &TokenResponse{AccessToken: token}

	w.WriteHeader(http.StatusCreated)
	if err := json.NewEncoder(w).Encode(res); err != nil {
		log.WithError(err).Error("cannot encode")
	}
}
Пример #5
0
func (s *svc) handleTokenError(err error, w http.ResponseWriter, r *http.Request) {
	log := keys.MustGetLog(r)
	e := codes.NewErr(codes.BadInputData, "user or password do not match")
	log.WithError(e).Error(codes.BadInputData.String())
	w.WriteHeader(http.StatusBadRequest)
	if err := json.NewEncoder(w).Encode(e); err != nil {
		log.WithError(err).Error("cannot encode")
	}
	return
}
Пример #6
0
func (c *controller) DownloadBLOB(user *entities.User, pathSpec string) (io.Reader, error) {
	storagePath := c.getStoragePath(user, pathSpec)
	fd, err := os.Open(storagePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, codes.NewErr(codes.NotFound, err.Error())
		}
		return nil, err
	}
	return fd, nil
}
Пример #7
0
func (c *controller) ExamineObject(user *entities.User, pathSpec string) (*entities.ObjectInfo, error) {
	storagePath := c.getStoragePath(user, pathSpec)
	finfo, err := os.Stat(storagePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, codes.NewErr(codes.NotFound, err.Error())
		}
		return nil, err
	}
	oinfo := c.getObjectInfo(pathSpec, finfo)
	return oinfo, nil
}
Пример #8
0
func TestMove_withError(t *testing.T) {
	dirs := defaultDirs
	o := newObject(t)
	o.setupService(t, &dirs)

	o.mockMetaDataController.On("MoveObject").Once().Return(codes.NewErr(99, ""))

	r, err := http.NewRequest("POST", moveURL+"tree", nil)
	require.Nil(t, err)
	w := httptest.NewRecorder()
	o.wrapAuthenticatedRequest(w, r, http.HandlerFunc(o.service.MoveObject))
	require.Equal(t, http.StatusInternalServerError, w.Code)
}
Пример #9
0
func TestListTree_withBadInputError(t *testing.T) {
	dirs := defaultDirs
	o := newObject(t)
	o.setupService(t, &dirs)

	o.mockMetaDataController.On("ListTree").Once().Return(oinfos, codes.NewErr(codes.BadInputData, ""))

	r, err := http.NewRequest("GET", listURL+"tree", nil)
	require.Nil(t, err)
	w := httptest.NewRecorder()
	o.wrapAuthenticatedRequest(w, r, http.HandlerFunc(o.service.ListTree))
	require.Equal(t, http.StatusBadRequest, w.Code)
}
Пример #10
0
func TestUpload_withError(t *testing.T) {
	dirs := defaultDirs
	o := newObject(t)
	o.setupService(t, &dirs)

	reader := strings.NewReader("1")
	o.mockDataController.On("UploadBLOB").Return(codes.NewErr(99, ""))

	r, err := http.NewRequest("PUT", uploadURL+"myblob", reader)
	require.Nil(t, err)
	w := httptest.NewRecorder()
	o.wrapAuthenticatedRequest(w, r, http.HandlerFunc(o.service.Upload))
	require.Equal(t, http.StatusInternalServerError, w.Code)
}
Пример #11
0
func TestDownload_withNotFoundError(t *testing.T) {
	dirs := defaultDirs
	o := newObject(t)
	o.setupService(t, &dirs)

	reader := strings.NewReader("1")
	o.mockDataController.On("DownloadBLOB").Return(reader, codes.NewErr(codes.NotFound, ""))

	r, err := http.NewRequest("GET", downloadURL+"myblob", nil)
	require.Nil(t, err)
	w := httptest.NewRecorder()
	o.wrapAuthenticatedRequest(w, r, http.HandlerFunc(o.service.Download))
	require.Equal(t, http.StatusNotFound, w.Code)
}
Пример #12
0
// ExamineObject returns the metadata associated with the object.
func (c *Controller) ExamineObject(user *entities.User, pathSpec string) (*entities.ObjectInfo, error) {
	storagePath := c.getStoragePath(user, pathSpec)
	finfo, err := os.Stat(storagePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, codes.NewErr(codes.NotFound, err.Error())
		}
		return nil, err
	}

	rec, err := c.GetDBMetaData(c.GetVirtualPath(user, pathSpec), true, c.GetVirtualPath(user, "/"))
	if err != nil {
		return nil, err
	}

	oinfo := c.getObjectInfo(pathSpec, finfo, rec)
	return oinfo, nil
}