@ -356,6 +356,18 @@ func (s *Server) registerResourcePublicRoutes(g *echo.Group) {
if err != nil {
return echo . NewHTTPError ( http . StatusBadRequest , fmt . Sprintf ( "ID is not a number: %s" , c . Param ( "resourceId" ) ) ) . SetInternal ( err )
}
resourceVisibility , err := CheckResourceVisibility ( ctx , s . Store , resourceID )
if err != nil {
return echo . NewHTTPError ( http . StatusBadRequest , "Failed to get resource visibility" ) . SetInternal ( err )
}
// Protected resource require a logined user
userID , ok := c . Get ( getUserIDContextKey ( ) ) . ( int )
if resourceVisibility == store . Protected && ( ! ok || userID <= 0 ) {
return echo . NewHTTPError ( http . StatusUnauthorized , "Resource visibility not match" ) . SetInternal ( err )
}
publicID , err := url . QueryUnescape ( c . Param ( "publicId" ) )
if err != nil {
return echo . NewHTTPError ( http . StatusBadRequest , fmt . Sprintf ( "publicID is invalid: %s" , c . Param ( "publicId" ) ) ) . SetInternal ( err )
@ -370,6 +382,11 @@ func (s *Server) registerResourcePublicRoutes(g *echo.Group) {
return echo . NewHTTPError ( http . StatusInternalServerError , fmt . Sprintf ( "Failed to find resource by ID: %v" , resourceID ) ) . SetInternal ( err )
}
// Private resource require logined user is the creator
if resourceVisibility == store . Private && ( ! ok || userID != resource . CreatorID ) {
return echo . NewHTTPError ( http . StatusUnauthorized , "Resource visibility not match" ) . SetInternal ( err )
}
blob := resource . Blob
if resource . InternalPath != "" {
src , err := os . Open ( resource . InternalPath )
@ -401,6 +418,18 @@ func (s *Server) registerResourcePublicRoutes(g *echo.Group) {
if err != nil {
return echo . NewHTTPError ( http . StatusBadRequest , fmt . Sprintf ( "ID is not a number: %s" , c . Param ( "resourceId" ) ) ) . SetInternal ( err )
}
resourceVisibility , err := CheckResourceVisibility ( ctx , s . Store , resourceID )
if err != nil {
return echo . NewHTTPError ( http . StatusBadRequest , "Failed to get resource visibility" ) . SetInternal ( err )
}
// Protected resource require a logined user
userID , ok := c . Get ( getUserIDContextKey ( ) ) . ( int )
if resourceVisibility == store . Protected && ( ! ok || userID <= 0 ) {
return echo . NewHTTPError ( http . StatusUnauthorized , "Resource visibility not match" ) . SetInternal ( err )
}
publicID , err := url . QueryUnescape ( c . Param ( "publicId" ) )
if err != nil {
return echo . NewHTTPError ( http . StatusBadRequest , fmt . Sprintf ( "publicID is invalid: %s" , c . Param ( "publicId" ) ) ) . SetInternal ( err )
@ -420,6 +449,11 @@ func (s *Server) registerResourcePublicRoutes(g *echo.Group) {
return echo . NewHTTPError ( http . StatusInternalServerError , fmt . Sprintf ( "Failed to find resource by ID: %v" , resourceID ) ) . SetInternal ( err )
}
// Private resource require logined user is the creator
if resourceVisibility == store . Private && ( ! ok || userID != resource . CreatorID ) {
return echo . NewHTTPError ( http . StatusUnauthorized , "Resource visibility not match" ) . SetInternal ( err )
}
blob := resource . Blob
if resource . InternalPath != "" {
resourcePath := resource . InternalPath
@ -552,3 +586,48 @@ func getOrGenerateThumbnailImage(srcBlob []byte, dstPath string) ([]byte, error)
}
return dstBlob , nil
}
func CheckResourceVisibility ( ctx context . Context , s * store . Store , resourceID int ) ( store . Visibility , error ) {
memoResourceFind := & api . MemoResourceFind {
ResourceID : & resourceID ,
}
memoResources , err := s . FindMemoResourceList ( ctx , memoResourceFind )
if err != nil {
return store . Private , err
}
// If resource is belongs to no memo, it'll always PRIVATE
if len ( memoResources ) == 0 {
return store . Private , nil
}
memoIDs := make ( [ ] int , 0 , len ( memoResources ) )
for _ , memoResource := range memoResources {
memoIDs = append ( memoIDs , memoResource . MemoID )
}
visibilityList , err := s . FindMemosVisibilityList ( ctx , memoIDs )
if err != nil {
return store . Private , err
}
var isProtected bool
for _ , visibility := range visibilityList {
// If any memo is PUBLIC, resource do
if visibility == store . Public {
return store . Public , nil
}
if visibility == store . Protected {
isProtected = true
}
}
// If no memo is PUBLIC, but any memo is PROTECTED, resource do
if isProtected {
return store . Protected , nil
}
// If all memo is PRIVATE, the resource do
return store . Private , nil
}