jira,wiki批量修改登录用户名

前言

jira对接统一单点登录后,因为cas的登录账号和jira原来的登录账号不一致,所以通过cas登录后,jira中根据登录账号获取用户信息时也会获取失败,而不会登录到jira系统中。所以需要保证jira账号和cas账号的一致,crowd后台可以直接修改登录账号,但没法批量修改,只能单条一一修改,工作量比较大,所以现在想直接从库里面统一修改jira的登录账号从英文名修改成邮箱。

1、修改jira日志级别
1.1 观察数据同步日志

首先我找到了crowd的用户表是cwd_user表,里面user_name,lower_user_name记录的就是登录账号,同时jira库中cwd_user表信息是crowd cwd_user表同步过来的用户信息。但我单独修改了crowd库中cwd_user表的user_name,lower_user字段信息后,手动登录jira后台执行同步程序后,jira cwd_user表的信息没有同步过来,在Jira后台也无法修改这个用户信息,所以我恢复了原始数据。
然后我打开jira的sql 日志,想通过观察日志来查看jira同步时都修改了哪些表,jira日志目录如下:
/opt/atlassian/jira/atlassian-jira/WEB-INF/classes/log4j.properties
设置LoggingSQLInterceptor = ON
LoggingSQLInterceptor =true


#####################################################
# SQL logs
#####################################################
#
# Beware of turning this log level on.  At INFO level it will log every SQL statement
# and at DEBUG level it will also log the calling stack trace.  Turning this on will DEGRADE your
# JIRA database throughput.
#
log4j.logger.com.atlassian.jira.ofbiz.LoggingSQLInterceptor = ON, sqllog
log4j.additivity.com.atlassian.jira.ofbiz.LoggingSQLInterceptor = true

打开日志后,我在crowd后台修改了登录名,然后 执行同步程序,观察如下:
中文部分是我自己的注释

开始扫描删除的用户, 扫描新增或更新的用户:

