diff --git a/api/admin.go b/api/admin.go
new file mode 100644
index 0000000000..d4af1d247f
--- /dev/null
+++ b/api/admin.go
@@ -0,0 +1,51 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package api
+
+import (
+ "bufio"
+ "net/http"
+ "os"
+
+ l4g "code.google.com/p/log4go"
+ "github.com/gorilla/mux"
+
+ "github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
+)
+
+func InitAdmin(r *mux.Router) {
+ l4g.Debug("Initializing admin api routes")
+
+ sr := r.PathPrefix("/admin").Subrouter()
+ sr.Handle("/logs", ApiUserRequired(getLogs)).Methods("GET")
+}
+
+func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
+
+ if !c.HasSystemAdminPermissions("getLogs") {
+ return
+ }
+
+ var lines []string
+
+ if utils.Cfg.LogSettings.FileEnable {
+
+ file, err := os.Open(utils.Cfg.LogSettings.FileLocation)
+ if err != nil {
+ c.Err = model.NewAppError("getLogs", "Error reading log file", err.Error())
+ }
+
+ defer file.Close()
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ lines = append(lines, scanner.Text())
+ }
+ } else {
+ lines = append(lines, "")
+ }
+
+ w.Write([]byte(model.ArrayToJson(lines)))
+}
diff --git a/api/admin_test.go b/api/admin_test.go
new file mode 100644
index 0000000000..460ac1208b
--- /dev/null
+++ b/api/admin_test.go
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package api
+
+import (
+ "testing"
+
+ "github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/store"
+)
+
+func TestGetLogs(t *testing.T) {
+ Setup()
+
+ team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
+ team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
+
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user.Id))
+
+ c := &Context{}
+ c.RequestId = model.NewId()
+ c.IpAddress = "cmd_line"
+ UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
+
+ Client.LoginByEmail(team.Name, user.Email, "pwd")
+
+ if logs, err := Client.GetLogs(); err != nil {
+ t.Fatal(err)
+ } else if len(logs.Data.([]string)) <= 0 {
+ t.Fatal()
+ }
+}
diff --git a/api/api.go b/api/api.go
index 9770930f76..35ac0bdc02 100644
--- a/api/api.go
+++ b/api/api.go
@@ -41,6 +41,7 @@ func InitApi() {
InitFile(r)
InitCommand(r)
InitConfig(r)
+ InitAdmin(r)
templatesDir := utils.FindDir("api/templates")
l4g.Debug("Parsing server templates at %v", templatesDir)
diff --git a/api/context.go b/api/context.go
index d97295e5ed..fc7d8f23d1 100644
--- a/api/context.go
+++ b/api/context.go
@@ -295,6 +295,16 @@ func (c *Context) IsSystemAdmin() bool {
return false
}
+func (c *Context) HasSystemAdminPermissions(where string) bool {
+ if c.IsSystemAdmin() {
+ return true
+ }
+
+ c.Err = model.NewAppError(where, "You do not have the appropriate permissions", "userId="+c.Session.UserId)
+ c.Err.StatusCode = http.StatusForbidden
+ return false
+}
+
func (c *Context) IsTeamAdmin(userId string) bool {
if uresult := <-Srv.Store.User().Get(userId); uresult.Err != nil {
c.Err = uresult.Err
diff --git a/mattermost.go b/mattermost.go
index 499abcd92d..c95c8ee438 100644
--- a/mattermost.go
+++ b/mattermost.go
@@ -329,9 +329,9 @@ Usage:
platform -create_user -team_name="name" -email="user@example.com" -password="mypassword"
-assign_role Assigns role to a user. It requres the -role,
- -email and -team_name flag. If you're assigning the
- role="system_admin" role it must be for a user on the
- team_name="admin"
+ -email and -team_name flag. You may need to logout
+ of your current sessions for the new role to be
+ applied.
Example:
platform -assign_role -team_name="name" -email="user@example.com" -role="admin"
diff --git a/model/client.go b/model/client.go
index c355b90f51..5aac09289c 100644
--- a/model/client.go
+++ b/model/client.go
@@ -338,6 +338,15 @@ func (c *Client) GetAudits(id string, etag string) (*Result, *AppError) {
}
}
+func (c *Client) GetLogs() (*Result, *AppError) {
+ if r, err := c.DoGet("/admin/logs", "", ""); err != nil {
+ return nil, err
+ } else {
+ return &Result{r.Header.Get(HEADER_REQUEST_ID),
+ r.Header.Get(HEADER_ETAG_SERVER), ArrayFromJson(r.Body)}, nil
+ }
+}
+
func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) {
if r, err := c.DoPost("/channels/create", channel.ToJson()); err != nil {
return nil, err
diff --git a/utils/config.go b/utils/config.go
index c67e17e790..a1d282c29c 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -11,9 +11,10 @@ import (
)
const (
- MODE_DEV = "dev"
- MODE_BETA = "beta"
- MODE_PROD = "prod"
+ MODE_DEV = "dev"
+ MODE_BETA = "beta"
+ MODE_PROD = "prod"
+ LOG_ROTATE_SIZE = 10000
)
type ServiceSettings struct {
@@ -180,10 +181,10 @@ func ConfigureCmdLineLog() {
ls.ConsoleEnable = true
ls.ConsoleLevel = "ERROR"
ls.FileEnable = false
- configureLog(ls)
+ configureLog(&ls)
}
-func configureLog(s LogSettings) {
+func configureLog(s *LogSettings) {
l4g.Close()
@@ -217,7 +218,7 @@ func configureLog(s LogSettings) {
flw := l4g.NewFileLogWriter(s.FileLocation, false)
flw.SetFormat(s.FileFormat)
flw.SetRotate(true)
- flw.SetRotateLines(100000)
+ flw.SetRotateLines(LOG_ROTATE_SIZE)
l4g.AddFilter("file", level, flw)
}
}
@@ -241,7 +242,7 @@ func LoadConfig(fileName string) {
panic("Error decoding config file=" + fileName + ", err=" + err.Error())
}
- configureLog(config.LogSettings)
+ configureLog(&config.LogSettings)
Cfg = &config
SanitizeOptions = getSanitizeOptions()
diff --git a/web/react/components/admin_console/admin_controller.jsx b/web/react/components/admin_console/admin_controller.jsx
index bb43af8027..68984c9e0f 100644
--- a/web/react/components/admin_console/admin_controller.jsx
+++ b/web/react/components/admin_console/admin_controller.jsx
@@ -4,6 +4,7 @@
var AdminSidebar = require('./admin_sidebar.jsx');
var EmailTab = require('./email_settings.jsx');
var JobsTab = require('./jobs_settings.jsx');
+var LogsTab = require('./logs.jsx');
var Navbar = require('../../components/navbar.jsx');
export default class AdminController extends React.Component {
@@ -28,6 +29,8 @@ export default class AdminController extends React.Component {
tab =