Skip to content

Commit

Permalink
Merge branch 'master' into get-users-autocomplete-api4
Browse files Browse the repository at this point in the history
  • Loading branch information
andreistanciu24 committed Mar 1, 2017
2 parents 6c7a458 + c1d5e9a commit 9a6bd06
Show file tree
Hide file tree
Showing 43 changed files with 1,233 additions and 223 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -202,7 +202,7 @@ test-server: start-docker prepare-enterprise
rm -f cover.out
echo "mode: count" > cover.out

$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=650s -covermode=count -coverprofile=capi.out ./api || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=1050s -covermode=count -coverprofile=capi.out ./api || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=650s -covermode=count -coverprofile=capi4.out ./api4 || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=60s -covermode=count -coverprofile=capp.out ./app || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=60s -covermode=count -coverprofile=cmodel.out ./model || exit 1
Expand Down
95 changes: 4 additions & 91 deletions api/license.go
Expand Up @@ -7,19 +7,13 @@ import (
"bytes"
"io"
"net/http"
"strings"

l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)

const (
EXPIRED_LICENSE_ERROR = "api.license.add_license.expired.app_error"
INVALID_LICENSE_ERROR = "api.license.add_license.invalid.app_error"
)

func InitLicense() {
l4g.Debug(utils.T("api.license.init.debug"))

Expand All @@ -28,26 +22,6 @@ func InitLicense() {
BaseRoutes.License.Handle("/client_config", ApiAppHandler(getClientLicenceConfig)).Methods("GET")
}

func LoadLicense() {
licenseId := ""
if result := <-app.Srv.Store.System().Get(); result.Err == nil {
props := result.Data.(model.StringMap)
licenseId = props[model.SYSTEM_ACTIVE_LICENSE_ID]
}

if len(licenseId) != 26 {
l4g.Info(utils.T("mattermost.load_license.find.warn"))
return
}

if result := <-app.Srv.Store.License().Get(licenseId); result.Err == nil {
record := result.Data.(*model.LicenseRecord)
utils.LoadLicense([]byte(record.Bytes))
} else {
l4g.Info(utils.T("mattermost.load_license.find.warn"))
}
}

func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("attempt")
err := r.ParseMultipartForm(*utils.Cfg.FileSettings.MaxFileSize)
Expand Down Expand Up @@ -83,10 +57,10 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
buf := bytes.NewBuffer(nil)
io.Copy(buf, file)

if license, err := SaveLicense(buf.Bytes()); err != nil {
if err.Id == EXPIRED_LICENSE_ERROR {
if license, err := app.SaveLicense(buf.Bytes()); err != nil {
if err.Id == model.EXPIRED_LICENSE_ERROR {
c.LogAudit("failed - expired or non-started license")
} else if err.Id == INVALID_LICENSE_ERROR {
} else if err.Id == model.INVALID_LICENSE_ERROR {
c.LogAudit("failed - invalid license")
} else {
c.LogAudit("failed - unable to save license")
Expand All @@ -99,56 +73,10 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
}
}

func SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) {
var license *model.License

if success, licenseStr := utils.ValidateLicense(licenseBytes); success {
license = model.LicenseFromJson(strings.NewReader(licenseStr))

if result := <-app.Srv.Store.User().AnalyticsUniqueUserCount(""); result.Err != nil {
return nil, model.NewLocAppError("addLicense", "api.license.add_license.invalid_count.app_error", nil, result.Err.Error())
} else {
uniqueUserCount := result.Data.(int64)

if uniqueUserCount > int64(*license.Features.Users) {
return nil, model.NewLocAppError("addLicense", "api.license.add_license.unique_users.app_error", map[string]interface{}{"Users": *license.Features.Users, "Count": uniqueUserCount}, "")
}
}

if ok := utils.SetLicense(license); !ok {
return nil, model.NewLocAppError("addLicense", EXPIRED_LICENSE_ERROR, nil, "")
}

record := &model.LicenseRecord{}
record.Id = license.Id
record.Bytes = string(licenseBytes)
rchan := app.Srv.Store.License().Save(record)

sysVar := &model.System{}
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
sysVar.Value = license.Id
schan := app.Srv.Store.System().SaveOrUpdate(sysVar)

if result := <-rchan; result.Err != nil {
RemoveLicense()
return nil, model.NewLocAppError("addLicense", "api.license.add_license.save.app_error", nil, "err="+result.Err.Error())
}

if result := <-schan; result.Err != nil {
RemoveLicense()
return nil, model.NewLocAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "")
}
} else {
return nil, model.NewLocAppError("addLicense", INVALID_LICENSE_ERROR, nil, "")
}

return license, nil
}

func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("")

if err := RemoveLicense(); err != nil {
if err := app.RemoveLicense(); err != nil {
c.Err = err
return
}
Expand All @@ -158,21 +86,6 @@ func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(model.MapToJson(rdata)))
}

