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

     1  // Copyright (c) 2018-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  
    15  	"github.com/xzl8028/xenia-server/model"
    16  	"github.com/xzl8028/xenia-server/store"
    17  )
    18  
    19  func initSqlSupplierSchemes(sqlStore SqlStore) {
    20  	for _, db := range sqlStore.GetAllConns() {
    21  		table := db.AddTableWithName(model.Scheme{}, "Schemes").SetKeys(false, "Id")
    22  		table.ColMap("Id").SetMaxSize(26)
    23  		table.ColMap("Name").SetMaxSize(model.SCHEME_NAME_MAX_LENGTH).SetUnique(true)
    24  		table.ColMap("DisplayName").SetMaxSize(model.SCHEME_DISPLAY_NAME_MAX_LENGTH)
    25  		table.ColMap("Description").SetMaxSize(model.SCHEME_DESCRIPTION_MAX_LENGTH)
    26  		table.ColMap("Scope").SetMaxSize(32)
    27  		table.ColMap("DefaultTeamAdminRole").SetMaxSize(64)
    28  		table.ColMap("DefaultTeamUserRole").SetMaxSize(64)
    29  		table.ColMap("DefaultTeamGuestRole").SetMaxSize(64)
    30  		table.ColMap("DefaultChannelAdminRole").SetMaxSize(64)
    31  		table.ColMap("DefaultChannelUserRole").SetMaxSize(64)
    32  		table.ColMap("DefaultChannelGuestRole").SetMaxSize(64)
    33  	}
    34  }
    35  
    36  func (s *SqlSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
    37  	result := store.NewSupplierResult()
    38  
    39  	if len(scheme.Id) == 0 {
    40  		if transaction, err := s.GetMaster().Begin(); err != nil {
    41  			result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
    42  		} else {
    43  			defer finalizeTransaction(transaction)
    44  			result = s.createScheme(ctx, scheme, transaction, hints...)
    45  
    46  			if result.Err == nil {
    47  				if err := transaction.Commit(); err != nil {
    48  					result.Err = model.NewAppError("SqlSchemeStore.SchemeSave", "store.sql_scheme.save_scheme.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
    49  				}
    50  			}
    51  		}
    52  	} else {
    53  		if !scheme.IsValid() {
    54  			result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "schemeId="+scheme.Id, http.StatusBadRequest)
    55  			return result
    56  		}
    57  
    58  		scheme.UpdateAt = model.GetMillis()
    59  
    60  		if rowsChanged, err := s.GetMaster().Update(scheme); err != nil {
    61  			result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, err.Error(), http.StatusInternalServerError)
    62  		} else if rowsChanged != 1 {
    63  			result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, "no record to update", http.StatusInternalServerError)
    64  		}
    65  
    66  		result.Data = scheme
    67  	}
    68  
    69  	return result
    70  }
    71  
    72  func (s *SqlSupplier) createScheme(ctx context.Context, scheme *model.Scheme, transaction *gorp.Transaction, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
    73  	result := store.NewSupplierResult()
    74  
    75  	// Fetch the default system scheme roles to populate default permissions.
    76  	defaultRoleNames := []string{model.TEAM_ADMIN_ROLE_ID, model.TEAM_USER_ROLE_ID, model.TEAM_GUEST_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, model.CHANNEL_USER_ROLE_ID, model.CHANNEL_GUEST_ROLE_ID}
    77  	defaultRoles := make(map[string]*model.Role)
    78  	roles, err := s.RoleGetByNames(ctx, defaultRoleNames)
    79  	if err != nil {
    80  		result.Err = err
    81  		return result
    82  	}
    83  
    84  	for _, role := range roles {
    85  		switch role.Name {
    86  		case model.TEAM_ADMIN_ROLE_ID:
    87  			defaultRoles[model.TEAM_ADMIN_ROLE_ID] = role
    88  		case model.TEAM_USER_ROLE_ID:
    89  			defaultRoles[model.TEAM_USER_ROLE_ID] = role
    90  		case model.TEAM_GUEST_ROLE_ID:
    91  			defaultRoles[model.TEAM_GUEST_ROLE_ID] = role
    92  		case model.CHANNEL_ADMIN_ROLE_ID:
    93  			defaultRoles[model.CHANNEL_ADMIN_ROLE_ID] = role
    94  		case model.CHANNEL_USER_ROLE_ID:
    95  			defaultRoles[model.CHANNEL_USER_ROLE_ID] = role
    96  		case model.CHANNEL_GUEST_ROLE_ID:
    97  			defaultRoles[model.CHANNEL_GUEST_ROLE_ID] = role
    98  		}
    99  	}
   100  
   101  	if len(defaultRoles) != 6 {
   102  		result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.retrieve_default_scheme_roles.app_error", nil, "", http.StatusInternalServerError)
   103  		return result
   104  	}
   105  
   106  	// Create the appropriate default roles for the scheme.
   107  	if scheme.Scope == model.SCHEME_SCOPE_TEAM {
   108  		// Team Admin Role
   109  		teamAdminRole := &model.Role{
   110  			Name:          model.NewId(),
   111  			DisplayName:   fmt.Sprintf("Team Admin Role for Scheme %s", scheme.Name),
   112  			Permissions:   defaultRoles[model.TEAM_ADMIN_ROLE_ID].Permissions,
   113  			SchemeManaged: true,
   114  		}
   115  
   116  		if savedRole, err := s.createRole(ctx, teamAdminRole, transaction); err != nil {
   117  			result.Err = err
   118  			return result
   119  		} else {
   120  			scheme.DefaultTeamAdminRole = savedRole.Name
   121  		}
   122  
   123  		// Team User Role
   124  		teamUserRole := &model.Role{
   125  			Name:          model.NewId(),
   126  			DisplayName:   fmt.Sprintf("Team User Role for Scheme %s", scheme.Name),
   127  			Permissions:   defaultRoles[model.TEAM_USER_ROLE_ID].Permissions,
   128  			SchemeManaged: true,
   129  		}
   130  
   131  		if savedRole, err := s.createRole(ctx, teamUserRole, transaction); err != nil {
   132  			result.Err = err
   133  			return result
   134  		} else {
   135  			scheme.DefaultTeamUserRole = savedRole.Name
   136  		}
   137  
   138  		// Team Guest Role
   139  		teamGuestRole := &model.Role{
   140  			Name:          model.NewId(),
   141  			DisplayName:   fmt.Sprintf("Team Guest Role for Scheme %s", scheme.Name),
   142  			Permissions:   defaultRoles[model.TEAM_GUEST_ROLE_ID].Permissions,
   143  			SchemeManaged: true,
   144  		}
   145  
   146  		if savedRole, err := s.createRole(ctx, teamGuestRole, transaction); err != nil {
   147  			result.Err = err
   148  			return result
   149  		} else {
   150  			scheme.DefaultTeamGuestRole = savedRole.Name
   151  		}
   152  	}
   153  	if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   154  		// Channel Admin Role
   155  		channelAdminRole := &model.Role{
   156  			Name:          model.NewId(),
   157  			DisplayName:   fmt.Sprintf("Channel Admin Role for Scheme %s", scheme.Name),
   158  			Permissions:   defaultRoles[model.CHANNEL_ADMIN_ROLE_ID].Permissions,
   159  			SchemeManaged: true,
   160  		}
   161  
   162  		if savedRole, err := s.createRole(ctx, channelAdminRole, transaction); err != nil {
   163  			result.Err = err
   164  			return result
   165  		} else {
   166  			scheme.DefaultChannelAdminRole = savedRole.Name
   167  		}
   168  
   169  		// Channel User Role
   170  		channelUserRole := &model.Role{
   171  			Name:          model.NewId(),
   172  			DisplayName:   fmt.Sprintf("Channel User Role for Scheme %s", scheme.Name),
   173  			Permissions:   defaultRoles[model.CHANNEL_USER_ROLE_ID].Permissions,
   174  			SchemeManaged: true,
   175  		}
   176  
   177  		if savedRole, err := s.createRole(ctx, channelUserRole, transaction); err != nil {
   178  			result.Err = err
   179  			return result
   180  		} else {
   181  			scheme.DefaultChannelUserRole = savedRole.Name
   182  		}
   183  
   184  		// Channel Guest Role
   185  		channelGuestRole := &model.Role{
   186  			Name:          model.NewId(),
   187  			DisplayName:   fmt.Sprintf("Channel Guest Role for Scheme %s", scheme.Name),
   188  			Permissions:   defaultRoles[model.CHANNEL_GUEST_ROLE_ID].Permissions,
   189  			SchemeManaged: true,
   190  		}
   191  
   192  		if savedRole, err := s.createRole(ctx, channelGuestRole, transaction); err != nil {
   193  			result.Err = err
   194  			return result
   195  		} else {
   196  			scheme.DefaultChannelGuestRole = savedRole.Name
   197  		}
   198  	}
   199  
   200  	scheme.Id = model.NewId()
   201  	if len(scheme.Name) == 0 {
   202  		scheme.Name = model.NewId()
   203  	}
   204  	scheme.CreateAt = model.GetMillis()
   205  	scheme.UpdateAt = scheme.CreateAt
   206  
   207  	// Validate the scheme
   208  	if !scheme.IsValidForCreate() {
   209  		result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest)
   210  		return result
   211  	}
   212  
   213  	if err := transaction.Insert(scheme); err != nil {
   214  		result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError)
   215  	}
   216  
   217  	result.Data = scheme
   218  
   219  	return result
   220  }
   221  
   222  func (s *SqlSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
   223  	result := store.NewSupplierResult()
   224  
   225  	var scheme model.Scheme
   226  
   227  	if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil {
   228  		if err == sql.ErrNoRows {
   229  			result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound)
   230  		} else {
   231  			result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   232  		}
   233  	}
   234  
   235  	result.Data = &scheme
   236  
   237  	return result
   238  }
   239  
   240  func (s *SqlSupplier) SchemeGetByName(ctx context.Context, schemeName string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
   241  	result := store.NewSupplierResult()
   242  
   243  	var scheme model.Scheme
   244  
   245  	if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Name = :Name", map[string]interface{}{"Name": schemeName}); err != nil {
   246  		if err == sql.ErrNoRows {
   247  			result.Err = model.NewAppError("SqlSchemeStore.GetByName", "store.sql_scheme.get.app_error", nil, "Name="+schemeName+", "+err.Error(), http.StatusNotFound)
   248  		} else {
   249  			result.Err = model.NewAppError("SqlSchemeStore.GetByName", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   250  		}
   251  	}
   252  
   253  	result.Data = &scheme
   254  
   255  	return result
   256  }
   257  
   258  func (s *SqlSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
   259  	result := store.NewSupplierResult()
   260  
   261  	// Get the scheme
   262  	var scheme model.Scheme
   263  	if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil {
   264  		if err == sql.ErrNoRows {
   265  			result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound)
   266  		} else {
   267  			result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
   268  		}
   269  
   270  		return result
   271  	}
   272  
   273  	// Update any teams or channels using this scheme to the default scheme.
   274  	if scheme.Scope == model.SCHEME_SCOPE_TEAM {
   275  		if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil {
   276  			result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.reset_teams.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
   277  			return result
   278  		}
   279  	} else if scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   280  		if _, err := s.GetMaster().Exec("UPDATE Channels SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil {
   281  			result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.reset_channels.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
   282  			return result
   283  		}
   284  
   285  		// Blow away the channel caches.
   286  		s.Channel().ClearCaches()
   287  	}
   288  
   289  	// Delete the roles belonging to the scheme.
   290  	roleNames := []string{scheme.DefaultChannelGuestRole, scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole}
   291  	if scheme.Scope == model.SCHEME_SCOPE_TEAM {
   292  		roleNames = append(roleNames, scheme.DefaultTeamGuestRole, scheme.DefaultTeamUserRole, scheme.DefaultTeamAdminRole)
   293  	}
   294  
   295  	var inQueryList []string
   296  	queryArgs := make(map[string]interface{})
   297  	for i, roleId := range roleNames {
   298  		inQueryList = append(inQueryList, fmt.Sprintf(":RoleName%v", i))
   299  		queryArgs[fmt.Sprintf("RoleName%v", i)] = roleId
   300  	}
   301  	inQuery := strings.Join(inQueryList, ", ")
   302  
   303  	time := model.GetMillis()
   304  	queryArgs["UpdateAt"] = time
   305  	queryArgs["DeleteAt"] = time
   306  
   307  	if _, err := s.GetMaster().Exec("UPDATE Roles SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt WHERE Name IN ("+inQuery+")", queryArgs); err != nil {
   308  		result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.role_update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
   309  		return result
   310  	}
   311  
   312  	// Delete the scheme itself.
   313  	scheme.UpdateAt = time
   314  	scheme.DeleteAt = time
   315  
   316  	if rowsChanged, err := s.GetMaster().Update(&scheme); err != nil {
   317  		result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
   318  	} else if rowsChanged != 1 {
   319  		result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "no record to update", http.StatusInternalServerError)
   320  	} else {
   321  		result.Data = &scheme
   322  	}
   323  
   324  	return result
   325  }
   326  
   327  func (s *SqlSupplier) SchemeGetAllPage(ctx context.Context, scope string, offset int, limit int, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
   328  	result := store.NewSupplierResult()
   329  
   330  	var schemes []*model.Scheme
   331  
   332  	scopeClause := ""
   333  	if len(scope) > 0 {
   334  		scopeClause = " AND Scope=:Scope "
   335  	}
   336  
   337  	if _, err := s.GetReplica().Select(&schemes, "SELECT * from Schemes WHERE DeleteAt = 0 "+scopeClause+" ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Limit": limit, "Offset": offset, "Scope": scope}); err != nil {
   338  		result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   339  	}
   340  
   341  	result.Data = schemes
   342  
   343  	return result
   344  }
   345  
   346  func (s *SqlSupplier) SchemePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
   347  	result := store.NewSupplierResult()
   348  
   349  	if _, err := s.GetMaster().Exec("DELETE from Schemes"); err != nil {
   350  		result.Err = model.NewAppError("SqlSchemeStore.PermanentDeleteAll", "store.sql_scheme.permanent_delete_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   351  	}
   352  
   353  	return result
   354  }