Skip to content

Commit

Permalink
Force usage of utf8bm4 charset for user attribute values.
Browse files Browse the repository at this point in the history
  • Loading branch information
bsinou committed Apr 9, 2019
1 parent dbd4b9f commit d0469c6
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 27 deletions.
12 changes: 12 additions & 0 deletions common/dao/mysql.go
Expand Up @@ -26,6 +26,7 @@ import (
"sync"

mysqltools "github.com/go-sql-driver/mysql"
"github.com/micro/go-micro/errors"
)

var (
Expand Down Expand Up @@ -96,3 +97,14 @@ func (m *mysql) SetMaxConnectionsForWeight(num int) {
m.conn.SetMaxOpenConns(maxConns)
m.conn.SetMaxIdleConns(maxIdleConns)
}

// FilterDAOErrors hides sensitive information about the underlying table
// when we receive MySQLError.
func FilterDAOErrors(err error) error {
if err != nil {
if _, ok := err.(*mysqltools.MySQLError); ok {
err = errors.InternalServerError("dao.error", "DAO error received")
}
}
return err
}
4 changes: 2 additions & 2 deletions common/service/db.go
Expand Up @@ -31,7 +31,7 @@ import (
"github.com/pydio/cells/common/config"
"github.com/pydio/cells/common/dao"
"github.com/pydio/cells/common/log"
"github.com/pydio/cells/common/service/context"
servicecontext "github.com/pydio/cells/common/service/context"
)

func newDBProvider(service micro.Service) error {
Expand Down Expand Up @@ -96,7 +96,7 @@ func NewDAOHandlerWrapper(val dao.DAO) server.HandlerWrapper {
return func(h server.HandlerFunc) server.HandlerFunc {
return func(ctx context.Context, req server.Request, rsp interface{}) error {
ctx = servicecontext.WithDAO(ctx, val)
return h(ctx, req, rsp)
return dao.FilterDAOErrors(h(ctx, req, rsp))
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions idm/user/migrations/mysql/0.2.sql
@@ -0,0 +1,4 @@
-- +migrate Up
ALTER TABLE idm_user_attributes MODIFY value LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

-- +migrate Down
94 changes: 69 additions & 25 deletions idm/user/sql.go
Expand Up @@ -29,15 +29,15 @@ import (
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/any"
"github.com/micro/go-micro/errors"
"github.com/rubenv/sql-migrate"
migrate "github.com/rubenv/sql-migrate"
"go.uber.org/zap"

"github.com/pydio/cells/common"
"github.com/pydio/cells/common/auth"
"github.com/pydio/cells/common/log"
"github.com/pydio/cells/common/proto/idm"
"github.com/pydio/cells/common/proto/tree"
"github.com/pydio/cells/common/service/proto"
service "github.com/pydio/cells/common/service/proto"
"github.com/pydio/cells/common/sql"
"github.com/pydio/cells/common/sql/index"
"github.com/pydio/cells/common/sql/resources"
Expand Down Expand Up @@ -249,8 +249,7 @@ func (s *sqlimpl) Add(in interface{}) (interface{}, []*tree.Node, error) {
user.Uuid = foundOrCreatedNode.Uuid
}

// Remove existing attributes, replace with new ones
// TODO: should we put these two operations (delete / insert) inside a transaction?
// Remove existing attributes and roles, replace with new ones using a transaction
if user.GroupLabel != "" {
if user.Attributes == nil {
user.Attributes = make(map[string]string, 1)
Expand All @@ -262,54 +261,99 @@ func (s *sqlimpl) Add(in interface{}) (interface{}, []*tree.Node, error) {
}
user.Attributes[idm.UserAttrLabelLike] = user.Login
}
if stmt := s.GetStmt("DeleteAttributes"); stmt != nil {

if _, err := stmt.Exec(user.Uuid); err != nil {
return nil, createdNodes, err
// Use a transaction to perform update on the user
db := s.DB()

// Start a transaction
tx, errTx := db.BeginTx(context.Background(), nil)
if errTx != nil {
return nil, createdNodes, errTx
}

// Checking transaction went fine
defer func() {
if errTx != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()

// Insure we can retrieve all necessary prepared statements
delAttributes := s.GetStmt("DeleteAttributes")
if delAttributes == nil {
errTx = fmt.Errorf("Unknown statement")
return nil, createdNodes, errTx
}
addAttribute := s.GetStmt("AddAttribute")
if addAttribute == nil {
errTx = fmt.Errorf("Unknown statement")
return nil, createdNodes, errTx
}
delUserRoles := s.GetStmt("DeleteUserRoles")
if delUserRoles == nil {
errTx = fmt.Errorf("Unknown statement")
return nil, createdNodes, errTx
}
addUserRole := s.GetStmt("AddRole")
if addUserRole == nil {
errTx = fmt.Errorf("Unknown statement")
return nil, createdNodes, errTx
}

// Execute retrieved statements within the transaction
if stmt := tx.Stmt(delAttributes); stmt != nil {
defer stmt.Close()
if _, errTx = stmt.Exec(user.Uuid); errTx != nil {
return nil, createdNodes, errTx
}
} else {
return nil, createdNodes, fmt.Errorf("unknown statement")
return nil, createdNodes, fmt.Errorf("Empty statement")
}
for attr, val := range user.Attributes {
if stmt := s.GetStmt("AddAttribute"); stmt != nil {

if _, err := stmt.Exec(
for attr, val := range user.Attributes {
if stmt := tx.Stmt(addAttribute); stmt != nil {
defer stmt.Close()
if _, errTx = stmt.Exec(
user.Uuid,
attr,
val,
); err != nil {
return nil, createdNodes, err
); errTx != nil {
return nil, createdNodes, errTx
}
} else {
return nil, createdNodes, fmt.Errorf("unknown statement")
return nil, createdNodes, fmt.Errorf("Empty statement")
}
}

if stmt := s.GetStmt("DeleteUserRoles"); stmt != nil {

if _, err := stmt.Exec(user.Uuid); err != nil {
return nil, createdNodes, err
if stmt := tx.Stmt(delUserRoles); stmt != nil {
defer stmt.Close()
if _, errTx = stmt.Exec(user.Uuid); errTx != nil {
return nil, createdNodes, errTx
}
} else {
return nil, createdNodes, fmt.Errorf("unknown statement")
return nil, createdNodes, fmt.Errorf("Empty statement")
}

for _, role := range user.Roles {
if role.UserRole || role.GroupRole {
continue
}

if stmt := s.GetStmt("AddRole"); stmt != nil {

if _, err := stmt.Exec(
if stmt := tx.Stmt(addUserRole); stmt != nil {
defer stmt.Close()
if _, errTx = stmt.Exec(
user.Uuid,
role.Uuid,
); err != nil {
return nil, createdNodes, err
); errTx != nil {
return nil, createdNodes, errTx
}
} else {
return nil, createdNodes, fmt.Errorf("unknown statement")
return nil, createdNodes, fmt.Errorf("Empty statement")
}
}

for _, n := range created {
createdNodes = append(createdNodes, n.Node)
}
Expand Down

0 comments on commit d0469c6

Please sign in to comment.