2019-04-03 16:30:05,868 atlassian-scheduler-quartz1.clustered_Worker-2 INFO      [atlassian.jira.ofbiz.LoggingSQLInterceptor] 1ms Connection returned. borrowed : 0
2019-04-03 16:30:05,869 atlassian-scheduler-quartz1.clustered_Worker-2 INFO      [atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleted [ 13 ] users in [ 83ms ]
2019-04-03 16:30:05,869 atlassian-scheduler-quartz1.clustered_Worker-2 INFO      [atlassian.crowd.directory.DbCachingRemoteChangeOperations] scanned for deleted users in [ 101ms ]
2019-04-03 16:30:05,870 atlassian-scheduler-quartz1.clustered_Worker-2 INFO      [atlassian.crowd.directory.DbCachingRemoteChangeOperations] scanning [ 1066 ] users to add or update

#扫描并比较:
2019-04-03 16:30:05,872 atlassian-scheduler-quartz1.clustered_Worker-2 INFO      [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] scanned and compared [ 1066 ] users for update in DB cache in [ 3ms ]


#根据crowd  cwd_user表的external_id 查 jira crowd表里面的唯一数据: 修改前的值
SELECT ID, directory_id, user_name, active, created_date, updated_date, first_name, last_name, display_name, email_address, EXTERNAL_ID FROM cwd_user WHERE directory_id='10100' AND EXTERNAL_ID='11111:aed4a01f-we2wsw-w2-ddd-ee2e2'

//根据要修改的lower_user_name 查app_user
SELECT ID, user_key, lower_user_name FROM app_user WHERE lower_user_name='clock@company.com'

//根据修改前值 查cwd_user
SELECT ID, directory_id, user_name, lower_user_name, active, created_date, updated_date, first_name, lower_first_name, last_name, lower_last_name, display_name, lower_display_name, email_address, lower_email_address, CREDENTIAL, deleted_externally, EXTERNAL_ID FROM cwd_user WHERE directory_id='10100' AND lower_user_name='clock'


更新crw_user lower_user user_name 
UPDATE cwd_user SET directory_id='10100', user_name='clock@company.com', lower_user_name='clock@company.com', active='1', created_date='2016-12-02 17:49:10.0', updated_date='2019-04-03 16:30:05.874', first_name='clock', lower_first_name='clock', last_name='clock', lower_last_name='clock', display_name='clock clock', lower_display_name='clock clock', email_address='clock@company.com', lower_email_address='clock@company.com', CREDENTIAL='X', deleted_externally='null', EXTERNAL_ID='11111:aed4a01f-we2wsw-w2-ddd-ee2e2' WHERE ID='10821'



查询cwd_membership 的值,根据旧值查
SELECT ID, parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id FROM cwd_membership WHERE membership_type='GROUP_USER' AND lower_child_name='clock' AND directory_id='10100'

删除旧值
"DELETE FROM cwd_membership WHERE membership_type='GROUP_USER' AND child_name='clock' AND directory_id='10100'

//验证旧值
SELECT lower_parent_name FROM cwd_membership WHERE (directory_id =  '10100' ) AND (lower_child_name =  'clock' ) AND (membership_type =  'GROUP_USER' )


验证新值

SELECT lower_parent_name FROM cwd_membership WHERE (directory_id =  '10100' ) AND (lower_child_name =  'clock@company.com' ) AND (membership_type =  'GROUP_USER' )

插入新lower_user 的membership值
INSERT INTO cwd_membership (ID, parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id) VALUES ('15304', '10414', '10821', 'GROUP_USER', 'null', 'crowd-users', 'crowd-users', 'clock@company.com', 'clock@company.com', '10100')




SELECT lower_parent_name FROM cwd_membership WHERE (directory_id =  '10100' ) AND (lower_child_name =  'clock@company.com' ) AND (membership_type =  'GROUP_USER' )



INSERT INTO cwd_membership (ID, parent_id, child_id, membership_type, group_type, parent_name, lower_parent_name, child_name, lower_child_name, directory_id) VALUES ('15305', '10444', '10821', 'GROUP_USER', 'null', 'test-研发组', 'test-研发组', 'click@compayn.com', 'clock@company.com', '10100')





SELECT user_key FROM app_user WHERE lower_user_name='clock'



UPDATE app_user SET  lower_user_name = 'clock@company.com'  WHERE user_key='clock'


SELECT COUNT(*) FROM cwd_user WHERE lower_user_name='clock'


SELECT ID, directory_id, user_name, lower_user_name, active, created_date, updated_date, first_name, lower_first_name, last_name, lower_last_name, display_name, lower_display_name, email_address, lower_email_address, CREDENTIAL, deleted_externally, EXTERNAL_ID FROM cwd_user WHERE directory_id='10100' AND lower_user_name='clock@company.com'



UPDATE cwd_user SET directory_id='10100', user_name='clock@company.com', lower_user_name='clock@company.com', active='1', created_date='2016-12-02 17:49:10.0', updated_date='2019-04-03 16:30:05.874', first_name='clock', lower_first_name='clock', last_name='clock', lower_last_name='clock', display_name='clock clock', lower_display_name='clock clock', email_address='clock@company.com', lower_email_address='clock@company.com', CREDENTIAL='X', deleted_externally='null', EXTERNAL_ID='11111:aed4a01f-we2wsw-w2-ddd-ee2e2' WHERE ID='10821'


SELECT ID, user_key, lower_user_name FROM app_user WHERE lower_user_name='clock@company.com'


INSERT INTO audit_log (ID, REMOTE_ADDRESS, CREATED, AUTHOR_KEY, SUMMARY, CATEGORY, OBJECT_TYPE, OBJECT_ID, OBJECT_NAME, OBJECT_PARENT_ID, OBJECT_PARENT_NAME, AUTHOR_TYPE, EVENT_SOURCE_NAME, SEARCH_FIELD) VALUES ('24654', 'null', '2019-04-03 16:30:05.889', 'null', 'User updated', 'user management', 'USER', 'clock', 'clock@company.com', '10100', 'jira', '0', '', 'user updated management clock@company.com jira clock')



INSERT INTO audit_changed_value (ID, LOG_ID, NAME, DELTA_FROM, DELTA_TO) VALUES ('22202', '24654', 'Username', 'clock', 'clock@company.com')

从观察出的日志,大概可以看到jira从crowd库中同步时主要修改了3张表
cwd_user,cwd_membership,app_user。
其中cwd_membership是删除旧的关系,然后再新增新的关系。cwd_user,app_user是直接修改了user_name字段。

其中app_user可以看一下表结构,user_key,lower_user_name都是唯一索引,我们修改了lower_user_name,但user_key是不会更改的,可以推出jira其它工单信息表可能跟这个user_key是关联的。新增用户数据的时候user_key默认和lower_user_name一致,但如果我们手动修改一个user_key为将要新增的lower_user_name,那么user_key会随机生一个字符编码。

我也照上面那样修改了这3张表的数据,刷新jira后台用户管理页面后,任然不起作用,登出重新登录后也不生效。

1.1 观察数据查询日志

在修改库不生效后,我又观察jira后台根据关键字查询用户的日志,查询输入的关键字(test_search)去查找,并没有查找到内容,也没有执行sql,如果用有的用户名 关键字可以看到会执行sql,下面是没有匹配到内容的日志:

        ...
        at com.atlassian.jira.user.OfBizUserHistoryStore.getSortedHistory(OfBizUserHistoryStore.java:234)
        at com.atlassian.jira.user.OfBizUserHistoryStore.getHistory(OfBizUserHistoryStore.java:220)
        at com.atlassian.jira.user.CachingUserHistoryStore$DelegatingStoreCacheLoader.load(CachingUserHistoryStore.java:302)
        at com.atlassian.jira.user.CachingUserHistoryStore$DelegatingStoreCacheLoader.load(CachingUserHistoryStore.java:298)
        at com.atlassian.cache.memory.MemoryCacheManager$3$1.load(MemoryCacheManager.java:132)
        at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3573)
        at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2350)
        at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2313)
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2228)
        at com.google.common.cache.LocalCache.get(LocalCache.java:3970)
        at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)
        at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4834)
        at com.atlassian.cache.memory.DelegatingCache$DelegatingLoadingCache.get(DelegatingCache.java:264)
        at com.atlassian.jira.user.CachingUserHistoryStore.getHistory(CachingUserHistoryStore.java:222)
        at com.atlassian.jira.user.CachingUserHistoryStore.getHistory(CachingUserHistoryStore.java:245)
        at com.atlassian.jira.user.SessionBasedAnonymousUserHistoryStore.getHistory(SessionBasedAnonymousUserHistoryStore.java:235)
        at com.atlassian.jira.user.DefaultUserHistoryManager.getHistory(DefaultUserHistoryManager.java:90)
        at com.atlassian.jira.user.DefaultUserProjectHistoryManager.getCurrentProject(DefaultUserProjectHistoryManager.java:58)
        at com.atlassian.jira.plugin.navigation.TopNavigationModuleDescriptorImpl.getTopNavigationContext(TopNavigationModuleDescriptorImpl.java:139)
        at com.atlassian.jira.plugin.navigation.TopNavigationModuleDescriptorImpl.getTopNavigationHtml(TopNavigationModuleDescriptorImpl.java:94)
        at com.atlassian.jira.tzdetect.HeadsUp.getHtml(HeadsUp.java:61)
        at com.atlassian.jira.plugin.navigation.HeaderFooterRendering$8.visit(HeaderFooterRendering.java:313)
        at com.atlassian.jira.plugin.navigation.HeaderFooterRendering$8.visit(HeaderFooterRendering.java:303)
        at com.atlassian.ozymandias.SafePluginPointAccess.invokeModule(SafePluginPointAccess.java:452)
        at com.atlassian.ozymandias.SafePluginPointAccess.descriptors(SafePluginPointAccess.java:150)
        at com.atlassian.jira.plugin.navigation.HeaderFooterRendering.includeTopNavigation(HeaderFooterRendering.java:302)
        at com.atlassian.jira.plugin.navigation.HeaderFooterRendering$1.run(HeaderFooterRendering.java:105)
        at com.atlassian.ozymandias.SafePluginPointAccess.runnable(SafePluginPointAccess.java:201)
        at com.atlassian.jira.plugin.navigation.HeaderFooterRendering.includeTopNavigation(HeaderFooterRendering.java:100)
        at org.apache.jsp.decorators.admin_jsp._jspService(admin_jsp.java:666)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

