1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-12-24 13:43:12 +02:00

First pass linter cleanup (#603)

* first pass linter cleanup

* address review comments
This commit is contained in:
Doug Lauder 2021-06-21 05:21:42 -04:00 committed by GitHub
parent c4154cd2dd
commit 66975bdfe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 329 additions and 322 deletions

View File

@ -12,10 +12,14 @@ linters-settings:
enable-all: true
disable:
- fieldalignment
lll:
line-length: 150
gomnd:
ignored-numbers: 10
linters:
disable-all: true
enable:
- gofmt
- goimports
@ -43,10 +47,10 @@ linters:
- goconst
- gocritic
- godot
- goerr113
# - goerr113
- goheader
- golint
- gomnd
# - gomnd
- gomodguard
- goprintffuncname
- gosimple

View File

@ -1,7 +1,6 @@
package api
import (
"context"
"encoding/json"
"errors"
"fmt"
@ -22,13 +21,14 @@ import (
)
const (
HEADER_REQUESTED_WITH = "X-Requested-With"
HEADER_REQUESTED_WITH_XML = "XMLHttpRequest"
HeaderRequestedWith = "X-Requested-With"
HeaderRequestedWithXML = "XMLHttpRequest"
SingleUser = "single-user"
)
const (
ERROR_NO_WORKSPACE_CODE = 1000
ERROR_NO_WORKSPACE_MESSAGE = "No workspace"
ErrorNoWorkspaceCode = 1000
ErrorNoWorkspaceMessage = "No workspace"
)
// ----------------------------------------------------------------------------------------------------
@ -105,13 +105,8 @@ func (a *API) requireCSRFToken(next http.Handler) http.Handler {
}
func (a *API) checkCSRFToken(r *http.Request) bool {
token := r.Header.Get(HEADER_REQUESTED_WITH)
if token == HEADER_REQUESTED_WITH_XML {
return true
}
return false
token := r.Header.Get(HeaderRequestedWith)
return token == HeaderRequestedWithXML
}
func (a *API) hasValidReadTokenForBlock(r *http.Request, container store.Container, blockID string) bool {
@ -158,7 +153,7 @@ func (a *API) getContainerAllowingReadTokenForBlock(r *http.Request, blockID str
return &container, nil
}
return nil, errors.New("Access denied to workspace")
return nil, errors.New("access denied to workspace")
}
// Native auth: always use root workspace
@ -176,7 +171,7 @@ func (a *API) getContainerAllowingReadTokenForBlock(r *http.Request, blockID str
return &container, nil
}
return nil, errors.New("Access denied to workspace")
return nil, errors.New("access denied to workspace")
}
func (a *API) getContainer(r *http.Request) (*store.Container, error) {
@ -263,7 +258,7 @@ func stampModifiedByUser(r *http.Request, blocks []model.Block, auditRec *audit.
ctx := r.Context()
session := ctx.Value("session").(*model.Session)
userID := session.UserID
if userID == "single-user" {
if userID == SingleUser {
userID = ""
}
@ -444,12 +439,12 @@ func (a *API) handleGetMe(w http.ResponseWriter, r *http.Request) {
auditRec := a.makeAuditRecord(r, "getMe", audit.Fail)
defer a.audit.LogRecord(audit.LevelRead, auditRec)
if session.UserID == "single-user" {
if session.UserID == SingleUser {
now := time.Now().Unix()
user = &model.User{
ID: "single-user",
Username: "single-user",
Email: "single-user",
ID: SingleUser,
Username: SingleUser,
Email: SingleUser,
CreateAt: now,
UpdateAt: now,
}
@ -659,12 +654,16 @@ func (a *API) handleExport(w http.ResponseWriter, r *http.Request) {
defer a.audit.LogRecord(audit.LevelRead, auditRec)
auditRec.AddMeta("rootID", rootID)
blocks := []model.Block{}
var blocks []model.Block
if rootID == "" {
blocks, err = a.app.GetAllBlocks(*container)
} else {
blocks, err = a.app.GetBlocksWithRootID(*container, rootID)
}
if err != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err)
return
}
a.logger.Debug("raw blocks", mlog.Int("block_count", len(blocks)))
auditRec.AddMeta("rawCount", len(blocks))
@ -720,15 +719,6 @@ func filterOrphanBlocks(blocks []model.Block) (ret []model.Block) {
return blocks
}
func arrayContainsBlockWithID(array []model.Block, blockID string) bool {
for _, item := range array {
if item.ID == blockID {
return true
}
}
return false
}
func (a *API) handleImport(w http.ResponseWriter, r *http.Request) {
// swagger:operation POST /api/v1/workspaces/{workspaceID}/blocks/import importBlocks
//
@ -936,7 +926,7 @@ func (a *API) handlePostSharing(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session := ctx.Value("session").(*model.Session)
userID := session.UserID
if userID == "single-user" {
if userID == SingleUser {
userID = ""
}
sharing.ModifiedBy = userID
@ -1213,7 +1203,7 @@ func (a *API) handleUploadFile(w http.ResponseWriter, r *http.Request) {
auditRec.AddMeta("rootID", rootID)
auditRec.AddMeta("filename", handle.Filename)
fileId, err := a.app.SaveFile(file, workspaceID, rootID, handle.Filename)
fileID, err := a.app.SaveFile(file, workspaceID, rootID, handle.Filename)
if err != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err)
return
@ -1221,9 +1211,9 @@ func (a *API) handleUploadFile(w http.ResponseWriter, r *http.Request) {
a.logger.Debug("uploadFile",
mlog.String("filename", handle.Filename),
mlog.String("fileID", fileId),
mlog.String("fileID", fileID),
)
data, err := json.Marshal(FileUploadResponse{FileID: fileId})
data, err := json.Marshal(FileUploadResponse{FileID: fileID})
if err != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err)
return
@ -1231,7 +1221,7 @@ func (a *API) handleUploadFile(w http.ResponseWriter, r *http.Request) {
jsonBytesResponse(w, http.StatusOK, data)
auditRec.AddMeta("fileID", fileId)
auditRec.AddMeta("fileID", fileID)
auditRec.Success()
}
@ -1269,7 +1259,7 @@ func (a *API) getWorkspaceUsers(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session := ctx.Value("session").(*model.Session)
if !a.app.DoesUserHaveWorkspaceAccess(session.UserID, workspaceID) {
a.errorResponse(w, http.StatusForbidden, "Access denied to workspace", errors.New("Access denied to workspace"))
a.errorResponse(w, http.StatusForbidden, "Access denied to workspace", errors.New("access denied to workspace"))
return
}
@ -1307,7 +1297,7 @@ func (a *API) errorResponse(w http.ResponseWriter, code int, message string, sou
data = []byte("{}")
}
w.WriteHeader(code)
w.Write(data)
_, _ = w.Write(data)
}
func (a *API) errorResponseWithCode(w http.ResponseWriter, statusCode int, errorCode int, message string, sourceError error) {
@ -1322,27 +1312,21 @@ func (a *API) errorResponseWithCode(w http.ResponseWriter, statusCode int, error
data = []byte("{}")
}
w.WriteHeader(statusCode)
w.Write(data)
_, _ = w.Write(data)
}
func (a *API) noContainerErrorResponse(w http.ResponseWriter, sourceError error) {
a.errorResponseWithCode(w, http.StatusBadRequest, ERROR_NO_WORKSPACE_CODE, ERROR_NO_WORKSPACE_MESSAGE, sourceError)
a.errorResponseWithCode(w, http.StatusBadRequest, ErrorNoWorkspaceCode, ErrorNoWorkspaceMessage, sourceError)
}
func jsonStringResponse(w http.ResponseWriter, code int, message string) {
func jsonStringResponse(w http.ResponseWriter, code int, message string) { //nolint:unparam
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
fmt.Fprint(w, message)
}
func jsonBytesResponse(w http.ResponseWriter, code int, json []byte) {
func jsonBytesResponse(w http.ResponseWriter, code int, json []byte) { //nolint:unparam
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
w.Write(json)
}
func addUserID(rw http.ResponseWriter, req *http.Request, next http.Handler) {
ctx := context.WithValue(req.Context(), "userid", req.Header.Get("userid"))
req = req.WithContext(ctx)
next.ServeHTTP(rw, req)
_, _ = w.Write(json)
}

View File

@ -8,7 +8,7 @@ import (
)
// makeAuditRecord creates an audit record pre-populated with data from the request.
func (a *API) makeAuditRecord(r *http.Request, event string, initialStatus string) *audit.Record {
func (a *API) makeAuditRecord(r *http.Request, event string, initialStatus string) *audit.Record { //nolint:unparam
ctx := r.Context()
var sessionID string
var userID string

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
@ -18,6 +19,10 @@ import (
"github.com/mattermost/focalboard/server/services/mlog"
)
const (
MinimumPasswordLength = 8
)
// LoginRequest is a login request
// swagger:model
type LoginRequest struct {
@ -102,13 +107,13 @@ type ChangePasswordRequest struct {
NewPassword string `json:"newPassword"`
}
// IsValid validates a password change request
// IsValid validates a password change request.
func (rd *ChangePasswordRequest) IsValid() error {
if rd.OldPassword == "" {
return errors.New("Old password is required")
return errors.New("old password is required")
}
if rd.NewPassword == "" {
return errors.New("New password is required")
return errors.New("new password is required")
}
if err := isValidPassword(rd.NewPassword); err != nil {
return err
@ -118,8 +123,8 @@ func (rd *ChangePasswordRequest) IsValid() error {
}
func isValidPassword(password string) error {
if len(password) < 8 {
return errors.New("Password must be at least 8 characters")
if len(password) < MinimumPasswordLength {
return fmt.Errorf("password must be at least %d characters", MinimumPasswordLength)
}
return nil
}
@ -243,9 +248,9 @@ func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
// Validate token
if len(registerData.Token) > 0 {
workspace, err := a.app.GetRootWorkspace()
if err != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err)
workspace, err2 := a.app.GetRootWorkspace()
if err2 != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err2)
return
}
@ -255,9 +260,9 @@ func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
}
} else {
// No signup token, check if no active users
userCount, err := a.app.GetRegisteredUserCount()
if err != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err)
userCount, err2 := a.app.GetRegisteredUserCount()
if err2 != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err2)
return
}
if userCount > 0 {
@ -335,7 +340,7 @@ func (a *API) handleChangePassword(w http.ResponseWriter, r *http.Request) {
}
var requestData ChangePasswordRequest
if err := json.Unmarshal(requestBody, &requestData); err != nil {
if err = json.Unmarshal(requestBody, &requestData); err != nil {
a.errorResponse(w, http.StatusInternalServerError, "", err)
return
}
@ -374,9 +379,9 @@ func (a *API) attachSession(handler func(w http.ResponseWriter, r *http.Request)
now := time.Now().Unix()
session := &model.Session{
ID: "single-user",
ID: SingleUser,
Token: token,
UserID: "single-user",
UserID: SingleUser,
AuthService: a.authService,
Props: map[string]interface{}{},
CreateAt: now,
@ -441,6 +446,5 @@ func (a *API) adminRequired(handler func(w http.ResponseWriter, r *http.Request)
}
handler(w, r)
return
}
}

View File

@ -10,53 +10,61 @@ import (
"github.com/pkg/errors"
)
// GetSession Get a user active session and refresh the session if is needed
const (
DaysPerMonth = 30
DaysPerWeek = 7
HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
)
// GetSession Get a user active session and refresh the session if is needed.
func (a *App) GetSession(token string) (*model.Session, error) {
return a.auth.GetSession(token)
}
// IsValidReadToken validates the read token for a block
// IsValidReadToken validates the read token for a block.
func (a *App) IsValidReadToken(c store.Container, blockID string, readToken string) (bool, error) {
return a.auth.IsValidReadToken(c, blockID, readToken)
}
// GetRegisteredUserCount returns the number of registered users
// GetRegisteredUserCount returns the number of registered users.
func (a *App) GetRegisteredUserCount() (int, error) {
return a.store.GetRegisteredUserCount()
}
// GetDailyActiveUsers returns the number of daily active users
// GetDailyActiveUsers returns the number of daily active users.
func (a *App) GetDailyActiveUsers() (int, error) {
secondsAgo := int64(60 * 60 * 24)
secondsAgo := int64(SecondsPerMinute * MinutesPerHour * HoursPerDay)
return a.store.GetActiveUserCount(secondsAgo)
}
// GetWeeklyActiveUsers returns the number of weekly active users
// GetWeeklyActiveUsers returns the number of weekly active users.
func (a *App) GetWeeklyActiveUsers() (int, error) {
secondsAgo := int64(60 * 60 * 24 * 7)
secondsAgo := int64(SecondsPerMinute * MinutesPerHour * HoursPerDay * DaysPerWeek)
return a.store.GetActiveUserCount(secondsAgo)
}
// GetMonthlyActiveUsers returns the number of monthly active users
// GetMonthlyActiveUsers returns the number of monthly active users.
func (a *App) GetMonthlyActiveUsers() (int, error) {
secondsAgo := int64(60 * 60 * 24 * 30)
secondsAgo := int64(SecondsPerMinute * MinutesPerHour * HoursPerDay * DaysPerMonth)
return a.store.GetActiveUserCount(secondsAgo)
}
// GetUser Get an existing active user by id
func (a *App) GetUser(ID string) (*model.User, error) {
if len(ID) < 1 {
// GetUser gets an existing active user by id.
func (a *App) GetUser(id string) (*model.User, error) {
if len(id) < 1 {
return nil, errors.New("no user ID")
}
user, err := a.store.GetUserById(ID)
user, err := a.store.GetUserByID(id)
if err != nil {
return nil, errors.Wrap(err, "unable to find user")
}
return user, nil
}
// Login create a new user session if the authentication data is valid
// Login create a new user session if the authentication data is valid.
func (a *App) Login(username, email, password, mfaToken string) (string, error) {
var user *model.User
if username != "" {
@ -110,7 +118,7 @@ func (a *App) Login(username, email, password, mfaToken string) (string, error)
return session.Token, nil
}
// RegisterUser create a new user if the provided data is valid
// RegisterUser creates a new user if the provided data is valid.
func (a *App) RegisterUser(username, email, password string) error {
var user *model.User
if username != "" {
@ -169,7 +177,7 @@ func (a *App) ChangePassword(userID, oldPassword, newPassword string) error {
var user *model.User
if userID != "" {
var err error
user, err = a.store.GetUserById(userID)
user, err = a.store.GetUserByID(userID)
if err != nil {
return errors.Wrap(err, "invalid username or password")
}

View File

@ -70,8 +70,8 @@ func TestGetUser(t *testing.T) {
{"success", "goodID", false},
}
th.Store.EXPECT().GetUserById("badID").Return(nil, errors.New("Bad Id"))
th.Store.EXPECT().GetUserById("goodID").Return(mockUser, nil)
th.Store.EXPECT().GetUserByID("badID").Return(nil, errors.New("Bad Id"))
th.Store.EXPECT().GetUserByID("goodID").Return(mockUser, nil)
for _, test := range testcases {
t.Run(test.title, func(t *testing.T) {
@ -168,8 +168,8 @@ func TestChangePassword(t *testing.T) {
{"success, using username", mockUser.ID, "testPassword", "newPassword", false},
}
th.Store.EXPECT().GetUserById("badID").Return(nil, errors.New("userID not found"))
th.Store.EXPECT().GetUserById(mockUser.ID).Return(mockUser, nil).Times(2)
th.Store.EXPECT().GetUserByID("badID").Return(nil, errors.New("userID not found"))
th.Store.EXPECT().GetUserByID(mockUser.ID).Return(mockUser, nil).Times(2)
th.Store.EXPECT().UpdateUserPasswordByID(mockUser.ID, gomock.Any()).Return(nil)
for _, test := range testcases {

View File

@ -38,20 +38,7 @@ func (a *App) InsertBlock(c store.Container, block model.Block) error {
}
func (a *App) InsertBlocks(c store.Container, blocks []model.Block) error {
blockIDsToNotify := []string{}
uniqueBlockIDs := make(map[string]bool)
for _, block := range blocks {
if !uniqueBlockIDs[block.ID] {
blockIDsToNotify = append(blockIDsToNotify, block.ID)
}
// ParentID as empty string denotes a block at the root
if !uniqueBlockIDs[block.ParentID] {
blockIDsToNotify = append(blockIDsToNotify, block.ParentID)
}
err := a.store.InsertBlock(c, block)
if err != nil {
return err
@ -78,16 +65,11 @@ func (a *App) GetAllBlocks(c store.Container) ([]model.Block, error) {
}
func (a *App) DeleteBlock(c store.Container, blockID string, modifiedBy string) error {
blockIDsToNotify := []string{blockID}
parentID, err := a.GetParentID(c, blockID)
if err != nil {
return err
}
if len(parentID) > 0 {
blockIDsToNotify = append(blockIDsToNotify, parentID)
}
err = a.store.DeleteBlock(c, blockID, modifiedBy)
if err != nil {
return err

View File

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
@ -40,16 +39,23 @@ func (a *App) GetFileReader(workspaceID, rootID, filename string) (filestore.Rea
}
// FIXUP: Check the deprecated old location
if workspaceID == "0" && !exists {
oldExists, err := a.filesBackend.FileExists(filename)
if err != nil {
return nil, err
oldExists, err2 := a.filesBackend.FileExists(filename)
if err2 != nil {
return nil, err2
}
if oldExists {
err := a.filesBackend.MoveFile(filename, filePath)
if err != nil {
a.logger.Error("ERROR moving file", mlog.String("old", filename), mlog.String("new", filePath))
err2 := a.filesBackend.MoveFile(filename, filePath)
if err2 != nil {
a.logger.Error("ERROR moving file",
mlog.String("old", filename),
mlog.String("new", filePath),
mlog.Err(err2),
)
} else {
a.logger.Debug("Moved file", mlog.String("old", filename), mlog.String("new", filePath))
a.logger.Debug("Moved file",
mlog.String("old", filename),
mlog.String("new", filePath),
)
}
}
}
@ -61,8 +67,3 @@ func (a *App) GetFileReader(workspaceID, rootID, filename string) (filestore.Rea
return reader, nil
}
func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}

View File

@ -24,7 +24,6 @@ type TestHelper struct {
}
func SetupTestHelper(t *testing.T) *TestHelper {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cfg := config.Configuration{}

View File

@ -2,6 +2,7 @@ package app
import (
"database/sql"
"errors"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/services/store"
@ -9,7 +10,7 @@ import (
func (a *App) GetSharing(c store.Container, rootID string) (*model.Sharing, error) {
sharing, err := a.store.GetSharing(c, rootID)
if err == sql.ErrNoRows {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {

View File

@ -19,7 +19,7 @@ func TestGetSharing(t *testing.T) {
WorkspaceID: utils.CreateGUID(),
}
t.Run("should get a sharing sucessfully", func(t *testing.T) {
t.Run("should get a sharing successfully", func(t *testing.T) {
want := &model.Sharing{
ID: utils.CreateGUID(),
Enabled: true,

View File

@ -2,6 +2,7 @@ package app
import (
"database/sql"
"errors"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/services/mlog"
@ -33,9 +34,9 @@ func (a *App) GetRootWorkspace() (*model.Workspace, error) {
return workspace, nil
}
func (a *App) GetWorkspace(ID string) (*model.Workspace, error) {
workspace, err := a.store.GetWorkspace(ID)
if err == sql.ErrNoRows {
func (a *App) GetWorkspace(id string) (*model.Workspace, error) {
workspace, err := a.store.GetWorkspace(id)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {

View File

@ -10,18 +10,18 @@ import (
"github.com/pkg/errors"
)
// Auth authenticates sessions
// Auth authenticates sessions.
type Auth struct {
config *config.Configuration
store store.Store
}
// New returns a new Auth
// New returns a new Auth.
func New(config *config.Configuration, store store.Store) *Auth {
return &Auth{config: config, store: store}
}
// GetSession Get a user active session and refresh the session if is needed
// GetSession Get a user active session and refresh the session if needed.
func (a *Auth) GetSession(token string) (*model.Session, error) {
if len(token) < 1 {
return nil, errors.New("no session token")
@ -32,12 +32,12 @@ func (a *Auth) GetSession(token string) (*model.Session, error) {
return nil, errors.Wrap(err, "unable to get the session for the token")
}
if session.UpdateAt < (time.Now().Unix() - a.config.SessionRefreshTime) {
a.store.RefreshSession(session)
_ = a.store.RefreshSession(session)
}
return session, nil
}
// IsValidReadToken validates the read token for a block
// IsValidReadToken validates the read token for a block.
func (a *Auth) IsValidReadToken(c store.Container, blockID string, readToken string) (bool, error) {
rootID, err := a.store.GetRootID(c, blockID)
if err != nil {
@ -45,7 +45,7 @@ func (a *Auth) IsValidReadToken(c store.Container, blockID string, readToken str
}
sharing, err := a.store.GetSharing(c, rootID)
if err == sql.ErrNoRows {
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
if err != nil {

View File

@ -41,11 +41,9 @@ func setupTestHelper(t *testing.T) *TestHelper {
Session: *mockSession,
Store: mockStore,
}
}
func TestGetSession(t *testing.T) {
th := setupTestHelper(t)
testcases := []struct {

View File

@ -13,7 +13,7 @@ import (
)
const (
API_URL_SUFFIX = "/api/v1"
APIURLSuffix = "/api/v1"
)
type Response struct {
@ -57,10 +57,10 @@ func toJSON(v interface{}) string {
}
type Client struct {
Url string
ApiUrl string
HttpClient *http.Client
HttpHeader map[string]string
URL string
APIURL string
HTTPClient *http.Client
HTTPHeader map[string]string
}
func NewClient(url, sessionToken string) *Client {
@ -69,63 +69,63 @@ func NewClient(url, sessionToken string) *Client {
"X-Requested-With": "XMLHttpRequest",
"Authorization": "Bearer " + sessionToken,
}
return &Client{url, url + API_URL_SUFFIX, &http.Client{}, headers}
return &Client{url, url + APIURLSuffix, &http.Client{}, headers}
}
func (c *Client) DoApiGet(url, etag string) (*http.Response, error) {
return c.DoApiRequest(http.MethodGet, c.ApiUrl+url, "", etag)
func (c *Client) DoAPIGet(url, etag string) (*http.Response, error) {
return c.DoAPIRequest(http.MethodGet, c.APIURL+url, "", etag)
}
func (c *Client) DoApiPost(url, data string) (*http.Response, error) {
return c.DoApiRequest(http.MethodPost, c.ApiUrl+url, data, "")
func (c *Client) DoAPIPost(url, data string) (*http.Response, error) {
return c.DoAPIRequest(http.MethodPost, c.APIURL+url, data, "")
}
func (c *Client) doApiPostBytes(url string, data []byte) (*http.Response, error) {
return c.doApiRequestBytes(http.MethodPost, c.ApiUrl+url, data, "")
func (c *Client) doAPIPostBytes(url string, data []byte) (*http.Response, error) {
return c.doAPIRequestBytes(http.MethodPost, c.APIURL+url, data, "")
}
func (c *Client) DoApiPut(url, data string) (*http.Response, error) {
return c.DoApiRequest(http.MethodPut, c.ApiUrl+url, data, "")
func (c *Client) DoAPIPut(url, data string) (*http.Response, error) {
return c.DoAPIRequest(http.MethodPut, c.APIURL+url, data, "")
}
func (c *Client) doApiPutBytes(url string, data []byte) (*http.Response, error) {
return c.doApiRequestBytes(http.MethodPut, c.ApiUrl+url, data, "")
func (c *Client) doAPIPutBytes(url string, data []byte) (*http.Response, error) {
return c.doAPIRequestBytes(http.MethodPut, c.APIURL+url, data, "")
}
func (c *Client) DoApiDelete(url string) (*http.Response, error) {
return c.DoApiRequest(http.MethodDelete, c.ApiUrl+url, "", "")
func (c *Client) DoAPIDelete(url string) (*http.Response, error) {
return c.DoAPIRequest(http.MethodDelete, c.APIURL+url, "", "")
}
func (c *Client) DoApiRequest(method, url, data, etag string) (*http.Response, error) {
return c.doApiRequestReader(method, url, strings.NewReader(data), etag)
func (c *Client) DoAPIRequest(method, url, data, etag string) (*http.Response, error) {
return c.doAPIRequestReader(method, url, strings.NewReader(data), etag)
}
func (c *Client) doApiRequestBytes(method, url string, data []byte, etag string) (*http.Response, error) {
return c.doApiRequestReader(method, url, bytes.NewReader(data), etag)
func (c *Client) doAPIRequestBytes(method, url string, data []byte, etag string) (*http.Response, error) {
return c.doAPIRequestReader(method, url, bytes.NewReader(data), etag)
}
func (c *Client) doApiRequestReader(method, url string, data io.Reader, etag string) (*http.Response, error) {
func (c *Client) doAPIRequestReader(method, url string, data io.Reader, _ /* etag */ string) (*http.Response, error) {
rq, err := http.NewRequest(method, url, data)
if err != nil {
return nil, err
}
if c.HttpHeader != nil && len(c.HttpHeader) > 0 {
for k, v := range c.HttpHeader {
if c.HTTPHeader != nil && len(c.HTTPHeader) > 0 {
for k, v := range c.HTTPHeader {
rq.Header.Set(k, v)
}
}
rp, err := c.HttpClient.Do(rq)
rp, err := c.HTTPClient.Do(rq)
if err != nil || rp == nil {
return nil, err
}
if rp.StatusCode == 304 {
if rp.StatusCode == http.StatusNotModified {
return rp, nil
}
if rp.StatusCode >= 300 {
if rp.StatusCode >= http.StatusMultipleChoices {
defer closeBody(rp)
b, err := ioutil.ReadAll(rp.Body)
if err != nil {
@ -150,7 +150,7 @@ func (c *Client) GetSubtreeRoute(id string) string {
}
func (c *Client) GetBlocks() ([]model.Block, *Response) {
r, err := c.DoApiGet(c.GetBlocksRoute(), "")
r, err := c.DoAPIGet(c.GetBlocksRoute(), "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
@ -160,7 +160,7 @@ func (c *Client) GetBlocks() ([]model.Block, *Response) {
}
func (c *Client) InsertBlocks(blocks []model.Block) (bool, *Response) {
r, err := c.DoApiPost(c.GetBlocksRoute(), toJSON(blocks))
r, err := c.DoAPIPost(c.GetBlocksRoute(), toJSON(blocks))
if err != nil {
return false, BuildErrorResponse(r, err)
}
@ -170,7 +170,7 @@ func (c *Client) InsertBlocks(blocks []model.Block) (bool, *Response) {
}
func (c *Client) DeleteBlock(blockID string) (bool, *Response) {
r, err := c.DoApiDelete(c.GetBlockRoute(blockID))
r, err := c.DoAPIDelete(c.GetBlockRoute(blockID))
if err != nil {
return false, BuildErrorResponse(r, err)
}
@ -180,7 +180,7 @@ func (c *Client) DeleteBlock(blockID string) (bool, *Response) {
}
func (c *Client) GetSubtree(blockID string) ([]model.Block, *Response) {
r, err := c.DoApiGet(c.GetSubtreeRoute(blockID), "")
r, err := c.DoAPIGet(c.GetSubtreeRoute(blockID), "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
@ -196,7 +196,7 @@ func (c *Client) GetSharingRoute(rootID string) string {
}
func (c *Client) GetSharing(rootID string) (*model.Sharing, *Response) {
r, err := c.DoApiGet(c.GetSharingRoute(rootID), "")
r, err := c.DoAPIGet(c.GetSharingRoute(rootID), "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
@ -207,7 +207,7 @@ func (c *Client) GetSharing(rootID string) (*model.Sharing, *Response) {
}
func (c *Client) PostSharing(sharing model.Sharing) (bool, *Response) {
r, err := c.DoApiPost(c.GetSharingRoute(sharing.ID), toJSON(sharing))
r, err := c.DoAPIPost(c.GetSharingRoute(sharing.ID), toJSON(sharing))
if err != nil {
return false, BuildErrorResponse(r, err)
}

View File

@ -12,12 +12,12 @@ type contextKey struct {
var connContextKey = &contextKey{"http-conn"}
// SetContextConn stores the connection in the request context
// SetContextConn stores the connection in the request context.
func SetContextConn(ctx context.Context, c net.Conn) context.Context {
return context.WithValue(ctx, connContextKey, c)
}
// GetContextConn gets the stored connection from the request context
// GetContextConn gets the stored connection from the request context.
func GetContextConn(r *http.Request) net.Conn {
value := r.Context().Value(connContextKey)
if value == nil {

View File

@ -66,7 +66,9 @@ func SetupTestHelper() *TestHelper {
sessionToken := "TESTTOKEN"
th := &TestHelper{}
logger := mlog.NewLogger()
logger.Configure("", getTestConfig().LoggingCfgJSON)
if err := logger.Configure("", getTestConfig().LoggingCfgJSON); err != nil {
panic(err)
}
srv, err := server.New(getTestConfig(), sessionToken, logger)
if err != nil {
panic(err)
@ -111,7 +113,7 @@ func (th *TestHelper) InitBasic() *TestHelper {
}
func (th *TestHelper) TearDown() {
defer th.Server.Logger().Shutdown()
defer func() { _ = th.Server.Logger().Shutdown() }()
err := th.Server.Shutdown()
if err != nil {

View File

@ -105,7 +105,7 @@ func main() {
log.Fatal("Error in config file for logger: ", err)
return
}
defer logger.Shutdown()
defer func() { _ = logger.Shutdown() }()
if logger.HasTargets() {
restore := logger.RedirectStdLog(mlog.Info, mlog.String("src", "stdlog"))
@ -176,7 +176,7 @@ func main() {
// Waiting for SIGINT (pkill -2)
<-stop
server.Shutdown()
_ = server.Shutdown()
}
// StartServer starts the server
@ -254,7 +254,7 @@ func stopServer() {
if err != nil {
pServer.Logger().Error("server.Shutdown ERROR", mlog.Err(err))
}
pServer.Logger().Shutdown()
_ = pServer.Logger().Shutdown()
pServer = nil
}

View File

@ -53,7 +53,7 @@ type Block struct {
DeleteAt int64 `json:"deleteAt"`
}
// Archive is an import / export archive
// Archive is an import / export archive.
type Archive struct {
Version int64 `json:"version"`
Date int64 `json:"date"`
@ -62,7 +62,7 @@ type Archive struct {
func BlocksFromJSON(data io.Reader) []Block {
var blocks []Block
json.NewDecoder(data).Decode(&blocks)
_ = json.NewDecoder(data).Decode(&blocks)
return blocks
}

View File

@ -31,6 +31,6 @@ type Sharing struct {
func SharingFromJSON(data io.Reader) Sharing {
var sharing Sharing
json.NewDecoder(data).Decode(&sharing)
_ = json.NewDecoder(data).Decode(&sharing)
return sharing
}

View File

@ -2,5 +2,5 @@ package server
func (s *Server) initHandlers() {
cfg := s.config
s.api.MattermostAuth = cfg.AuthMode == "mattermost"
s.api.MattermostAuth = cfg.AuthMode == MattermostAuthMod
}

View File

@ -1,7 +1,7 @@
package server
import (
"log"
"fmt"
"net"
"net/http"
"os"
@ -43,6 +43,8 @@ const (
//nolint:gomnd
minSessionExpiryTime = int64(60 * 60 * 24 * 31) // 31 days
MattermostAuthMod = "mattermost"
)
type Server struct {
@ -72,18 +74,18 @@ func New(cfg *config.Configuration, singleUserToken string, logger *mlog.Logger)
logger.Error("Unable to start the database", mlog.Err(err))
return nil, err
}
if cfg.AuthMode == "mattermost" {
layeredStore, err := mattermostauthlayer.New(cfg.DBType, cfg.DBConfigString, db)
if err != nil {
log.Print("Unable to start the database", err)
return nil, err
if cfg.AuthMode == MattermostAuthMod {
layeredStore, err2 := mattermostauthlayer.New(cfg.DBType, cfg.DBConfigString, db)
if err2 != nil {
logger.Error("Unable to start the database", mlog.Err(err2))
return nil, err2
}
db = layeredStore
}
authenticator := auth.New(cfg, db)
wsServer := ws.NewServer(authenticator, singleUserToken, cfg.AuthMode == "mattermost", logger)
wsServer := ws.NewServer(authenticator, singleUserToken, cfg.AuthMode == MattermostAuthMod, logger)
filesBackendSettings := filestore.FileBackendSettings{}
filesBackendSettings.DriverName = cfg.FilesDriver
@ -119,8 +121,8 @@ func New(cfg *config.Configuration, singleUserToken string, logger *mlog.Logger)
// Init audit
auditService := audit.NewAudit()
if err := auditService.Configure(cfg.AuditCfgFile, cfg.AuditCfgJSON); err != nil {
return nil, errors.New("unable to initialize the audit service")
if err2 := auditService.Configure(cfg.AuditCfgFile, cfg.AuditCfgJSON); err2 != nil {
return nil, fmt.Errorf("unable to initialize the audit service: %w", err2)
}
appServices := app.Services{
@ -250,7 +252,7 @@ func (s *Server) Start() error {
}
return nil
}, func(error) {
s.metricsServer.Shutdown()
_ = s.metricsServer.Shutdown()
})
if err := group.Run(); err != nil {

View File

@ -33,7 +33,7 @@ type Audit struct {
auditLogger *mlog.Logger
}
// NewAudit creates a new Audit instance which can be configured via `(*Audit).Configure`
// NewAudit creates a new Audit instance which can be configured via `(*Audit).Configure`.
func NewAudit(options ...mlog.Option) *Audit {
logger := mlog.NewLogger(options...)

View File

@ -2,6 +2,7 @@ package auth
import "regexp"
//nolint:lll
var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
// IsEmailValid checks if the email provided passes the required structure and length.

View File

@ -9,7 +9,7 @@ import (
const (
PasswordMaximumLength = 64
PasswordSpecialChars = "!\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
PasswordSpecialChars = "!\"\\#$%&'()*+,-./:;<=>?@[]^_`|~" //nolint:gosec
PasswordNumbers = "0123456789"
PasswordUpperCaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
PasswordLowerCaseLetters = "abcdefghijklmnopqrstuvwxyz"
@ -23,7 +23,7 @@ const (
InvalidSymbolPassword = "symbol"
)
// HashPassword generates a hash using the bcrypt.GenerateFromPassword
// HashPassword generates a hash using the bcrypt.GenerateFromPassword.
func HashPassword(password string) string {
hash, err := bcrypt.GenerateFromPassword([]byte(password), 10)
if err != nil {
@ -33,7 +33,7 @@ func HashPassword(password string) string {
return string(hash)
}
// ComparePassword compares the hash
// ComparePassword compares the hash.
func ComparePassword(hash, password string) bool {
if len(password) == 0 || len(hash) == 0 {
return false
@ -48,7 +48,7 @@ type InvalidPasswordError struct {
}
func (ipe *InvalidPasswordError) Error() string {
return fmt.Sprintf("invalid password, failing criterias: %s", strings.Join(ipe.FailingCriterias, ", "))
return fmt.Sprintf("invalid password, failing criteria: %s", strings.Join(ipe.FailingCriterias, ", "))
}
type PasswordSettings struct {

View File

@ -9,10 +9,10 @@ import (
)
const (
HEADER_TOKEN = "token"
HEADER_AUTH = "Authorization"
HEADER_BEARER = "BEARER"
SESSION_COOKIE_TOKEN = "FOCALBOARDAUTHTOKEN"
HeaderToken = "token"
HeaderAuth = "Authorization"
HeaderBearer = "BEARER"
SessionCookieToken = "FOCALBOARDAUTHTOKEN"
)
type TokenLocation int
@ -40,20 +40,20 @@ func (tl TokenLocation) String() string {
}
func ParseAuthTokenFromRequest(r *http.Request) (string, TokenLocation) {
authHeader := r.Header.Get(HEADER_AUTH)
authHeader := r.Header.Get(HeaderAuth)
// Attempt to parse the token from the cookie
if cookie, err := r.Cookie(SESSION_COOKIE_TOKEN); err == nil {
if cookie, err := r.Cookie(SessionCookieToken); err == nil {
return cookie.Value, TokenLocationCookie
}
// Parse the token from the header
if len(authHeader) > 6 && strings.ToUpper(authHeader[0:6]) == HEADER_BEARER {
if len(authHeader) > 6 && strings.ToUpper(authHeader[0:6]) == HeaderBearer {
// Default session token
return authHeader[7:], TokenLocationHeader
}
if len(authHeader) > 5 && strings.ToLower(authHeader[0:5]) == HEADER_TOKEN {
if len(authHeader) > 5 && strings.ToLower(authHeader[0:5]) == HeaderToken {
// OAuth token
return authHeader[6:], TokenLocationHeader
}

View File

@ -31,7 +31,7 @@ func TestParseAuthTokenFromRequest(t *testing.T) {
}
req := httptest.NewRequest("GET", pathname, nil)
if tc.header != "" {
req.Header.Add(HEADER_AUTH, tc.header)
req.Header.Add(HeaderAuth, tc.header)
}
if tc.cookie != "" {
req.AddCookie(&http.Cookie{

View File

@ -22,7 +22,7 @@ type InstanceInfo struct {
InstallationID string
}
// Metrics used to instrumentate metrics in prometheus
// Metrics used to instrumentate metrics in prometheus.
type Metrics struct {
registry *prometheus.Registry
@ -41,7 +41,7 @@ type Metrics struct {
blockLastActivity prometheus.Gauge
}
// NewMetrics Factory method to create a new metrics collector
// NewMetrics Factory method to create a new metrics collector.
func NewMetrics(info InstanceInfo) *Metrics {
m := &Metrics{}

View File

@ -8,12 +8,12 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Service prometheus to run the server
// Service prometheus to run the server.
type Service struct {
*http.Server
}
// NewMetricsServer factory method to create a new prometheus server
// NewMetricsServer factory method to create a new prometheus server.
func NewMetricsServer(address string, metricsService *Metrics, logger *mlog.Logger) *Service {
return &Service{
&http.Server{
@ -25,12 +25,12 @@ func NewMetricsServer(address string, metricsService *Metrics, logger *mlog.Logg
}
}
// Run will start the prometheus server
// Run will start the prometheus server.
func (h *Service) Run() error {
return errors.Wrap(h.Server.ListenAndServe(), "prometheus ListenAndServe")
}
// Shutdown will shutdown the prometheus server
// Shutdown will shutdown the prometheus server.
func (h *Service) Shutdown() error {
return errors.Wrap(h.Server.Close(), "prometheus Close")
}

View File

@ -1,11 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
//nolint:gomnd
package mlog
import "github.com/mattermost/logr/v2"
// Standard levels
// Standard levels.
var (
Panic = logr.Panic // ID = 0
Fatal = logr.Fatal // ID = 1
@ -33,7 +34,7 @@ var (
Metrics = Level{ID: 501, Name: "metrics"}
)
// Combinations for LogM (log multi)
// Combinations for LogM (log multi).
var (
/* Example
MAuditAll = []Level{AuditAPI, AuditContent, AuditPerms, AuditCLI}

View File

@ -106,7 +106,7 @@ type Logger struct {
log *logr.Logger
}
// NewLogger creates a new Logger instance which can be configured via `(*Logger).Configure`
// NewLogger creates a new Logger instance which can be configured via `(*Logger).Configure`.
func NewLogger(options ...Option) *Logger {
lgr, _ := logr.New(options...)
log := lgr.NewLogger()
@ -129,15 +129,16 @@ func (l *Logger) Configure(cfgFile string, cfgEscaped string) error {
// Add config from file
if cfgFile != "" {
if b, err := ioutil.ReadFile(string(cfgFile)); err != nil {
b, err := ioutil.ReadFile(cfgFile)
if err != nil {
return fmt.Errorf("error reading logger config file %s: %w", cfgFile, err)
} else {
var mapCfgFile LoggerConfig
if err := json.Unmarshal(b, &mapCfgFile); err != nil {
return fmt.Errorf("error decoding logger config file %s: %w", cfgFile, err)
}
cfgMap.append(mapCfgFile)
}
var mapCfgFile LoggerConfig
if err := json.Unmarshal(b, &mapCfgFile); err != nil {
return fmt.Errorf("error decoding logger config file %s: %w", cfgFile, err)
}
cfgMap.append(mapCfgFile)
}
// Add config from escaped json string
@ -172,7 +173,7 @@ func (l *Logger) With(fields ...Field) *Logger {
// Note, transformations and serializations done via fields are already
// lazily evaluated and don't require this check beforehand.
func (l *Logger) IsLevelEnabled(level Level) bool {
return l.IsLevelEnabled(level)
return l.log.IsLevelEnabled(level)
}
// Log emits the log record for any targets configured for the specified level.
@ -215,7 +216,7 @@ func (l *Logger) Error(msg string, fields ...Field) {
// followed by `os.Exit(1)`.
func (l *Logger) Fatal(msg string, fields ...Field) {
l.log.Log(logr.Fatal, msg, fields...)
l.Shutdown()
_ = l.Shutdown()
os.Exit(1)
}

View File

@ -8,7 +8,7 @@ import (
"github.com/mattermost/logr/v2/formatters"
)
// CreateTestLogger creates a logger for unit tests. Log records are output to `(*testing.T)Log`
// CreateTestLogger creates a logger for unit tests. Log records are output to `(*testing.T)Log`.
func CreateTestLogger(t *testing.T, levels ...Field) (logger *Logger) {
logger = NewLogger()
@ -16,7 +16,10 @@ func CreateTestLogger(t *testing.T, levels ...Field) (logger *Logger) {
formatter := &formatters.Plain{}
target := newTestingTarget(t)
logger.log.Logr().AddTarget(target, "test", filter, formatter, 1000)
if err := logger.log.Logr().AddTarget(target, "test", filter, formatter, 1000); err != nil {
t.Fail()
return nil
}
return logger
}

View File

@ -15,7 +15,6 @@ import (
)
const (
mysqlDBType = "mysql"
sqliteDBType = "sqlite3"
postgresDBType = "postgres"
)
@ -56,12 +55,12 @@ func New(dbType, connectionString string, store store.Store) (*MattermostAuthLay
}
// Shutdown close the connection with the store.
func (l *MattermostAuthLayer) Shutdown() error {
err := l.Store.Shutdown()
func (s *MattermostAuthLayer) Shutdown() error {
err := s.Store.Shutdown()
if err != nil {
return err
}
return l.mmDB.Close()
return s.mmDB.Close()
}
func (s *MattermostAuthLayer) GetRegisteredUserCount() (int, error) {
@ -82,7 +81,8 @@ func (s *MattermostAuthLayer) GetRegisteredUserCount() (int, error) {
func (s *MattermostAuthLayer) getUserByCondition(condition sq.Eq) (*model.User, error) {
query := s.getQueryBuilder().
Select("id", "username", "email", "password", "MFASecret as mfa_secret", "AuthService as auth_service", "COALESCE(AuthData, '') as auth_data", "props", "CreateAt as create_at", "UpdateAt as update_at", "DeleteAt as delete_at").
Select("id", "username", "email", "password", "MFASecret as mfa_secret", "AuthService as auth_service", "COALESCE(AuthData, '') as auth_data",
"props", "CreateAt as create_at", "UpdateAt as update_at", "DeleteAt as delete_at").
From("Users").
Where(sq.Eq{"deleteAt": 0}).
Where(condition)
@ -90,7 +90,8 @@ func (s *MattermostAuthLayer) getUserByCondition(condition sq.Eq) (*model.User,
user := model.User{}
var propsBytes []byte
err := row.Scan(&user.ID, &user.Username, &user.Email, &user.Password, &user.MfaSecret, &user.AuthService, &user.AuthData, &propsBytes, &user.CreateAt, &user.UpdateAt, &user.DeleteAt)
err := row.Scan(&user.ID, &user.Username, &user.Email, &user.Password, &user.MfaSecret, &user.AuthService,
&user.AuthData, &propsBytes, &user.CreateAt, &user.UpdateAt, &user.DeleteAt)
if err != nil {
return nil, err
}
@ -103,7 +104,7 @@ func (s *MattermostAuthLayer) getUserByCondition(condition sq.Eq) (*model.User,
return &user, nil
}
func (s *MattermostAuthLayer) GetUserById(userID string) (*model.User, error) {
func (s *MattermostAuthLayer) GetUserByID(userID string) (*model.User, error) {
return s.getUserByCondition(sq.Eq{"id": userID})
}
@ -131,7 +132,7 @@ func (s *MattermostAuthLayer) UpdateUserPasswordByID(userID, password string) er
return errors.New("no update allowed from focalboard, update it using mattermost")
}
// GetActiveUserCount returns the number of users with active sessions within N seconds ago
// GetActiveUserCount returns the number of users with active sessions within N seconds ago.
func (s *MattermostAuthLayer) GetActiveUserCount(updatedSecondsAgo int64) (int, error) {
query := s.getQueryBuilder().
Select("count(distinct userId)").
@ -165,7 +166,7 @@ func (s *MattermostAuthLayer) UpdateSession(session *model.Session) error {
return errors.New("no update allowed from focalboard, update it using mattermost")
}
func (s *MattermostAuthLayer) DeleteSession(sessionId string) error {
func (s *MattermostAuthLayer) DeleteSession(sessionID string) error {
return errors.New("no update allowed from focalboard, update it using mattermost")
}
@ -173,10 +174,10 @@ func (s *MattermostAuthLayer) CleanUpSessions(expireTime int64) error {
return errors.New("no update allowed from focalboard, update it using mattermost")
}
func (s *MattermostAuthLayer) GetWorkspace(ID string) (*model.Workspace, error) {
if ID == "0" {
func (s *MattermostAuthLayer) GetWorkspace(id string) (*model.Workspace, error) {
if id == "0" {
workspace := model.Workspace{
ID: ID,
ID: id,
Title: "",
}
@ -186,7 +187,7 @@ func (s *MattermostAuthLayer) GetWorkspace(ID string) (*model.Workspace, error)
query := s.getQueryBuilder().
Select("DisplayName, Type").
From("Channels").
Where(sq.Eq{"ID": ID})
Where(sq.Eq{"ID": id})
row := query.QueryRow()
var displayName string
@ -197,14 +198,14 @@ func (s *MattermostAuthLayer) GetWorkspace(ID string) (*model.Workspace, error)
}
if channelType != "D" && channelType != "G" {
return &model.Workspace{ID: ID, Title: displayName}, nil
return &model.Workspace{ID: id, Title: displayName}, nil
}
query = s.getQueryBuilder().
Select("Username").
From("ChannelMembers").
Join("Users ON Users.ID=ChannelMembers.UserID").
Where(sq.Eq{"ChannelID": ID})
Where(sq.Eq{"ChannelID": id})
var sb strings.Builder
rows, err := query.Query()
@ -223,7 +224,7 @@ func (s *MattermostAuthLayer) GetWorkspace(ID string) (*model.Workspace, error)
}
sb.WriteString(name)
}
return &model.Workspace{ID: ID, Title: sb.String()}, nil
return &model.Workspace{ID: id, Title: sb.String()}, nil
}
func (s *MattermostAuthLayer) HasWorkspaceAccess(userID string, workspaceID string) (bool, error) {
@ -255,7 +256,8 @@ func (s *MattermostAuthLayer) getQueryBuilder() sq.StatementBuilderType {
func (s *MattermostAuthLayer) GetUsersByWorkspace(workspaceID string) ([]*model.User, error) {
query := s.getQueryBuilder().
Select("id", "username", "email", "password", "MFASecret as mfa_secret", "AuthService as auth_service", "COALESCE(AuthData, '') as auth_data", "props", "CreateAt as create_at", "UpdateAt as update_at", "DeleteAt as delete_at").
Select("id", "username", "email", "password", "MFASecret as mfa_secret", "AuthService as auth_service", "COALESCE(AuthData, '') as auth_data",
"props", "CreateAt as create_at", "UpdateAt as update_at", "DeleteAt as delete_at").
From("Users").
Join("ChannelMembers ON ChannelMembers.UserID = Users.ID").
Where(sq.Eq{"deleteAt": 0}).

View File

@ -345,19 +345,19 @@ func (mr *MockStoreMockRecorder) GetUserByEmail(email interface{}) *gomock.Call
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByEmail", reflect.TypeOf((*MockStore)(nil).GetUserByEmail), email)
}
// GetUserById mocks base method.
func (m *MockStore) GetUserById(userID string) (*model.User, error) {
// GetUserByID mocks base method.
func (m *MockStore) GetUserByID(userID string) (*model.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserById", userID)
ret := m.ctrl.Call(m, "GetUserByID", userID)
ret0, _ := ret[0].(*model.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserById indicates an expected call of GetUserById.
func (mr *MockStoreMockRecorder) GetUserById(userID interface{}) *gomock.Call {
// GetUserByID indicates an expected call of GetUserByID.
func (mr *MockStoreMockRecorder) GetUserByID(userID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserById", reflect.TypeOf((*MockStore)(nil).GetUserById), userID)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByID", reflect.TypeOf((*MockStore)(nil).GetUserByID), userID)
}
// GetUserByUsername mocks base method.

View File

@ -132,7 +132,7 @@ func (s *SQLStore) GetBlocksWithType(c store.Container, blockType string) ([]mod
return s.blocksFromRows(rows)
}
// GetSubTree2 returns blocks within 2 levels of the given blockID
// GetSubTree2 returns blocks within 2 levels of the given blockID.
func (s *SQLStore) GetSubTree2(c store.Container, blockID string) ([]model.Block, error) {
query := s.getQueryBuilder().
Select(
@ -162,7 +162,7 @@ func (s *SQLStore) GetSubTree2(c store.Container, blockID string) ([]model.Block
return s.blocksFromRows(rows)
}
// GetSubTree3 returns blocks within 3 levels of the given blockID
// GetSubTree3 returns blocks within 3 levels of the given blockID.
func (s *SQLStore) GetSubTree3(c store.Container, blockID string) ([]model.Block, error) {
// This first subquery returns repeated blocks
query := s.getQueryBuilder().Select(
@ -363,19 +363,19 @@ func (s *SQLStore) InsertBlock(c store.Container, block model.Block) error {
Where(sq.Eq{"COALESCE(workspace_id, '0')": c.WorkspaceID})
_, err = sq.ExecContextWith(ctx, tx, deleteQuery)
if err != nil {
tx.Rollback()
_ = tx.Rollback()
return err
}
_, err = sq.ExecContextWith(ctx, tx, query.Into(s.tablePrefix+"blocks"))
if err != nil {
tx.Rollback()
_ = tx.Rollback()
return err
}
_, err = sq.ExecContextWith(ctx, tx, query.Into(s.tablePrefix+"blocks_history"))
if err != nil {
tx.Rollback()
_ = tx.Rollback()
return err
}
@ -413,7 +413,7 @@ func (s *SQLStore) DeleteBlock(c store.Container, blockID string, modifiedBy str
_, err = sq.ExecContextWith(ctx, tx, insertQuery)
if err != nil {
tx.Rollback()
_ = tx.Rollback()
return err
}
@ -424,7 +424,7 @@ func (s *SQLStore) DeleteBlock(c store.Container, blockID string, modifiedBy str
_, err = sq.ExecContextWith(ctx, tx, deleteQuery)
if err != nil {
tx.Rollback()
_ = tx.Rollback()
return err
}

View File

@ -10,7 +10,7 @@ import (
"github.com/mattermost/focalboard/server/services/store/sqlstore/initializations"
)
// InitializeTemplates imports default templates if the blocks table is empty
// InitializeTemplates imports default templates if the blocks table is empty.
func (s *SQLStore) InitializeTemplates() error {
isNeeded, err := s.isInitializationNeeded()
if err != nil {
@ -54,7 +54,7 @@ func (s *SQLStore) importInitialTemplates() error {
return nil
}
// isInitializationNeeded returns true if the blocks table is empty
// isInitializationNeeded returns true if the blocks table is empty.
func (s *SQLStore) isInitializationNeeded() (bool, error) {
query := s.getQueryBuilder().
Select("count(*)").

View File

@ -84,7 +84,7 @@ func appendMultipleStatementsFlag(connectionString string) (string, error) {
// migrations in MySQL need to run with the multiStatements flag
// enabled, so this method creates a new connection ensuring that it's
// enabled
// enabled.
func (s *SQLStore) getMySQLMigrationConnection() (*sql.DB, error) {
connectionString, err := appendMultipleStatementsFlag(s.connectionString)
if err != nil {
@ -123,9 +123,9 @@ func (s *SQLStore) Migrate() error {
}
if s.dbType == mysqlDBType {
db, err := s.getMySQLMigrationConnection()
if err != nil {
return err
db, err2 := s.getMySQLMigrationConnection()
if err2 != nil {
return err2
}
defer db.Close()

View File

@ -8,7 +8,7 @@ import (
"github.com/mattermost/focalboard/server/model"
)
// GetActiveUserCount returns the number of users with active sessions within N seconds ago
// GetActiveUserCount returns the number of users with active sessions within N seconds ago.
func (s *SQLStore) GetActiveUserCount(updatedSecondsAgo int64) (int, error) {
query := s.getQueryBuilder().
Select("count(distinct user_id)").
@ -94,9 +94,9 @@ func (s *SQLStore) UpdateSession(session *model.Session) error {
return err
}
func (s *SQLStore) DeleteSession(sessionId string) error {
func (s *SQLStore) DeleteSession(sessionID string) error {
query := s.getQueryBuilder().Delete(s.tablePrefix+"sessions").
Where("id", sessionId)
Where("id", sessionID)
_, err := query.Exec()
return err

View File

@ -29,9 +29,13 @@ func (s *SQLStore) UpsertSharing(c store.Container, sharing model.Sharing) error
now,
)
if s.dbType == mysqlDBType {
query = query.Suffix("ON DUPLICATE KEY UPDATE enabled = ?, token = ?, modified_by = ?, update_at = ?", sharing.Enabled, sharing.Token, sharing.ModifiedBy, now)
query = query.Suffix("ON DUPLICATE KEY UPDATE enabled = ?, token = ?, modified_by = ?, update_at = ?",
sharing.Enabled, sharing.Token, sharing.ModifiedBy, now)
} else {
query = query.Suffix("ON CONFLICT (id) DO UPDATE SET enabled = EXCLUDED.enabled, token = EXCLUDED.token, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at")
query = query.Suffix(
`ON CONFLICT (id)
DO UPDATE SET enabled = EXCLUDED.enabled, token = EXCLUDED.token, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at`,
)
}
_, err := query.Exec()

View File

@ -27,7 +27,7 @@ func SetupTests(t *testing.T) (store.Store, func()) {
require.Nil(t, err)
tearDown := func() {
defer logger.Shutdown()
defer func() { _ = logger.Shutdown() }()
err = store.Shutdown()
require.Nil(t, err)
}

View File

@ -77,7 +77,7 @@ func (s *SQLStore) getUsersByCondition(condition sq.Eq) ([]*model.User, error) {
return users, nil
}
func (s *SQLStore) GetUserById(userID string) (*model.User, error) {
func (s *SQLStore) GetUserByID(userID string) (*model.User, error) {
return s.getUserByCondition(sq.Eq{"id": userID})
}

View File

@ -28,9 +28,13 @@ func (s *SQLStore) UpsertWorkspaceSignupToken(workspace model.Workspace) error {
now,
)
if s.dbType == mysqlDBType {
query = query.Suffix("ON DUPLICATE KEY UPDATE signup_token = ?, modified_by = ?, update_at = ?", workspace.SignupToken, workspace.ModifiedBy, now)
query = query.Suffix("ON DUPLICATE KEY UPDATE signup_token = ?, modified_by = ?, update_at = ?",
workspace.SignupToken, workspace.ModifiedBy, now)
} else {
query = query.Suffix("ON CONFLICT (id) DO UPDATE SET signup_token = EXCLUDED.signup_token, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at")
query = query.Suffix(
`ON CONFLICT (id)
DO UPDATE SET signup_token = EXCLUDED.signup_token, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at`,
)
}
_, err := query.Exec()
@ -62,14 +66,17 @@ func (s *SQLStore) UpsertWorkspaceSettings(workspace model.Workspace) error {
if s.dbType == mysqlDBType {
query = query.Suffix("ON DUPLICATE KEY UPDATE settings = ?, modified_by = ?, update_at = ?", settingsJSON, workspace.ModifiedBy, now)
} else {
query = query.Suffix("ON CONFLICT (id) DO UPDATE SET settings = EXCLUDED.settings, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at")
query = query.Suffix(
`ON CONFLICT (id)
DO UPDATE SET settings = EXCLUDED.settings, modified_by = EXCLUDED.modified_by, update_at = EXCLUDED.update_at`,
)
}
_, err = query.Exec()
return err
}
func (s *SQLStore) GetWorkspace(ID string) (*model.Workspace, error) {
func (s *SQLStore) GetWorkspace(id string) (*model.Workspace, error) {
var settingsJSON string
query := s.getQueryBuilder().
@ -81,7 +88,7 @@ func (s *SQLStore) GetWorkspace(ID string) (*model.Workspace, error) {
"update_at",
).
From(s.tablePrefix + "workspaces").
Where(sq.Eq{"id": ID})
Where(sq.Eq{"id": id})
row := query.QueryRow()
workspace := model.Workspace{}

View File

@ -4,7 +4,7 @@ package store
import "github.com/mattermost/focalboard/server/model"
// Conainer represents a container in a store
// Using a struct to make extending this easier in the future
// Using a struct to make extending this easier in the future.
type Container struct {
WorkspaceID string
}
@ -30,7 +30,7 @@ type Store interface {
SetSystemSetting(key, value string) error
GetRegisteredUserCount() (int, error)
GetUserById(userID string) (*model.User, error)
GetUserByID(userID string) (*model.User, error)
GetUserByEmail(email string) (*model.User, error)
GetUserByUsername(username string) (*model.User, error)
CreateUser(user *model.User) error
@ -44,7 +44,7 @@ type Store interface {
CreateSession(session *model.Session) error
RefreshSession(session *model.Session) error
UpdateSession(session *model.Session) error
DeleteSession(sessionId string) error
DeleteSession(sessionID string) error
CleanUpSessions(expireTime int64) error
UpsertSharing(c Container, sharing model.Sharing) error

View File

@ -19,7 +19,7 @@ func StoreTestSystemStore(t *testing.T, setup func(t *testing.T) (store.Store, f
})
}
func testSetGetSystemSettings(t *testing.T, store store.Store, container store.Container) {
func testSetGetSystemSettings(t *testing.T, store store.Store, _ /*container*/ store.Container) {
t.Run("Get empty settings", func(t *testing.T) {
settings, err := store.GetSystemSettings()
require.NoError(t, err)

View File

@ -39,10 +39,12 @@ func testGetWorkspaceUsers(t *testing.T, store store.Store) {
})
require.Nil(t, err)
defer store.UpdateUser(&model.User{
ID: userID,
DeleteAt: time.Now().Unix(),
})
defer func() {
_ = store.UpdateUser(&model.User{
ID: userID,
DeleteAt: time.Now().Unix(),
})
}()
users, err = store.GetUsersByWorkspace("workspace_1")
require.Equal(t, 1, len(users))

View File

@ -79,7 +79,7 @@ func (ts *Service) sendDailyTelemetry(override bool) {
func (ts *Service) sendTelemetry(event string, properties map[string]interface{}) {
if ts.rudderClient != nil {
var context *rudder.Context
ts.rudderClient.Enqueue(rudder.Track{
_ = ts.rudderClient.Enqueue(rudder.Track{
Event: event,
UserId: ts.telemetryID,
Properties: properties,
@ -103,7 +103,7 @@ func (ts *Service) initRudder(endpoint, rudderKey string) {
ts.logger.Fatal("Failed to create Rudder instance")
return
}
client.Enqueue(rudder.Identify{
_ = client.Enqueue(rudder.Identify{
UserId: ts.telemetryID,
})

View File

@ -3,6 +3,7 @@ package webhook
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"github.com/mattermost/focalboard/server/model"
@ -10,7 +11,7 @@ import (
"github.com/mattermost/focalboard/server/services/mlog"
)
// NotifyUpdate calls webhooks
// NotifyUpdate calls webhooks.
func (wh *Client) NotifyUpdate(block model.Block) {
if len(wh.config.WebhookUpdate) < 1 {
return
@ -21,18 +22,21 @@ func (wh *Client) NotifyUpdate(block model.Block) {
wh.logger.Fatal("NotifyUpdate: json.Marshal", mlog.Err(err))
}
for _, url := range wh.config.WebhookUpdate {
http.Post(url, "application/json", bytes.NewBuffer(json))
resp, _ := http.Post(url, "application/json", bytes.NewBuffer(json)) //nolint:gosec
_, _ = ioutil.ReadAll(resp.Body)
resp.Body.Close()
wh.logger.Debug("webhook.NotifyUpdate", mlog.String("url", url))
}
}
// Client is a webhook client
// Client is a webhook client.
type Client struct {
config *config.Configuration
logger *mlog.Logger
}
// NewClient creates a new Client
// NewClient creates a new Client.
func NewClient(config *config.Configuration, logger *mlog.Logger) *Client {
return &Client{
config: config,

View File

@ -1,6 +1,7 @@
package web
import (
"errors"
"fmt"
"net/http"
"net/url"
@ -24,12 +25,11 @@ type RoutedService interface {
type Server struct {
http.Server
baseURL string
rootPath string
port int
ssl bool
localOnly bool
logger *mlog.Logger
baseURL string
rootPath string
port int
ssl bool
logger *mlog.Logger
}
// NewServer creates a new instance of the webserver.
@ -81,13 +81,13 @@ func (ws *Server) registerRoutes() {
indexTemplate, err := template.New("index").ParseFiles(path.Join(ws.rootPath, "index.html"))
if err != nil {
ws.logger.Error("Unable to serve the index.html file", mlog.Err(err))
w.WriteHeader(500)
w.WriteHeader(http.StatusInternalServerError)
return
}
err = indexTemplate.ExecuteTemplate(w, "index.html", map[string]string{"BaseURL": ws.baseURL})
if err != nil {
ws.logger.Error("Unable to serve the index.html file", mlog.Err(err))
w.WriteHeader(500)
w.WriteHeader(http.StatusInternalServerError)
return
}
})
@ -115,7 +115,7 @@ func (ws *Server) Start() {
ws.logger.Info("http server started", mlog.Int("port", ws.port))
go func() {
if err := ws.ListenAndServe(); err != http.ErrServerClosed {
if err := ws.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
ws.logger.Fatal("ListenAndServeTLS", mlog.Err(err))
}
ws.logger.Info("http server stopped")

View File

@ -16,7 +16,7 @@ import (
"github.com/mattermost/focalboard/server/services/store"
)
// IsValidSessionToken authenticates session tokens
// IsValidSessionToken authenticates session tokens.
type IsValidSessionToken func(token string) bool
type Hub interface {
@ -36,20 +36,20 @@ type Server struct {
logger *mlog.Logger
}
// UpdateMsg is sent on block updates
// UpdateMsg is sent on block updates.
type UpdateMsg struct {
Action string `json:"action"`
Block model.Block `json:"block"`
}
// clusterUpdateMsg is sent on block updates
// clusterUpdateMsg is sent on block updates.
type clusterUpdateMsg struct {
UpdateMsg
BlockID string `json:"block_id"`
WorkspaceID string `json:"workspace_id"`
}
// ErrorMsg is sent on errors
// ErrorMsg is sent on errors.
type ErrorMsg struct {
Error string `json:"error"`
}
@ -219,7 +219,7 @@ func (ws *Server) getAuthenticatedWorkspaceID(wsSession *websocketSession, comma
workspaceID := command.WorkspaceID
if len(workspaceID) == 0 {
ws.logger.Error("getAuthenticatedWorkspaceID: No workspace")
return "", errors.New("No workspace")
return "", errors.New("no workspace")
}
container := store.Container{
@ -231,16 +231,16 @@ func (ws *Server) getAuthenticatedWorkspaceID(wsSession *websocketSession, comma
for _, blockID := range command.BlockIDs {
isValid, _ := ws.auth.IsValidReadToken(container, blockID, command.ReadToken)
if !isValid {
return "", errors.New("Invalid read token for workspace")
return "", errors.New("invalid read token for workspace")
}
}
return workspaceID, nil
}
return "", errors.New("No read token")
return "", errors.New("no read token")
}
// TODO: Refactor workspace hashing
// TODO: Refactor workspace hashing.
func makeItemID(workspaceID, blockID string) string {
return workspaceID + "-" + blockID
}
@ -283,7 +283,7 @@ func (ws *Server) removeListener(client *websocket.Conn) {
ws.mu.Unlock()
}
// removeListenerFromBlocks removes a webSocket listener from a set of block.
// removeListenerFromBlocks removes a webSocket listener from a set of blocks.
func (ws *Server) removeListenerFromBlocks(wsSession *websocketSession, command *WebsocketCommand) {
workspaceID, err := ws.getAuthenticatedWorkspaceID(wsSession, command)
if err != nil {
@ -345,15 +345,13 @@ func (ws *Server) SetHub(hub Hub) {
Block: msg.Block,
}
if listeners != nil {
for _, listener := range listeners {
log.Printf("Broadcast change, workspaceID: %s, blockID: %s, remoteAddr: %s", msg.WorkspaceID, msg.BlockID, listener.RemoteAddr())
for _, listener := range listeners {
log.Printf("Broadcast change, workspaceID: %s, blockID: %s, remoteAddr: %s", msg.WorkspaceID, msg.BlockID, listener.RemoteAddr())
err := listener.WriteJSON(message)
if err != nil {
log.Printf("broadcast error: %v", err)
listener.Close()
}
err := listener.WriteJSON(message)
if err != nil {
log.Printf("broadcast error: %v", err)
listener.Close()
}
}
})
@ -369,7 +367,7 @@ func (ws *Server) getListeners(workspaceID string, blockID string) []*websocket.
return listeners
}
// BroadcastBlockDelete broadcasts delete messages to clients
// BroadcastBlockDelete broadcasts delete messages to clients.
func (ws *Server) BroadcastBlockDelete(workspaceID, blockID, parentID string) {
now := time.Now().Unix()
block := model.Block{}
@ -381,7 +379,7 @@ func (ws *Server) BroadcastBlockDelete(workspaceID, blockID, parentID string) {
ws.BroadcastBlockChange(workspaceID, block)
}
// BroadcastBlockChange broadcasts update messages to clients
// BroadcastBlockChange broadcasts update messages to clients.
func (ws *Server) BroadcastBlockChange(workspaceID string, block model.Block) {
blockIDsToNotify := []string{block.ID, block.ParentID}
@ -404,19 +402,17 @@ func (ws *Server) BroadcastBlockChange(workspaceID string, block model.Block) {
ws.hub.SendWSMessage(data)
}
if listeners != nil {
for _, listener := range listeners {
ws.logger.Debug("Broadcast change",
mlog.String("workspaceID", workspaceID),
mlog.String("blockID", blockID),
mlog.Stringer("remoteAddr", listener.RemoteAddr()),
)
for _, listener := range listeners {
ws.logger.Debug("Broadcast change",
mlog.String("workspaceID", workspaceID),
mlog.String("blockID", blockID),
mlog.Stringer("remoteAddr", listener.RemoteAddr()),
)
err := listener.WriteJSON(message)
if err != nil {
ws.logger.Error("broadcast error", mlog.Err(err))
listener.Close()
}
err := listener.WriteJSON(message)
if err != nil {
ws.logger.Error("broadcast error", mlog.Err(err))
listener.Close()
}
}
}