github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/sqlstore/role_supplier.go (about)

     1  // Copyright (c) 2017-present Xenia, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package sqlstore
     5  
     6  import (
     7  	"context"
     8  	"database/sql"
     9  	"fmt"
    10  	"net/http"
    11  	"strings"
    12  
    13  	"github.com/xzl8028/gorp"
    14  	"github.com/xzl8028/xenia-server/model"
    15  	"github.com/xzl8028/xenia-server/store"
    16  )
    17  
    18  type Role struct {
    19  	Id            string
    20  	Name          string
    21  	DisplayName   string
    22  	Description   string
    23  	CreateAt      int64
    24  	UpdateAt      int64
    25  	DeleteAt      int64
    26  	Permissions   string
    27  	SchemeManaged bool
    28  	BuiltIn       bool
    29  }
    30  
    31  func NewRoleFromModel(role *model.Role) *Role {
    32  	permissionsMap := make(map[string]bool)
    33  	permissions := ""
    34  
    35  	for _, permission := range role.Permissions {
    36  		if !permissionsMap[permission] {
    37  			permissions += fmt.Sprintf(" %v", permission)
    38  			permissionsMap[permission] = true
    39  		}
    40  	}
    41  
    42  	return &Role{
    43  		Id:            role.Id,
    44  		Name:          role.Name,
    45  		DisplayName:   role.DisplayName,
    46  		Description:   role.Description,
    47  		CreateAt:      role.CreateAt,
    48  		UpdateAt:      role.UpdateAt,
    49  		DeleteAt:      role.DeleteAt,
    50  		Permissions:   permissions,
    51  		SchemeManaged: role.SchemeManaged,
    52  		BuiltIn:       role.BuiltIn,
    53  	}
    54  }
    55  
    56  func (role Role) ToModel() *model.Role {
    57  	return &model.Role{
    58  		Id:            role.Id,
    59  		Name:          role.Name,
    60  		DisplayName:   role.DisplayName,
    61  		Description:   role.Description,
    62  		CreateAt:      role.CreateAt,
    63  		UpdateAt:      role.UpdateAt,
    64  		DeleteAt:      role.DeleteAt,
    65  		Permissions:   strings.Fields(role.Permissions),
    66  		SchemeManaged: role.SchemeManaged,
    67  		BuiltIn:       role.BuiltIn,
    68  	}
    69  }
    70  
    71  func initSqlSupplierRoles(sqlStore SqlStore) {
    72  	for _, db := range sqlStore.GetAllConns() {
    73  		table := db.AddTableWithName(Role{}, "Roles").SetKeys(false, "Id")
    74  		table.ColMap("Id").SetMaxSize(26)
    75  		table.ColMap("Name").SetMaxSize(64).SetUnique(true)
    76  		table.ColMap("DisplayName").SetMaxSize(128)
    77  		table.ColMap("Description").SetMaxSize(1024)
    78  		table.ColMap("Permissions").SetMaxSize(4096)
    79  	}
    80  }
    81  
    82  func (s *SqlSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...store.LayeredStoreHint) (*model.Role, *model.AppError) {
    83  	// Check the role is valid before proceeding.
    84  	if !role.IsValidWithoutId() {
    85  		return nil, model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.invalid_role.app_error", nil, "", http.StatusBadRequest)
    86  	}
    87  
    88  	if len(role.Id) == 0 {
    89  		transaction, err := s.GetMaster().Begin()
    90  		if err != nil {
    91  			return nil, model.NewAppError("SqlRoleStore.RoleSave", "store.sql_role.save.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
    92  		}
    93  		defer finalizeTransaction(transaction)
    94  		createdRole, appErr := s.createRole(ctx, role, transaction, hints...)
    95  		if appErr != nil {
    96  			transaction.Rollback()
    97  			return nil, appErr
    98  		} else if err := transaction.Commit(); err != nil {
    99  			return nil, model.NewAppError("SqlRoleStore.RoleSave", "store.sql_role.save_role.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
   100  		}
   101  		return createdRole, nil
   102  	}
   103  
   104  	dbRole := NewRoleFromModel(role)
   105  	dbRole.UpdateAt = model.GetMillis()
   106  	if rowsChanged, err := s.GetMaster().Update(dbRole); err != nil {
   107  		return nil, model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, err.Error(), http.StatusInternalServerError)
   108  	} else if rowsChanged != 1 {
   109  		return nil, model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, "no record to update", http.StatusInternalServerError)
   110  	}
   111  
   112  	return dbRole.ToModel(), nil
   113  }
   114  
   115  func (s *SqlSupplier) createRole(ctx context.Context, role *model.Role, transaction *gorp.Transaction, hints ...store.LayeredStoreHint) (*model.Role, *model.AppError) {
   116  	// Check the role is valid before proceeding.
   117  	if !role.IsValidWithoutId() {
   118  		return nil, model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.invalid_role.app_error", nil, "", http.StatusBadRequest)
   119  	}
   120  
   121  	dbRole := NewRoleFromModel(role)
   122  
   123  	dbRole.Id = model.NewId()
   124  	dbRole.CreateAt = model.GetMillis()
   125  	dbRole.UpdateAt = dbRole.CreateAt
   126  
   127  	if err := transaction.Insert(dbRole); err != nil {
   128  		return nil, model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError)
   129  	}
   130  
   131  	return dbRole.ToModel(), nil
   132  }
   133  
   134  func (s *SqlSupplier) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) (*model.Role, *model.AppError) {
   135  	var dbRole Role
   136  
   137  	if err := s.GetReplica().SelectOne(&dbRole, "SELECT * from Roles WHERE Id = :Id", map[string]interface{}{"Id": roleId}); err != nil {
   138  		if err == sql.ErrNoRows {
   139  			return nil, model.NewAppError("SqlRoleStore.Get", "store.sql_role.get.app_error", nil, "Id="+roleId+", "+err.Error(), http.StatusNotFound)
   140  		}
   141  		return nil, model.NewAppError("SqlRoleStore.Get", "store.sql_role.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   142  	}
   143  
   144  	return dbRole.ToModel(), nil
   145  }
   146  
   147  func (s *SqlSupplier) RoleGetAll(ctx context.Context, hints ...store.LayeredStoreHint) ([]*model.Role, *model.AppError) {
   148  	var dbRoles []Role
   149  
   150  	if _, err := s.GetReplica().Select(&dbRoles, "SELECT * from Roles", map[string]interface{}{}); err != nil {
   151  		if err == sql.ErrNoRows {
   152  			return nil, model.NewAppError("SqlRoleStore.GetAll", "store.sql_role.get_all.app_error", nil, err.Error(), http.StatusNotFound)
   153  		}
   154  		return nil, model.NewAppError("SqlRoleStore.GetAll", "store.sql_role.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   155  	}
   156  
   157  	var roles []*model.Role
   158  	for _, dbRole := range dbRoles {
   159  		roles = append(roles, dbRole.ToModel())
   160  	}
   161  	return roles, nil
   162  }
   163  
   164  func (s *SqlSupplier) RoleGetByName(ctx context.Context, name string, hints ...store.LayeredStoreHint) (*model.Role, *model.AppError) {
   165  	var dbRole Role
   166  
   167  	if err := s.GetReplica().SelectOne(&dbRole, "SELECT * from Roles WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil {
   168  		if err == sql.ErrNoRows {
   169  			return nil, model.NewAppError("SqlRoleStore.GetByName", "store.sql_role.get_by_name.app_error", nil, "name="+name+",err="+err.Error(), http.StatusNotFound)
   170  		}
   171  		return nil, model.NewAppError("SqlRoleStore.GetByName", "store.sql_role.get_by_name.app_error", nil, "name="+name+",err="+err.Error(), http.StatusInternalServerError)
   172  	}
   173  
   174  	return dbRole.ToModel(), nil
   175  }
   176  
   177  func (s *SqlSupplier) RoleGetByNames(ctx context.Context, names []string, hints ...store.LayeredStoreHint) ([]*model.Role, *model.AppError) {
   178  	var dbRoles []*Role
   179  
   180  	if len(names) == 0 {
   181  		return []*model.Role{}, nil
   182  	}
   183  
   184  	var searchPlaceholders []string
   185  	var parameters = map[string]interface{}{}
   186  	for i, value := range names {
   187  		searchPlaceholders = append(searchPlaceholders, fmt.Sprintf(":Name%d", i))
   188  		parameters[fmt.Sprintf("Name%d", i)] = value
   189  	}
   190  
   191  	searchTerm := "Name IN (" + strings.Join(searchPlaceholders, ", ") + ")"
   192  
   193  	if _, err := s.GetReplica().Select(&dbRoles, "SELECT * from Roles WHERE "+searchTerm, parameters); err != nil {
   194  		return nil, model.NewAppError("SqlRoleStore.GetByNames", "store.sql_role.get_by_names.app_error", nil, err.Error(), http.StatusInternalServerError)
   195  	}
   196  
   197  	var roles []*model.Role
   198  	for _, dbRole := range dbRoles {
   199  		roles = append(roles, dbRole.ToModel())
   200  	}
   201  
   202  	return roles, nil
   203  }
   204  
   205  func (s *SqlSupplier) RoleDelete(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) (*model.Role, *model.AppError) {
   206  	// Get the role.
   207  	var role *Role
   208  	if err := s.GetReplica().SelectOne(&role, "SELECT * from Roles WHERE Id = :Id", map[string]interface{}{"Id": roleId}); err != nil {
   209  		if err == sql.ErrNoRows {
   210  			return nil, model.NewAppError("SqlRoleStore.Delete", "store.sql_role.get.app_error", nil, "Id="+roleId+", "+err.Error(), http.StatusNotFound)
   211  		}
   212  		return nil, model.NewAppError("SqlRoleStore.Delete", "store.sql_role.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   213  	}
   214  
   215  	time := model.GetMillis()
   216  	role.DeleteAt = time
   217  	role.UpdateAt = time
   218  
   219  	if rowsChanged, err := s.GetMaster().Update(role); err != nil {
   220  		return nil, model.NewAppError("SqlRoleStore.Delete", "store.sql_role.delete.update.app_error", nil, err.Error(), http.StatusInternalServerError)
   221  	} else if rowsChanged != 1 {
   222  		return nil, model.NewAppError("SqlRoleStore.Delete", "store.sql_role.delete.update.app_error", nil, "no record to update", http.StatusInternalServerError)
   223  	}
   224  	return role.ToModel(), nil
   225  }
   226  
   227  func (s *SqlSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *model.AppError {
   228  	if _, err := s.GetMaster().Exec("DELETE FROM Roles"); err != nil {
   229  		return model.NewAppError("SqlRoleStore.PermanentDeleteAll", "store.sql_role.permanent_delete_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   230  	}
   231  
   232  	return nil
   233  }