关于Liferay中用户接受用户协议的研究

简介:

Liferay中用户接受用户协议的代码在PortalRequestProcessor类中,具体代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Authenticated users should agree to Terms of Use
             if  ((user !=  null ) && !user.isAgreedToTermsOfUse()) {
                 boolean  termsOfUseRequired =  false ;
                 try  {
                     termsOfUseRequired = PrefsPropsUtil.getBoolean(
                         user.getCompanyId(), PropsKeys.TERMS_OF_USE_REQUIRED);
                 }
                 catch  (SystemException se) {
                     termsOfUseRequired = PropsValues.TERMS_OF_USE_REQUIRED;
                 }
                 if  (termsOfUseRequired) {
                     return  _PATH_PORTAL_TERMS_OF_USE;
                 }
             }


这里可以看出,是否跳转到/portal/terms_of_use页面是由布尔变量termsOfUseRequired来决定的,只有这个布尔变量为true时候才会发生跳转。具体逻辑是:

(1)如果用户不为null,也就是非第一次登陆Liferay,并且用户的agreedToTermOfUse为false, 也就是第一次登陆时候。

那么就先初始化这个布尔变量为false ,然后读取portal.properties中的TERMS_OF_USE_REQUIRED变量,这个变量的初始值为true.'

1
2
3
4
5
#
    # Set this to true if all users are required to agree to the terms of use.
    #
    terms.of.use.required=true
    #



那么跳转到/portal/terms_of_use又如何呢?

我们发现,定义了一个struts的action_mapping(在struts-config.xml):

1
< action  path = "/portal/terms_of_use"  forward = "portal.terms_of_use"  />

在Tiles框架(tiles-defs.xml)中定义了这个forward key实际指向的页面:

1
2
3
4
< definition  name = "portal.terms_of_use"  extends = "portal" >
         < put  name = "title"  value = "terms-of-use"  />
         < put  name = "content"  value = "/portal/terms_of_use.jsp"  />
     </ definition >

所以最终的页面是/portal/terms_of_use.jsp



在这个页面中,我们可以看到对应的 "I Agree"和"I Disagree" 2个按钮的页面代码为:

1
2
3
4
5
6
7
8
9
< c:if  test="<%= !user.isAgreedToTermsOfUse() %>">
         < aui:button-row >
             < aui:button  type = "submit"  value = "i-agree"  />
             <%
             String taglibOnClick = "alert('" + UnicodeLanguageUtil.get(pageContext, "you-must-agree-with-the-terms-of-use-to-continue") + "');";
             %>
             < aui:button  onClick="<%= taglibOnClick %>" type="cancel" value="i-disagree" />
         </ aui:button-row >
     </ c:if >

我们可以看到,当用户点击"I Disagree"时候,它会跳到一个alert对话框,然后阻止你进一步操作直到你点了agree按钮。当用户点击"I Agree"时候,它会做一个表单提交,提交的url如下:


1
2
3
< aui:form  action='<%= themeDisplay.getPathMain() + "/portal/update_terms_of_use" %>' name="fm">
     < aui:input  name = "doAsUserId"  type = "hidden"  value="<%= themeDisplay.getDoAsUserId() %>" />
     < aui:input  name="<%= WebKeys.REFERER %>" type="hidden" value="<%= referer %>" />


提交到了/portal/update_terms_of_use,结合struts-config.xml,我们这个请求对应一个Struts的Action而不是一个页面:

1
< action  path = "/portal/update_terms_of_use"  type = "com.liferay.portal.action.UpdateTermsOfUseAction"  />

我们跟进到这个类:

1
2
3
4
5
6
7
8
9
10
11
public  class  UpdateTermsOfUseAction  extends  Action {
     @Override
     public  ActionForward execute(
             ActionMapping mapping, ActionForm form, HttpServletRequest request,
             HttpServletResponse response)
         throws  Exception {
         long  userId = PortalUtil.getUserId(request);
         UserServiceUtil.updateAgreedToTermsOfUse(userId,  true );
         return  mapping.findForward(ActionConstants.COMMON_REFERER);
     }
}

可以发现,它会让userServiceUtil来对当前用户更新下agreedToTermsOfUse状态位:

一直跟进会发现它最终调用的是UserLocalServiceImpl的updateAgreedToTermOfUse()方法:

1
2
3
4
5
6
7
8
public  User updateAgreedToTermsOfUse(
             long  userId,  boolean  agreedToTermsOfUse)
         throws  PortalException, SystemException {
         User user = userPersistence.findByPrimaryKey(userId);
         user.setAgreedToTermsOfUse(agreedToTermsOfUse);
         userPersistence.update(user,  false );
         return  user;
     }

它会去设置User_表的字段:


见User_表的DDL:


用户第一次注册然后登陆时选择接受"I Agree"用户term之后,它会显示改变这个字段的值:

从上面可以看出,我这里注册了一个用户,名字叫kevin qian,那么在初次接受term之后,会自动吧数据库表中agreedToTermsOfUse这个字段的位设置为1,因此下次就会跳过用户条款页面了。



总结:

综上所述我们有以下事实:

(1)当用户信息刚插入到Users_表中时候,agreedToTermsOfUse为false, 这也是用户的初始状态。

(2)如果用户在accept 用户条款页面中点了"Agree",那么数据库中agreedToTermsOfUse这个字段就会变成1了

(3)如果用户刚注册好他自己的账户(初始状态),这时候user不为null,并且agreedToTermsOfUse为false,这时候,Liferay的struts action会吧用户带到用户条款页面,也就是/portal/terms_of_use.jsp页面

(4)如果用户曾经在这个用户条款页面选择过 “ I Agree”,那么后果就是它对应的数据库记录中的agreedToTermsOfUse字段为true了,那么它再不可能到用户条款页面了,

(5)如果一用户不是新用户,那么他却在登录后跳转到用户条款页面,那么唯一的解释就是,这个用户不是在这个数据库中创建的,这个用户的这个字段agreedToTermsOfUse没有被更新。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1271289,如需转载请自行联系原作者
目录
相关文章
|
3月前
|
开发框架 监控 安全
.NET 应用程序安全背后究竟隐藏着多少秘密?从编码到部署全揭秘!
【8月更文挑战第28天】在数字化时代,.NET 应用程序的安全至关重要。从编码阶段到部署,需全面防护以保障系统稳定与用户数据安全。开发者应遵循安全编码规范,实施输入验证、权限管理和加密敏感信息等措施,并利用安全测试发现潜在漏洞。此外,部署时还需选择安全的服务器环境,配置 HTTPS 并实时监控应用状态,确保全方位防护。
52 3
|
6月前
|
小程序 安全 JavaScript
.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
|
JavaScript IDE 前端开发
【Web3 探索】如何获取协议中某个地址拥有的所有投资组合
在本指南中,我们将为您介绍使用Chainbase的getAccountPortfolios API检索协议中特定地址拥有的所有投资组合的步骤。
104 0
【Web3 探索】如何获取协议中某个地址拥有的所有投资组合
|
C语言
开讲啦:Chap 09 用户自己建立数据类型
C语言允许用户根据需要自己建立数据类型,用它来定义变量
开讲啦:Chap 09 用户自己建立数据类型
|
人工智能 Java 机器人
编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
285 0
编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
|
API
【环信】修改群组信息web_application 错误
【环信】修改群组信息web_application 错误
91 0
苹果“开除”Facebook,原因是后者违反协议分发数据收集APP
违反协议的Facebook被苹果撤销了ios开发者证书。
404 0