2 Replies Latest reply on Jun 11, 2009 8:57 PM by Anis RIZK

    problem with identity management in seam 2.1.1

    Anis RIZK Newbie

      Hello everyone, I have a problem  with the identity  management that I can not resolve for weeks,
      in my application users and roles management work very well (I am based on the example seamspace) except that I have to give access rights from the other tables(similar to the entity  member in seamspace: each member has a login and password that are stored in the table UserAccount, this is to associate the table with UserAccount Member)
      My problem is that I have generated the entities with the command seam-generate-entities but I can not associate the access rights to each member (I tried to inspire of  the method RegisterAction of seamspace but without result )
      this is my session bean 'MemberHome'



      package org.domain.test.session;
      
      import org.domain.test.entity.*;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.framework.EntityHome;
      
      
      @Name("memberHome")
      public class MemberHome extends EntityHome<Member> {
      
           
           public void setMemberMemberId(Integer id) {
                setId(id);
           }
      
           public Integer getMemberMemberId() {
                return (Integer) getId();
           }
      
           @Override
           protected Member createInstance() {
                Member member = new Member();
                 
                  return member;
           }
      
           public void wire() {
                getInstance();
           }
      
           public boolean isWired() {
                return true;
           }
      
           public Member getDefinedInstance() {
                return isIdDefined() ? getInstance() : null;
           }
         
      
      }
      
      


      and my entity bean 'Member'



      package org.domain.test.entity;
      
      // Generated 1 juin 2009 11:44:41 by Hibernate Tools 3.2.4.CR1
      
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import static javax.persistence.GenerationType.IDENTITY;
      import javax.persistence.Id;
      import javax.persistence.Table;
      import javax.persistence.UniqueConstraint;
      import org.hibernate.validator.Length;
      import org.hibernate.validator.NotNull;
      
      /**
       * Member generated by hbm2java
       */
      @Entity
      @Table(name = "member", catalog = "hp", uniqueConstraints = @UniqueConstraint(columnNames = "memberName"))
      public class Member implements java.io.Serializable {
      
           private Integer memberId;
           private String memberName;
           private String firstName;
           private String lastName;
      
           public Member() {
           }
      
           public Member(String memberName, String firstName, String lastName) {
                this.memberName = memberName;
                this.firstName = firstName;
                this.lastName = lastName;
           }
      
           @Id
           @GeneratedValue(strategy = IDENTITY)
           @Column(name = "memberId", unique = true, nullable = false)
           public Integer getMemberId() {
                return this.memberId;
           }
      
           public void setMemberId(Integer memberId) {
                this.memberId = memberId;
           }
      
           @Column(name = "memberName", unique = true, nullable = false, length = 40)
           @NotNull
           @Length(max = 40)
           public String getMemberName() {
                return this.memberName;
           }
      
           public void setMemberName(String memberName) {
                this.memberName = memberName;
           }
      
           @Column(name = "firstName", nullable = false, length = 40)
           @NotNull
           @Length(max = 40)
           public String getFirstName() {
                return this.firstName;
           }
      
           public void setFirstName(String firstName) {
                this.firstName = firstName;
           }
      
           @Column(name = "lastName", nullable = false, length = 40)
           @NotNull
           @Length(max = 40)
           public String getLastName() {
                return this.lastName;
           }
      
           public void setLastName(String lastName) {
                this.lastName = lastName;
           }
      
      }
      



      I also added the association  on the side of the entity bean UserAccount



      @OneToOne
              @JoinColumn(name = "MEMBER_ID")
              public Member getMember()
              {
                 return member;
              }
              
              public void setMember(Member member)
              {
                 this.member = member;
              }
      
      



      but I can not properly modify the session bean 'MemmberHome' as the case of Action Register. can someone help me?









        • 1. Re: problem with identity management in seam 2.1.1
          Leo van den berg Master

          Hi Anis,


          This is really a Hibernate (mapping) question!


          Seam.gen takes the tables from the DB (I assume you have these defined with the proper relation between Member and UserAccount) and you should basically get a mapped set of entities.


          What I see is the oneToOne relation from the UserAccount to Member, but I can't see the reverse relation. In other words. You Table UserAccount has a FK to Member, So there should at a minimum be a relation from Member to UserAccount to be able to update such a relation in your MemberHome


          The Seam documentation contains a lot of information about (the use of) identity management and the last Seam version allow you to create User and Roles with annotations. Try first to follow these examples or use the earlier version where you create your own AuthenticationManager using your own classes.


          Leo


          P.S. Another problemI see  (I have to be carefull now, because a lot of DB-designers will disagrre), is that you use an UniqueConstratint on the memberName, which you probably will enter manually in your application. The validation prior to persisting will NOT check uniqueness (you must create your validator) so basically when you type in a not-unique name, the DB will detect it and will generate a beautiful error.
          .


          • 2. Re: problem with identity management in seam 2.1.1
            Anis RIZK Newbie

            Thank you Leo for your reply
            I forgot to mention that for the Identity Management I have used the entities of the seamspace example with annotations of course, but for the other entities i have used seam gen
            this is my bean 'UserAccount'



            package org.domain.test.entity;
            
            import java.io.Serializable;
            import java.util.Set;
            
            import javax.persistence.Column;
            import javax.persistence.Entity;
            import javax.persistence.GeneratedValue;
            import javax.persistence.Id;
            import javax.persistence.JoinColumn;
            import javax.persistence.JoinTable;
            import javax.persistence.ManyToMany;
            import javax.persistence.OneToOne;
            import javax.persistence.Table;
            import javax.persistence.UniqueConstraint;
            
            import org.hibernate.validator.NotNull;
            import org.jboss.seam.annotations.security.management.UserEnabled;
            import org.jboss.seam.annotations.security.management.UserPassword;
            import org.jboss.seam.annotations.security.management.UserPrincipal;
            import org.jboss.seam.annotations.security.management.UserRoles;
            
            @Entity
            @Table(uniqueConstraints = @UniqueConstraint(columnNames = "username"), name = "user_account")
            public class UserAccount implements Serializable {
                 private static final long serialVersionUID = 6368734442192368866L;
            
                 private Long id;
                 private String username;
                 private String passwordHash;
                 private boolean enabled;
            
                 private Set<UserRole> roles;
                 private Member member;
                 @Id
                 @GeneratedValue
                 public Long getId() {
                      return id;
                 }
            
                 public void setId(Long id) {
                      this.id = id;
                 }
            
                 @NotNull
                 @UserPrincipal
                 public String getUsername() {
                      return username;
                 }
            
                 public void setUsername(String username) {
                      this.username = username;
                 }
            
                 @UserPassword
                 @Column(name = "password_hash")
                 public String getPasswordHash() {
                      return passwordHash;
                 }
            
                 public void setPasswordHash(String passwordHash) {
                      this.passwordHash = passwordHash;
                 }
            
                 @UserEnabled
                 public boolean isEnabled() {
                      return enabled;
                 }
            
                 public void setEnabled(boolean enabled) {
                      this.enabled = enabled;
                 }
            
                 @UserRoles
                 @ManyToMany
                 @JoinTable(name = "user_account_role", joinColumns = @JoinColumn(name = "account_id"), inverseJoinColumns = @JoinColumn(name = "member_of_role"))
                 public Set<UserRole> getRoles() {
                      return roles;
                 }
            
                 public void setRoles(Set<UserRole> roles) {
                      this.roles = roles;
                 }
                 
                 
                 
                 @OneToOne
                    @JoinColumn(name = "MEMBER_ID")
                    public Member getMember()
                    {
                       return member;
                    }
                    
                    public void setMember(Member member)
                    {
                       this.member = member;
                    }
            
                 
            }
            


            and the method 'UserAction'



            package org.domain.test.session;
            
            import static org.jboss.seam.ScopeType.CONVERSATION;
            
            import java.io.Serializable;
            import java.util.ArrayList;
            import java.util.List;
            
            import org.jboss.seam.annotations.In;
            import org.jboss.seam.annotations.Install;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Scope;
            import org.jboss.seam.core.Conversation;
            import org.jboss.seam.international.StatusMessages;
            import org.jboss.seam.security.management.IdentityManager;
            
            
            @Name("userAction")
            @Scope(CONVERSATION)
            
            public class UserAction implements Serializable
            {
               private String firstname;
               private String lastname;
               private String username;
               private String password;
               private String confirm;
               private List<String> roles;
               private boolean enabled;
               
               private boolean newUserFlag;   
               
               @In IdentityManager identityManager;
                  
               @Begin
               public void createUser()
               {
                  roles = new ArrayList<String>();
                  newUserFlag = true;
               }
               
               @Begin
               public void editUser(String username)
               {      
                  this.username = username;
                  roles = identityManager.getGrantedRoles(username);
                  enabled = identityManager.isUserEnabled(username);
                  newUserFlag = false;
               }
                  
               public String save()
               {
                  if (newUserFlag)
                  {
                     return saveNewUser();
                  }
                  else
                  {
                     return saveExistingUser();
                  }
               }
               
               private String saveNewUser()
               {      
                  if (password == null || !password.equals(confirm))
                  {
                     StatusMessages.instance().addToControl("password", "Passwords do not match");
                     return "failure";
                  }
                  
                  boolean success = identityManager.createUser(username, password, firstname, lastname);
                  
                  if (success)
                  {
                     for (String role : roles)
                     {
                        identityManager.grantRole(username, role);
                     }
                     
                     if (!enabled)
                     {
                        identityManager.disableUser(username);   
                     }
                     
                     Conversation.instance().end();
                     
                     return "success";
                  }
                  
                  return "failure";      
               }
               
               private String saveExistingUser()
               {
                  // Check if a new password has been entered
                  if (password != null && !"".equals(password))
                  {
                     if (!password.equals(confirm))
                     {
                        StatusMessages.instance().addToControl("password", "Passwords do not match");
                        return "failure";
                     }
                     else
                     {
                        identityManager.changePassword(username, password);
                     }
                  }
                  
                  List<String> grantedRoles = identityManager.getGrantedRoles(username);
                  
                  if (grantedRoles != null)
                  {
                     for (String role : grantedRoles)
                     {
                        if (!roles.contains(role)) identityManager.revokeRole(username, role);
                     }
                  }
                  
                  for (String role : roles)
                  {
                     if (grantedRoles == null || !grantedRoles.contains(role)) 
                     {
                        identityManager.grantRole(username, role);
                     }
                  }
                  
                  if (enabled)
                  {
                     identityManager.enableUser(username);
                  }
                  else
                  {
                     identityManager.disableUser(username);
                  }
                     
                  Conversation.instance().end();
                  return "success";
               }
               
               public String getFirstname()
               {
                  return firstname;
               }
               
               public void setFirstname(String firstname)
               {
                  this.firstname = firstname;
               }
               
               public String getLastname()
               {
                  return lastname;
               }
               
               public void setLastname(String lastname)
               {
                  this.lastname = lastname;
               }
               
               public String getUsername()
               {
                  return username;
               }
               
               public void setUsername(String username)
               {
                  this.username = username;
               }
               
               public String getPassword()
               {
                  return password;
               }
               
               public void setPassword(String password)
               {
                  this.password = password;
               }
               
               public String getConfirm()
               {
                  return confirm;
               }
               
               public void setConfirm(String confirm)
               {
                  this.confirm = confirm;
               }
               
               public List<String> getRoles()
               {
                  return roles;
               }
               
               public void setRoles(List<String> roles)
               {
                  this.roles = roles;
               }
               
               public boolean isEnabled()
               {
                  return enabled;
               }
               
               public void setEnabled(boolean enabled)
               {
                  this.enabled = enabled;
               }
            }



            what I'm looking for now is how to create a member and assign a default role for all memmbers
            I tried to add a fonction  'save' in my bean 'MemberHome'



            package org.domain.test.session;
            
            import org.domain.test.entity.*;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.framework.EntityHome;
            import org.jboss.seam.security.Identity;
            import org.jboss.seam.security.RunAsOperation;
            import org.jboss.seam.security.management.IdentityManager;
            import org.jboss.seam.annotations.In;
            import javax.persistence.EntityManager;
            import org.jboss.seam.faces.FacesMessages;
            
            @Name("memberHome")
            public class MemberHome extends EntityHome<Member> {
            
                 private Member member;
            
                  @In
                    private EntityManager entityManager;
                    
                    @In
                    private Identity identity;
                    
                    @In
                    private IdentityManager identityManager;
                       
                    private UserAccount newAccount;
                    
                    private String username;   
                    private boolean verified;
            
                    /**
                     * Password confirmation
                     */
                    private String password;
                    private String confirm;     
                 
                 public void setMemberMemberId(Integer id) {
                      setId(id);
                 }
            
                 public Integer getMemberMemberId() {
                      return (Integer) getId();
                 }
            
                 @Override
                 protected Member createInstance() {
                      Member member = new Member();
                      
                        return member;
                 }
            
                 public void wire() {
                      getInstance();
                 }
            
                 public boolean isWired() {
                      return true;
                 }
            
                 public Member getDefinedInstance() {
                      return isIdDefined() ? getInstance() : null;
                 }
            
                  public void save() {
                       member = new Member();
            
                            
                       
                       verified = (confirm != null && confirm.equals(password));
                       
                       if (!verified)
                       {
                          FacesMessages.instance().addToControl("confirmPassword", "Passwords do not match");
                       }           
                 
                       entityManager.persist(member);      
            
                       new RunAsOperation() {
                           public void execute() {
                              identityManager.createUser(username, password);
                              identityManager.grantRole(username, "collaborateur");            
                           }         
                        }.addRole("admin")
                         .run();
            
                        newAccount.setMember(member);
                        newAccount = entityManager.merge(newAccount);
            
                     // Login the user
                        identity.getCredentials().setUsername(username);
                        identity.getCredentials().setPassword(password);
                        identity.login();
                       
                  }
                  
                  public Member getMember()
                    {
                       return member;
                    }
                    
            
                    
                    public String getUsername()
                    {
                       return username;
                    }
                    
                    public void setUsername(String username)
                    {
                       this.username = username;
                    }
                    
                    public String getPassword()
                    {
                       return password;
                    }
                    
                    public void setPassword(String password)
                    {
                       this.password = password;
                    }
                    
                    public String getConfirm()
                    {
                       return confirm;
                    }
                    
                    public void setConfirm(String confirm)
                    {
                       this.confirm = confirm;
                    }
            
                    public boolean isVerified()
                    {
                       return verified;
                    }
                    
            
            }
            



            but without result :(


            PS: you are right about the UniqueConstratint on the memberName