func RemoveLicense() *model.AppError {
utils.RemoveLicense()

sysVar := &model.System{}
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
sysVar.Value = ""

if result := <-app.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil {
utils.RemoveLicense()
return result.Err
}

return nil
}

func getClientLicenceConfig(c *Context, w http.ResponseWriter, r *http.Request) {
useSanitizedLicense := !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM)

Expand Down
15 changes: 9 additions & 6 deletions api/user_test.go
Expand Up @@ -1823,16 +1823,19 @@ func TestUpdateMfa(t *testing.T) {
th := Setup().InitBasic()
Client := th.BasicClient

if utils.License.Features.MFA == nil {
utils.License.Features.MFA = new(bool)
}

isLicensed := utils.IsLicensed
license := utils.License
enableMfa := *utils.Cfg.ServiceSettings.EnableMultifactorAuthentication
defer func() {
utils.IsLicensed = false
*utils.License.Features.MFA = false
utils.IsLicensed = isLicensed
utils.License = license
*utils.Cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa
}()
utils.IsLicensed = false
utils.License = &model.License{Features: &model.Features{}}
if utils.License.Features.MFA == nil {
utils.License.Features.MFA = new(bool)
}

team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
Expand Down
33 changes: 33 additions & 0 deletions api4/file.go
Expand Up @@ -23,6 +23,7 @@ func InitFile() {

BaseRoutes.Files.Handle("", ApiSessionRequired(uploadFile)).Methods("POST")
BaseRoutes.File.Handle("", ApiSessionRequired(getFile)).Methods("GET")
BaseRoutes.File.Handle("/thumbnail", ApiSessionRequired(getFileThumbnail)).Methods("GET")

}

Expand Down Expand Up @@ -92,6 +93,38 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
}
}

func getFileThumbnail(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireFileId()
if c.Err != nil {
return
}

info, err := app.GetFileInfo(c.Params.FileId)
if err != nil {
c.Err = err
return
}

if info.CreatorId != c.Session.UserId && !app.SessionHasPermissionToChannelByPost(c.Session, info.PostId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}

if info.ThumbnailPath == "" {
c.Err = model.NewLocAppError("getFileThumbnail", "api.file.get_file_thumbnail.no_thumbnail.app_error", nil, "file_id="+info.Id)
c.Err.StatusCode = http.StatusBadRequest
return
}

if data, err := app.ReadFile(info.ThumbnailPath); err != nil {
c.Err = err
c.Err.StatusCode = http.StatusNotFound
} else if err := writeFileResponse(info.Name, info.MimeType, data, w, r); err != nil {
c.Err = err
return
}
}

