在事务中创建用户

如何解决在事务中创建用户

当像这样创建用户时:

using var trans = Db.BeginTransaction();
AuthRepository.CreateUserAuth(newUser,request.Password);
AuthRepository.AssignRoles(created,new List<string> { request.role });
//.. do other stuff
throw new Exception("other code may throw this");
trans.Commit();

Auth 存储库有自己的连接,因此它不是交易的一部分。这意味着,如果我的代码失效,我最终会遇到一个不受欢迎的用户。

有什么办法可以通过 AuthRepository 使用事务,还是只能手动写入用户和角色表?手动保存时找不到在文档中创建密码哈希的示例,有示例吗?

解决方法

您不能在事务中使用现有的 Auth Repository API,因为每个 API 都使用自己的数据库连接。

如果您愿意,您可以在 OrmLiteAuthRepository.cs 中实现那些 OrmLite Auth Respository API,并将它们移动到您的方法中,以便它们都使用相同的数据库连接 + 事务。

另请注意,要使用 Transactions in OrmLite,您应该使用 OpenTransaction(),例如:

using (var dbTrans = db.OpenTransaction())
{
}
,

添加我在这里使用的类,以防它根据需要帮助任何人进行一些重构:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using OutReachPete.ServiceModel.User;
using ServiceStack;
using ServiceStack.Auth;
using ServiceStack.OrmLite;

namespace OutReachPete.ServiceInterface.User
{
    public class UserHelper
    {
        public static bool ForceCaseInsensitiveUserNameSearch { get; set; } = true;
        public static bool UseDistinctRoleTables { get; set; } = true;

        public static UserAuthCustom CreateUserAuth(UserAuthCustom newUser,string password,IDbConnection db)
        {
            newUser.ValidateNewUser(password);

            AssertNoExistingUser(db,newUser);

            newUser.PopulatePasswordHashes(password);
            newUser.CreatedDate = DateTime.UtcNow;
            newUser.ModifiedDate = newUser.CreatedDate;

            db.Save(newUser);

            newUser = db.SingleById<UserAuthCustom>(newUser.Id);

            return newUser;
        }

        public static void AssertNoExistingUser(IDbConnection db,IUserAuth newUser,IUserAuth exceptForExistingUser = null)
        {
            if (newUser.UserName != null)
            {
                var existingUser = GetUserAuthByUserName(db,newUser.UserName);
                if (existingUser != null
                    && (exceptForExistingUser == null || existingUser.Id != exceptForExistingUser.Id))
                    throw new ArgumentException(string.Format(ErrorMessages.UserAlreadyExistsTemplate1,newUser.UserName.SafeInput()));
            }

            if (newUser.Email != null)
            {
                var existingUser = GetUserAuthByUserName(db,newUser.Email);
                if (existingUser != null
                    && (exceptForExistingUser == null || existingUser.Id != exceptForExistingUser.Id))
                    throw new ArgumentException(string.Format(ErrorMessages.EmailAlreadyExistsTemplate1,newUser.Email.SafeInput()));
            }
        }

        public static UserAuthCustom GetUserAuthByUserName(IDbConnection db,string userNameOrEmail)
        {
            var isEmail = userNameOrEmail.Contains("@");
            var lowerUserName = userNameOrEmail.ToLower();

            UserAuthCustom userAuth = null;

            // Usernames/Emails are saved in Lower Case so we can do an exact search using lowerUserName
            if (HostContext.GetPlugin<AuthFeature>()?.SaveUserNamesInLowerCase == true)
            {
                return isEmail
                    ? db.Select<UserAuthCustom>(q => q.Email == lowerUserName).FirstOrDefault()
                    : db.Select<UserAuthCustom>(q => q.UserName == lowerUserName).FirstOrDefault();
            }

            // Try an exact search using index first
            userAuth = isEmail
                ? db.Select<UserAuthCustom>(q => q.Email == userNameOrEmail).FirstOrDefault()
                : db.Select<UserAuthCustom>(q => q.UserName == userNameOrEmail).FirstOrDefault();

            if (userAuth != null)
                return userAuth;

            // Fallback to a non-index search if no exact match is found
            if (ForceCaseInsensitiveUserNameSearch)
            {
                userAuth = isEmail
                    ? db.Select<UserAuthCustom>(q => q.Email.ToLower() == lowerUserName).FirstOrDefault()
                    : db.Select<UserAuthCustom>(q => q.UserName.ToLower() == lowerUserName).FirstOrDefault();
            }

            return userAuth;
        }

