fix(share): allow special characters in share passwords (#2528)

Passwords containing emoji or URI-reserved characters produced an
unparseable cloudreve:// share URI, and the create/update binding
rejected anything non-alphanumeric.

- NewShareUri percent-encodes the userinfo via url.UserPassword; the
  parse side already decodes it
- drop the alphanum binding on ShareCreateService.Password
- round-trip test covers emoji, spaces, and reserved characters

Authored By: TDvorak <info@tdvorak.dev>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
pull/3582/head
Tomas Dvorak 2 weeks ago
parent 5817da287a
commit b85216fd51

@ -356,9 +356,9 @@ func SearchCategoryFromString(s string) setting.SearchCategory {
func NewShareUri(id, password string) string {
if password != "" {
return fmt.Sprintf("%s://%s:%s@%s", constants.CloudreveScheme, id, password, constants.FileSystemShare)
return fmt.Sprintf("%s://%s@%s", constants.CloudreveScheme, url.UserPassword(id, password), constants.FileSystemShare)
}
return fmt.Sprintf("%s://%s@%s", constants.CloudreveScheme, id, constants.FileSystemShare)
return fmt.Sprintf("%s://%s@%s", constants.CloudreveScheme, url.User(id), constants.FileSystemShare)
}
func NewMyUri(id string) string {

@ -0,0 +1,21 @@
package fs
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestShareUriPasswordRoundTrip(t *testing.T) {
for _, password := range []string{"plain", "with space", "a:b@c/d?e", "😀😴😭", "$%^&*"} {
u, err := NewUriFromString(NewShareUri("abc123", password))
require.NoError(t, err, "password %q", password)
require.Equal(t, "abc123", u.ID(""))
require.Equal(t, password, u.Password(), "password %q", password)
}
u, err := NewUriFromString(NewShareUri("abc123", ""))
require.NoError(t, err)
require.Equal(t, "abc123", u.ID(""))
require.Equal(t, "", u.Password())
}

@ -22,7 +22,7 @@ type (
ShareCreateService struct {
Uri string `json:"uri" binding:"required"`
IsPrivate bool `json:"is_private"`
Password string `json:"password" binding:"omitempty,max=32,alphanum"`
Password string `json:"password" binding:"omitempty,max=32"`
RemainDownloads int `json:"downloads"`
Expire int `json:"expire"`
ShareView bool `json:"share_view"`

Loading…
Cancel
Save