func writeFileResponse(filename string, contentType string, bytes []byte, w http.ResponseWriter, r *http.Request) *model.AppError {
w.Header().Set("Cache-Control", "max-age=2592000, public")
w.Header().Set("Content-Length", strconv.Itoa(len(bytes)))
Expand Down
52 changes: 52 additions & 0 deletions api4/file_test.go
Expand Up @@ -149,3 +149,55 @@ func TestGetFile(t *testing.T) {
_, resp = th.SystemAdminClient.GetFile(fileId)
CheckNoError(t, resp)
}

func TestGetFileThumbnail(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
channel := th.BasicChannel

if utils.Cfg.FileSettings.DriverName == "" {
t.Skip("skipping because no file driver is enabled")
}

fileId := ""
var sent []byte
var err error
if sent, err = readTestFile("test.png"); err != nil {
t.Fatal(err)
} else {
fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png")
CheckNoError(t, resp)

fileId = fileResp.FileInfos[0].Id
}

// Wait a bit for files to ready
time.Sleep(2 * time.Second)

data, resp := Client.GetFileThumbnail(fileId)
CheckNoError(t, resp)

if data == nil || len(data) == 0 {
t.Fatal("should not be empty")
}

_, resp = Client.GetFileThumbnail("junk")
CheckBadRequestStatus(t, resp)

_, resp = Client.GetFileThumbnail(model.NewId())
CheckNotFoundStatus(t, resp)

Client.Logout()
_, resp = Client.GetFileThumbnail(fileId)
CheckUnauthorizedStatus(t, resp)

otherUser := th.CreateUser()
Client.Login(otherUser.Email, otherUser.Password)
_, resp = Client.GetFileThumbnail(fileId)
CheckForbiddenStatus(t, resp)

Client.Logout()
_, resp = th.SystemAdminClient.GetFileThumbnail(fileId)
CheckNoError(t, resp)
}
24 changes: 24 additions & 0 deletions api4/team.go
Expand Up @@ -18,6 +18,7 @@ func InitTeam() {
BaseRoutes.Teams.Handle("", ApiSessionRequired(createTeam)).Methods("POST")
BaseRoutes.Teams.Handle("", ApiSessionRequired(getAllTeams)).Methods("GET")
BaseRoutes.TeamsForUser.Handle("", ApiSessionRequired(getTeamsForUser)).Methods("GET")
BaseRoutes.TeamsForUser.Handle("/unread", ApiSessionRequired(getTeamsUnreadForUser)).Methods("GET")

BaseRoutes.Team.Handle("", ApiSessionRequired(getTeam)).Methods("GET")
BaseRoutes.Team.Handle("/stats", ApiSessionRequired(getTeamStats)).Methods("GET")
Expand Down Expand Up @@ -104,6 +105,29 @@ func getTeamsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
}
}

func getTeamsUnreadForUser(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}

if c.Session.UserId != c.Params.UserId && !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
return
}

// optional team id to be excluded from the result
teamId := r.URL.Query().Get("exclude_team")

unreadTeamsList, err := app.GetTeamsUnreadForUser(teamId, c.Params.UserId)
if err != nil {
c.Err = err
return
}

w.Write([]byte(model.TeamsUnreadToJson(unreadTeamsList)))
}

func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireTeamId().RequireUserId()
if c.Err != nil {
Expand Down
31 changes: 31 additions & 0 deletions api4/team_test.go
Expand Up @@ -463,3 +463,34 @@ func TestUpdateTeamMemberRoles(t *testing.T) {
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TEAM_MEMBER)
CheckNoError(t, resp)
}

func TestGetMyTeamsUnread(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client

user := th.BasicUser
Client.Login(user.Email, user.Password)

teams, resp := Client.GetTeamsUnreadForUser(user.Id, "")
CheckNoError(t, resp)
if len(teams) == 0 {
t.Fatal("should have results")
}

teams, resp = Client.GetTeamsUnreadForUser(user.Id, th.BasicTeam.Id)
CheckNoError(t, resp)
if len(teams) != 0 {
t.Fatal("should not have results")
}

_, resp = Client.GetTeamsUnreadForUser("fail", "")
CheckBadRequestStatus(t, resp)

_, resp = Client.GetTeamsUnreadForUser(model.NewId(), "")
CheckForbiddenStatus(t, resp)

Client.Logout()
_, resp = Client.GetTeamsUnreadForUser(user.Id, "")
CheckUnauthorizedStatus(t, resp)
}
1 change: 1 addition & 0 deletions app/admin.go
Expand Up @@ -90,6 +90,7 @@ func InvalidateAllCachesSkipSend() {
store.ClearUserCaches()
store.ClearPostCaches()
store.ClearWebhookCaches()
LoadLicense()
}

func GetConfig() *model.Config {
Expand Down

0 comments on commit 9a6bd06

Please sign in to comment.