        public static void AssignRoles(IAuthRepository userAuthRepo,IUserAuth userAuth,IDbConnection db,ICollection<string> roles = null,ICollection<string> permissions = null)
        {
            if (userAuthRepo is IManageRoles managesRoles)
            {
                AssignRoles(userAuth.Id.ToString(),db,roles,permissions);
            }
            else
            {
                AssignRolesInternal(userAuth,permissions);

                SaveUserAuth(userAuth,db);
            }
        }

        public static IUserAuth GetUserAuth(string userAuthId,IDbConnection db)
        {
            if (string.IsNullOrEmpty(userAuthId))
                throw new ArgumentNullException(nameof(userAuthId));

            return db.SingleById<UserAuthCustom>(int.Parse(userAuthId));
        }

        public static void AssignRoles(string userAuthId,ICollection<string> permissions = null)
        {
            var userAuth = GetUserAuth(userAuthId,db);
            if (!UseDistinctRoleTables)
            {
                if (!roles.IsEmpty())
                {
                    foreach (var missingRole in roles.Where(x => userAuth.Roles == null || !userAuth.Roles.Contains(x)))
                    {
                        if (userAuth.Roles == null)
                            userAuth.Roles = new List<string>();

                        userAuth.Roles.Add(missingRole);
                    }
                }

                if (!permissions.IsEmpty())
                {
                    foreach (var missingPermission in permissions.Where(x => userAuth.Permissions == null || !userAuth.Permissions.Contains(x)))
                    {
                        if (userAuth.Permissions == null)
                            userAuth.Permissions = new List<string>();

                        userAuth.Permissions.Add(missingPermission);
                    }
                }

                SaveUserAuth(userAuth,db);
            }
            else
            {

                var now = DateTime.UtcNow;
                var userRoles = db.Select<UserAuthRole>(q => q.UserAuthId == userAuth.Id);

                if (!roles.IsEmpty())
                {
                    var roleSet = userRoles.Where(x => x.Role != null).Select(x => x.Role).ToHashSet();
                    foreach (var role in roles)
                    {
                        if (!roleSet.Contains(role))
                        {
                            db.Insert(new UserAuthRole
                            {
                                UserAuthId = userAuth.Id,Role = role,CreatedDate = now,ModifiedDate = now,});
                        }
                    }
                }

                if (!permissions.IsEmpty())
                {
                    var permissionSet = userRoles.Where(x => x.Permission != null).Select(x => x.Permission).ToHashSet();
                    foreach (var permission in permissions)
                    {
                        if (!permissionSet.Contains(permission))
                        {
                            db.Insert(new UserAuthRole
                            {
                                UserAuthId = userAuth.Id,Permission = permission,});
                        }
                    }
                }

            }
        }

        private static void AssignRolesInternal(IUserAuth userAuth,ICollection<string> roles,ICollection<string> permissions)
        {
            if (!roles.IsEmpty())
            {
                foreach (var missingRole in roles.Where(x => userAuth.Roles == null || !userAuth.Roles.Contains(x)))
                {
                    if (userAuth.Roles == null)
                        userAuth.Roles = new List<string>();

                    userAuth.Roles.Add(missingRole);
                }
            }

            if (!permissions.IsEmpty())
            {
                foreach (var missingPermission in permissions.Where(x =>
                    userAuth.Permissions == null || !userAuth.Permissions.Contains(x)))
                {
                    if (userAuth.Permissions == null)
                        userAuth.Permissions = new List<string>();

                    userAuth.Permissions.Add(missingPermission);
                }
            }
        }

        public static void SaveUserAuth(IUserAuth userAuth,IDbConnection db)
        {
            if (userAuth == null)
                throw new ArgumentNullException(nameof(userAuth));

            userAuth.ModifiedDate = DateTime.UtcNow;
            if (userAuth.CreatedDate == default(DateTime))
                userAuth.CreatedDate = userAuth.ModifiedDate;
            
            db.Save((UserAuthCustom)userAuth);
            
        }

    }
}

然后就这样称呼它:

var created = UserHelper.CreateUserAuth(newUser,request.Password,Db);

UserHelper.AssignRoles(AuthRepository,created,Db,new List<string> { request.CreateUserType.ToString() });

它只会使用通过的连接。只需将 UserAuthCustom 更改为您的用户类别即可。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-