Compare commits

..

4 Commits

Author SHA1 Message Date
ErickSkrauch
b73582bbf4 Do not limit hash format only to md5 2018-03-19 02:16:07 +03:00
ErickSkrauch
34598e39bc Allow any uuid version 2018-03-19 01:16:37 +03:00
ErickSkrauch
9fc6ca54d9 Fix latest tag condition 2018-02-17 02:21:03 +03:00
ErickSkrauch
aed957a896 Fix latest tag condition 2018-02-17 02:15:20 +03:00
10 changed files with 26 additions and 109 deletions

View File

@@ -35,7 +35,7 @@ jobs:
- docker build -t elyby/chrly:$DOCKER_TAG .
- docker push elyby/chrly:$DOCKER_TAG
- |
if [ -z ${TRAVIS_TAG+x} ]; then
if [ ! -z ${TRAVIS_TAG+x} ] && [[ "$TRAVIS_TAG" != *"-"* ]]; then
docker tag elyby/chrly:$DOCKER_TAG elyby/chrly:latest
docker push elyby/chrly:latest
fi

View File

@@ -18,20 +18,11 @@ import (
"github.com/thedevsaddam/govalidator"
)
//noinspection GoSnakeCaseUsage
const UUID_ANY = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
var regexUuidAny = regexp.MustCompile(UUID_ANY)
func init() {
govalidator.AddCustomRule("md5", func(field string, rule string, message string, value interface{}) error {
val := []byte(value.(string))
if ok, _ := regexp.Match(`^[a-f0-9]{32}$`, val); !ok {
if message == "" {
message = fmt.Sprintf("The %s field must be a valid md5 hash", field)
}
return errors.New(message)
}
return nil
})
govalidator.AddCustomRule("skinUploadingNotAvailable", func(field string, rule string, message string, value interface{}) error {
if message == "" {
message = "Skin uploading is temporary unavailable"
@@ -39,6 +30,20 @@ func init() {
return errors.New(message)
})
// Add ability to validate any possible uuid form
govalidator.AddCustomRule("uuid_any", func(field string, rule string, message string, value interface{}) error {
str := value.(string)
if !regexUuidAny.MatchString(str) {
if message == "" {
message = fmt.Sprintf("The %s field must contain valid UUID", field)
}
return errors.New(message)
}
return nil
})
}
func (cfg *Config) PostSkin(resp http.ResponseWriter, req *http.Request) {
@@ -152,11 +157,11 @@ func validatePostSkinRequest(request *http.Request) map[string][]string {
validationRules := govalidator.MapData{
"identityId": {"required", "numeric", "min:1"},
"username": {"required"},
"uuid": {"required", "uuid"},
"uuid": {"required", "uuid_any"},
"skinId": {"required", "numeric", "min:1"},
"url": {"url"},
"file:skin": {"ext:png", "size:24576", "mime:image/png"},
"hash": {"md5"},
"hash": {},
"is1_8": {"bool"},
"isSlim": {"bool"},
}

View File

@@ -268,7 +268,6 @@ func TestConfig_PostSkin_RequiredFields(t *testing.T) {
config, mocks := setupMocks(ctrl)
form := url.Values{
"hash": {"this is not md5"},
"mojangTextures": {"someBase64EncodedString"},
}
@@ -307,9 +306,6 @@ func TestConfig_PostSkin_RequiredFields(t *testing.T) {
"The uuid field is required",
"The uuid field must contain valid UUID"
],
"hash": [
"The hash field must be a valid md5 hash"
],
"url": [
"One of url or skin should be provided, but not both"
],

View File

@@ -1,27 +0,0 @@
package http
import (
"net/http"
"github.com/gorilla/mux"
)
const defaultHash = "default"
func (cfg *Config) Face(response http.ResponseWriter, request *http.Request) {
cfg.Logger.IncCounter("faces.request", 1)
username := parseUsername(mux.Vars(request)["username"])
rec, err := cfg.SkinsRepo.FindByUsername(username)
var hash string
if err != nil || rec.SkinId == 0 {
hash = defaultHash
} else {
hash = rec.Hash
}
http.Redirect(response, request, buildFaceUrl(hash), 301)
}
func buildFaceUrl(hash string) string {
return "http://ely.by/minecraft/skin_buffer/faces/" + hash + ".png"
}

View File

@@ -1,53 +0,0 @@
package http
import (
"net/http/httptest"
"testing"
"github.com/golang/mock/gomock"
testify "github.com/stretchr/testify/assert"
"github.com/elyby/chrly/db"
)
func TestConfig_Face(t *testing.T) {
assert := testify.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
config, mocks := setupMocks(ctrl)
mocks.Skins.EXPECT().FindByUsername("mock_user").Return(createSkinModel("mock_user", false), nil)
mocks.Log.EXPECT().IncCounter("faces.request", int64(1))
req := httptest.NewRequest("GET", "http://skinsystem.ely.by/skins/mock_user/face.png", nil)
w := httptest.NewRecorder()
config.CreateHandler().ServeHTTP(w, req)
resp := w.Result()
assert.Equal(301, resp.StatusCode)
assert.Equal("http://ely.by/minecraft/skin_buffer/faces/55d2a8848764f5ff04012cdb093458bd.png", resp.Header.Get("Location"))
}
func TestConfig_Face2(t *testing.T) {
assert := testify.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
config, mocks := setupMocks(ctrl)
mocks.Skins.EXPECT().FindByUsername("mock_user").Return(nil, &db.SkinNotFoundError{"mock_user"})
mocks.Log.EXPECT().IncCounter("faces.request", int64(1))
req := httptest.NewRequest("GET", "http://skinsystem.ely.by/skins/mock_user/face.png", nil)
w := httptest.NewRecorder()
config.CreateHandler().ServeHTTP(w, req)
resp := w.Result()
assert.Equal(301, resp.StatusCode)
assert.Equal("http://ely.by/minecraft/skin_buffer/faces/default.png", resp.Header.Get("Location"))
}

View File

@@ -55,8 +55,6 @@ func (cfg *Config) CreateHandler() http.Handler {
router.HandleFunc("/cloaks/{username}", cfg.Cape).Methods("GET").Name("cloaks")
router.HandleFunc("/textures/{username}", cfg.Textures).Methods("GET")
router.HandleFunc("/textures/signed/{username}", cfg.SignedTextures).Methods("GET")
router.HandleFunc("/skins/{username}/face", cfg.Face).Methods("GET")
router.HandleFunc("/skins/{username}/face.png", cfg.Face).Methods("GET")
// Legacy
router.HandleFunc("/skins", cfg.SkinGET).Methods("GET")
router.HandleFunc("/cloaks", cfg.CapeGET).Methods("GET")

View File

@@ -9,7 +9,6 @@ func (cfg *Config) NotFound(response http.ResponseWriter, request *http.Request)
data, _ := json.Marshal(map[string]string{
"status": "404",
"message": "Not Found",
"link": "http://docs.ely.by/skin-system.html",
})
response.Header().Set("Content-Type", "application/json")

View File

@@ -22,7 +22,6 @@ func TestConfig_NotFound(t *testing.T) {
response, _ := ioutil.ReadAll(resp.Body)
assert.JSONEq(`{
"status": "404",
"message": "Not Found",
"link": "http://docs.ely.by/skin-system.html"
"message": "Not Found"
}`, string(response))
}

View File

@@ -40,8 +40,8 @@ func (cfg *Config) SignedTextures(response http.ResponseWriter, request *http.Re
Value: rec.MojangTextures,
},
{
Name: "ely",
Value: "but why are you asking?",
Name: "chrly",
Value: "how do you tame a horse in Minecraft?",
},
},
}

View File

@@ -41,8 +41,8 @@ func TestConfig_SignedTextures(t *testing.T) {
"value": "mocked textures base64"
},
{
"name": "ely",
"value": "but why are you asking?"
"name": "chrly",
"value": "how do you tame a horse in Minecraft?"
}
]
}`, string(response))