仔细查看com.atlassian.cache.memory.MemoryCacheManager$3$1.load(MemoryCacheManager.java:132)这一段,执行的是缓存方法,有部分用户数据是加载到缓存里的。

2、crowd库修改
  1. 修改crowd库中cwd_user表的user_name,lower_user_name和cwd_membership中child_name,lower_child_name为新的登录用户名。
  2. 重启jira服务,wiki服务器

重新登录jira后台,刷新页面,发现用户名修改成功了。
登录wiki后台,刷新页面,可以观察到用户登录名修改成功了。
后面就可以通过修改数据库来批量修改登录用户名了。

3、总结
3.1

jira的用户名是缓存到内存中的,所以直接修改库中用户名,然后刷新页面发现没有变化。修改完crowd库中cwd_user,cwd_membership数据后,需要重启jira。
其实在数据库同步的日志中也可以观察到,同步程序是描DB cache数据来同步数据的,所以直接修改库,无法将修改值同步到DB cache中,所以同步程序也无法取到修改值

[atlassian.jira.ofbiz.LoggingSQLInterceptor] 1ms Connection returned. borrowed : 0
[atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleted [ 13 ] users in [ 83ms ]
[atlassian.crowd.directory.DbCachingRemoteChangeOperations] scanned for deleted users in [ 101ms ]
[atlassian.crowd.directory.DbCachingRemoteChangeOperations] scanning [ 1066 ] users to add or update

#扫描并比较:
[atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] scanned and compared [ 1066 ] users for update in DB cache in [ 3ms ]
3.2 ticket not match supplied service或ticket not recognized

问题描述如下:
在jira和wiki对接完单点登录后,我尝试从crowd库中可以批量修改登录账号。更新完crowd表后,重启了jira,可以正常登录,但wiki登录不上了报错:
ticket not match supplied service
ticket not recognized
有部分人可以登录,有部分人不能登录报上面的错误
原因是统一单点登录的账号在wiki中不匹配,需要保证统一单点登录的账号在wiki中存在。
我的conflence对接cas时就出现了如下错误:
在这里插入图片描述
原始服务器地址和提供的服务地址只差了一个‘/’,刚开始以为是cas client本身的错误,后来检查发现,原来是之前手动改了crwod库账号,而wiki账号没同步,注意在修改crwod中的登录账号后,wiki系统也需要重启,账号才能同步。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、登录JIRA 许多JIRA实例都会根据 权限 限制某些用户或用户组查看问题以及对问题的操作。而有些 JIRA实例就允许匿名用户访问,就像http://www.jira.cn中文演示站点允许任何未注册用户体验JIRA。 当你还没有登录JIRA时,会显示 登录 面板。 这时你可以: 1. 登录JIRA: 要登录JIRA, 输入你的 '用户名' 和 '密码' 然后点击 '登录' 按钮。 点击 '这台计算机上记住我的登录信息' 这个检查框可以防止从JIRA中自动注销。 然而, 你的会话不会保留, 例如 上一个搜索记录, 当前使用的项目等。 2. 重置密码: 要重置密码, 点击 '无法登录' 链接。 在弹出的'无法登录'对话框中选择 '我忘记了密码'。 在随后出现的'用户名'字段中输入你的用户名JIRA 会将重置密码链接发送到你在JIRA中登记的邮箱。如果你忘记了邮件地址, 你只能联系JIRA系统管理员。 3. 注册: 如果你还没有JIRA账号, 并且JIRA允许公开注册, 你就可以通过点击'注册'链接创建自己的JIRA账号。 在弹出的注册页面输入你的详细用户信息,并点击'注册'按钮。 请注意由于JIRA管理员可以对JIRA进行定制,所以你看到的页面可能会与截图有差别。 二、了解JIRA页面布局 • 面板 是你登录JIRA后看到的第一个页面。 • 导航栏 (在页面顶部)出现在JIRA所有页面上。它包括让你使用JIRA功能的快速链接。 • 页面顶部导航栏下的白色区域, 可以根据你的具体需要,定制显示不同类型信息的'面板小工具'。 请注意你的JIRA页面可能和上面的截图不太一样, 这是由于JIRA管理员 定制 了公司logo和背景色彩等元素。 但是导航栏上的基本菜单是一样的。 三、使用快捷键 如果你更喜欢使用键盘,JIRA一些基本功能支持快捷键操作。 本页面的内容: • 快捷键 • 全局快捷键 • '查看问题' 和 '问题导航器' 快捷键 • 表单快捷键 • 辅助键 • 打开快捷键对话框 • 禁止与开启快捷键功能 四、创建问题 创建问题 要创建JIRA问题, 你必须拥有相关项目的 '创建' 权限。 如果你还没有这个权限,请联系JIRA系统管理员。 你也可以观看JIRA视频了解如何创建问题。 JIRA视频链接地址http://www.confluence.cn/pages/viewpage.action?pageId=5177526。 要创建一个新的 JIRA 问题: 1. 点击页面顶部的 '创建问题' 链接。 2. 会显示'选择项目和问题类型'弹出框。选择相关的 项目 和 问题类型, 然后点击 '创建' 按钮。 注意如果默认的项目或问题类型不会显示这个弹出框, 例如 o 只有一个项目, 并且这个项目只有一个问题类型。 o 如果你在浏览项目时点击 '创建问题'链接, 而且浏览的项目只有一个问题类型。 o 如果你在浏览项目时点击 '创建' 图标, 例如: 3. '输入问题详细信息' 页面会显示出来。输入问题主题并完成所有标有带星号的斜体字体的必填字段。 注意这个页面可能由于JIRA管理员的自定义设置而显示不同的字段。 4. 点击页面底部的 '创建'按钮。这个新提交的问题就创建成功,你可以在 '查看问题'页面查看所有你输入的问题详细内容。你可能会收到包括问题主要信息以及带有问题超级链接的通知邮件。 要查看所有你创建的还没有解决的问题列表, 跳转到你的 用户配置页面,并点击 '我报告 & 开放的'过滤器。 如果JIRA管理员进行了高级配置, 你还可以 通过邮件创建问题。 五、在面板上添加饼图 '饼图' 可以根据指定 项目 或 问题过滤器,返回的问题列表,并按照指定字段进行分类汇总生成统计图形。例如, 根据一个项目中,一个版本的所有未解决问题, '饼图'可以按照指定的字段进行分类汇总 (例如按照 经办人)。 先看看饼图的外观 出现在面板上的 '饼图' 类似于下面截图: 在面板上添加'饼图' 1. 在你自己的 面板页面,点击右上角的 '添加小工具'链接。 2. 在随后显示出的 '小工具目录'对话框中选择 '饼图' 小工具,并点击 '马上添加' 按钮。然后点击底部的 '完成' 按钮返回面板页面。 3. 饼图小工具已经出现在面板中,并等待你继续配置: 1. '项目或保存的过滤器' — 输入项目或过滤器的名称,或点击'高级搜索'链接搜索项目或已经保存的过滤器。 2. '统计类型' — 选择饼图按照哪个字段进行分组统计。 3. '刷新频率' — 选择这个小工具自动刷新数据的时间间隔 (从不 / 每15分钟 / 每30分钟 / 每1个小时 / 每2个小时)。 4. 点击 '保存' 按钮。 只需简单地拖拽小工具,就可以移动面板上小工具的位置。你也可以改变小工具的外观

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值