diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 38f2bb09ad..c2b32df06c 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -80,7 +80,7 @@ }, { "ImportPath": "github.com/nfnt/resize", - "Rev": "f2d1b73023c55bdfb4fa2ed385d2bec95bce3692" + "Rev": "dc93e1b98c579d90ee2fa15c1fd6dac34f6e7899" }, { "ImportPath": "github.com/stretchr/objx", diff --git a/Godeps/_workspace/src/github.com/nfnt/resize/converter.go b/Godeps/_workspace/src/github.com/nfnt/resize/converter.go index 84bd284ba3..b3dd06b8d5 100644 --- a/Godeps/_workspace/src/github.com/nfnt/resize/converter.go +++ b/Godeps/_workspace/src/github.com/nfnt/resize/converter.go @@ -131,11 +131,11 @@ func resizeRGBA(in *image.RGBA, out *image.NRGBA, scale float64, coeffs []int16, // reverse alpha-premultiplication. if a != 0 { - r *= 0xffff + r *= 0xff r /= a - g *= 0xffff + g *= 0xff g /= a - b *= 0xffff + b *= 0xff b /= a } diff --git a/Godeps/_workspace/src/github.com/nfnt/resize/resize.go b/Godeps/_workspace/src/github.com/nfnt/resize/resize.go index 4d4ff6e3e4..c1672432ee 100644 --- a/Godeps/_workspace/src/github.com/nfnt/resize/resize.go +++ b/Godeps/_workspace/src/github.com/nfnt/resize/resize.go @@ -167,7 +167,7 @@ func Resize(width, height uint, img image.Image, interp InterpolationFunction) i // accessing the YCbCr arrays in a tight loop is slow. // converting the image to ycc increases performance by 2x. temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio) - result := newYCC(image.Rect(0, 0, int(width), int(height)), input.SubsampleRatio) + result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444) coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel) in := imageYCbCrToYCC(input) @@ -409,7 +409,7 @@ func resizeNearest(width, height uint, scaleX, scaleY float64, img image.Image, // accessing the YCbCr arrays in a tight loop is slow. // converting the image to ycc increases performance by 2x. temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio) - result := newYCC(image.Rect(0, 0, int(width), int(height)), input.SubsampleRatio) + result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444) coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX) in := imageYCbCrToYCC(input) diff --git a/Godeps/_workspace/src/github.com/nfnt/resize/resize_test.go b/Godeps/_workspace/src/github.com/nfnt/resize/resize_test.go index ee31ac494f..6f69113163 100644 --- a/Godeps/_workspace/src/github.com/nfnt/resize/resize_test.go +++ b/Godeps/_workspace/src/github.com/nfnt/resize/resize_test.go @@ -46,7 +46,7 @@ func Test_CorrectResize(t *testing.T) { } } -func Test_SameColor(t *testing.T) { +func Test_SameColorWithRGBA(t *testing.T) { img := image.NewRGBA(image.Rect(0, 0, 20, 20)) for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { @@ -56,9 +56,99 @@ func Test_SameColor(t *testing.T) { out := Resize(10, 10, img, Lanczos3) for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { - color := img.At(x, y).(color.RGBA) + color := out.At(x, y).(color.NRGBA) if color.R != 0x80 || color.G != 0x80 || color.B != 0x80 || color.A != 0xFF { - t.Fail() + t.Errorf("%+v", color) + } + } + } +} + +func Test_SameColorWithNRGBA(t *testing.T) { + img := image.NewNRGBA(image.Rect(0, 0, 20, 20)) + for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { + for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { + img.SetNRGBA(x, y, color.NRGBA{0x80, 0x80, 0x80, 0xFF}) + } + } + out := Resize(10, 10, img, Lanczos3) + for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { + for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { + color := out.At(x, y).(color.NRGBA) + if color.R != 0x80 || color.G != 0x80 || color.B != 0x80 || color.A != 0xFF { + t.Errorf("%+v", color) + } + } + } +} + +func Test_SameColorWithRGBA64(t *testing.T) { + img := image.NewRGBA64(image.Rect(0, 0, 20, 20)) + for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { + for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { + img.SetRGBA64(x, y, color.RGBA64{0x8000, 0x8000, 0x8000, 0xFFFF}) + } + } + out := Resize(10, 10, img, Lanczos3) + for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { + for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { + color := out.At(x, y).(color.NRGBA64) + if color.R != 0x8000 || color.G != 0x8000 || color.B != 0x8000 || color.A != 0xFFFF { + t.Errorf("%+v", color) + } + } + } +} + +func Test_SameColorWithNRGBA64(t *testing.T) { + img := image.NewNRGBA64(image.Rect(0, 0, 20, 20)) + for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { + for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { + img.SetNRGBA64(x, y, color.NRGBA64{0x8000, 0x8000, 0x8000, 0xFFFF}) + } + } + out := Resize(10, 10, img, Lanczos3) + for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { + for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { + color := out.At(x, y).(color.NRGBA64) + if color.R != 0x8000 || color.G != 0x8000 || color.B != 0x8000 || color.A != 0xFFFF { + t.Errorf("%+v", color) + } + } + } +} + +func Test_SameColorWithGray(t *testing.T) { + img := image.NewGray(image.Rect(0, 0, 20, 20)) + for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { + for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { + img.SetGray(x, y, color.Gray{0x80}) + } + } + out := Resize(10, 10, img, Lanczos3) + for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { + for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { + color := out.At(x, y).(color.Gray) + if color.Y != 0x80 { + t.Errorf("%+v", color) + } + } + } +} + +func Test_SameColorWithGray16(t *testing.T) { + img := image.NewGray16(image.Rect(0, 0, 20, 20)) + for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { + for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { + img.SetGray16(x, y, color.Gray16{0x8000}) + } + } + out := Resize(10, 10, img, Lanczos3) + for y := out.Bounds().Min.Y; y < out.Bounds().Max.Y; y++ { + for x := out.Bounds().Min.X; x < out.Bounds().Max.X; x++ { + color := out.At(x, y).(color.Gray16) + if color.Y != 0x8000 { + t.Errorf("%+v", color) } } } diff --git a/Makefile b/Makefile index 8793ba98ad..222d4ffe4f 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ GOPATH ?= $(GOPATH:) GOFLAGS ?= $(GOFLAGS:) BUILD_NUMBER ?= $(BUILD_NUMBER:) +GO=$(GOPATH)/bin/godep go + ifeq ($(BUILD_NUMBER),) BUILD_NUMBER := dev endif @@ -21,29 +23,27 @@ travis: @echo building for travis rm -Rf $(DIST_ROOT) - @go clean $(GOFLAGS) -i ./... - + @$(GO) clean $(GOFLAGS) -i ./... + @cd web/react/ && npm install - @go build $(GOFLAGS) ./... + @$(GO) build $(GOFLAGS) ./... @mkdir -p logs - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1 build: - @go build $(GOFLAGS) ./... + @$(GO) build $(GOFLAGS) ./... install: @go get $(GOFLAGS) github.com/tools/godep @if [ $(shell docker ps -a | grep -ci mattermost-mysql) -eq 0 ]; then \ - echo restoring go libs using godep; \ - $(GOPATH)/bin/godep restore; \ echo starting mattermost-mysql; \ docker run --name mattermost-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mostest \ -e MYSQL_USER=mmuser -e MYSQL_PASSWORD=mostest -e MYSQL_DATABASE=mattermost_test -d mysql > /dev/null; \ @@ -64,37 +64,37 @@ install: test: install @mkdir -p logs - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1 - @go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1 + @$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1 benchmark: install @mkdir -p logs - @go test $(GOFLAGS) -test.v -run=NO_TESTS -bench=$(BENCH) ./api || exit 1 + @$(GO) test $(GOFLAGS) -test.v -run=NO_TESTS -bench=$(BENCH) ./api || exit 1 cover: install rm -Rf $(DIST_RESULTS) mkdir -p $(DIST_RESULTS) - @go test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/api.cover.out github.com/mattermost/platform/api - @go test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/model.cover.out github.com/mattermost/platform/model - @go test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/store.cover.out github.com/mattermost/platform/store - @go test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/utils.cover.out github.com/mattermost/platform/utils - @go test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/web.cover.out github.com/mattermost/platform/web + @$(GO) test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/api.cover.out github.com/mattermost/platform/api + @$(GO) test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/model.cover.out github.com/mattermost/platform/model + @$(GO) test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/store.cover.out github.com/mattermost/platform/store + @$(GO) test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/utils.cover.out github.com/mattermost/platform/utils + @$(GO) test $(GOFLAGS) -coverprofile=$(DIST_RESULTS)/web.cover.out github.com/mattermost/platform/web cd $(DIST_RESULTS) && \ echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \ awk '{if($$1 != last) {print $$0;last=$$1}}' >> coverage.out - cd $(DIST_RESULTS) && go tool cover -html=coverage.out -o=coverage.html + cd $(DIST_RESULTS) && $(GO) tool cover -html=coverage.out -o=coverage.html rm -f $(DIST_RESULTS)/*.cover.out clean: rm -Rf $(DIST_ROOT) - @go clean $(GOFLAGS) -i ./... + @$(GO) clean $(GOFLAGS) -i ./... @if [ $(shell docker ps -a | grep -ci mattermost-mysql) -eq 1 ]; then \ echo stopping mattermost-mysql; \ @@ -124,7 +124,7 @@ run: install @cd web/react && npm start & @echo starting go web server - @go run $(GOFLAGS) mattermost.go -config=config.json & + @$(GO) run $(GOFLAGS) mattermost.go -config=config.json & @echo starting compass watch @cd web/sass-files && compass watch & @@ -161,8 +161,8 @@ cleandb: dist: install - @go build $(GOFLAGS) -i -a ./... - @go install $(GOFLAGS) -a ./... + @$(GO) build $(GOFLAGS) -i -a ./... + @$(GO) install $(GOFLAGS) -a ./... mkdir -p $(DIST_PATH)/bin cp $(GOPATH)/bin/platform $(DIST_PATH)/bin diff --git a/README.md b/README.md index 65a3e7c663..f0857e99de 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -**Mattermost Preview** +**Mattermost Alpha** **Team Communication Service** -**Version 0.5.0** +**Development Build** About Mattermost @@ -22,7 +22,7 @@ Learn More Installing the Mattermost ========================= -You're installing "Mattermost Preview", a pre-released 0.5.0 version intended for an early look at what we're building. While SpinPunch runs this version internally, it's not recommended for production deployments since we can't guarantee API stability or backwards compatibility until our 1.0.0 version release. +You're installing "Mattermost Alpha", a pre-released version intended for an early look at what we're building. While SpinPunch runs this version internally, it's not recommended for production deployments since we can't guarantee API stability or backwards compatibility until our production release. That said, any issues at all, please let us know on the Mattermost forum at: http://forum.mattermost.org diff --git a/api/channel.go b/api/channel.go index 4d8dbad099..123fd8a355 100644 --- a/api/channel.go +++ b/api/channel.go @@ -710,6 +710,11 @@ func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { return } + message := model.NewMessage(c.Session.TeamId, "", userId, model.ACTION_USER_REMOVED) + message.Add("channel_id",id) + message.Add("remover", c.Session.UserId) + PublishAndForget(message) + c.LogAudit("name=" + channel.Name + " user_id=" + userId) result := make(map[string]string) diff --git a/api/context.go b/api/context.go index ac9dffcbc9..16da0a6eb4 100644 --- a/api/context.go +++ b/api/context.go @@ -101,6 +101,12 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId) w.Header().Set(model.HEADER_VERSION_ID, utils.Cfg.ServiceSettings.Version) + // Instruct the browser not to display us in an iframe for anti-clickjacking + if !h.isApi { + w.Header().Set("X-Frame-Options", "DENY") + w.Header().Set("Content-Security-Policy", "frame-ancestors none") + } + sessionId := "" // attempt to parse the session token from the header diff --git a/api/file.go b/api/file.go index 82cee9d1e7..3ef50fbbd5 100644 --- a/api/file.go +++ b/api/file.go @@ -33,7 +33,7 @@ func InitFile(r *mux.Router) { sr := r.PathPrefix("/files").Subrouter() sr.Handle("/upload", ApiUserRequired(uploadFile)).Methods("POST") - sr.Handle("/get/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+\\.[A-Za-z0-9]{3,}}", ApiAppHandler(getFile)).Methods("GET") + sr.Handle("/get/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandler(getFile)).Methods("GET") sr.Handle("/get_public_link", ApiUserRequired(getPublicLink)).Methods("POST") } @@ -142,7 +142,7 @@ func fireAndForgetHandleImages(filenames []string, fileData [][]byte, teamId, ch go func() { var thumbnail image.Image if imgConfig.Width > int(utils.Cfg.ImageSettings.ThumbnailWidth) { - thumbnail = resize.Resize(utils.Cfg.ImageSettings.ThumbnailWidth, utils.Cfg.ImageSettings.ThumbnailHeight, img, resize.NearestNeighbor) + thumbnail = resize.Resize(utils.Cfg.ImageSettings.ThumbnailWidth, utils.Cfg.ImageSettings.ThumbnailHeight, img, resize.Lanczos3) } else { thumbnail = img } @@ -164,7 +164,7 @@ func fireAndForgetHandleImages(filenames []string, fileData [][]byte, teamId, ch go func() { var preview image.Image if imgConfig.Width > int(utils.Cfg.ImageSettings.PreviewWidth) { - preview = resize.Resize(utils.Cfg.ImageSettings.PreviewWidth, utils.Cfg.ImageSettings.PreviewHeight, img, resize.NearestNeighbor) + preview = resize.Resize(utils.Cfg.ImageSettings.PreviewWidth, utils.Cfg.ImageSettings.PreviewHeight, img, resize.Lanczos3) } else { preview = img } diff --git a/api/templates/email_change_body.html b/api/templates/email_change_body.html index f8f3845e78..439fffd5b0 100644 --- a/api/templates/email_change_body.html +++ b/api/templates/email_change_body.html @@ -8,7 +8,7 @@
| + |
|
||||||||||||||||||||||||||||||||||||||||
| + |
|
|