View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  package org.opencastproject.security.impl.jpa;
22  
23  import org.opencastproject.security.api.Organization;
24  import org.opencastproject.security.api.Role;
25  import org.opencastproject.security.api.User;
26  import org.opencastproject.util.EqualsUtil;
27  
28  import java.util.HashSet;
29  import java.util.Objects;
30  import java.util.Set;
31  
32  import javax.persistence.Access;
33  import javax.persistence.AccessType;
34  import javax.persistence.CascadeType;
35  import javax.persistence.Column;
36  import javax.persistence.Entity;
37  import javax.persistence.FetchType;
38  import javax.persistence.GeneratedValue;
39  import javax.persistence.Id;
40  import javax.persistence.JoinColumn;
41  import javax.persistence.JoinTable;
42  import javax.persistence.Lob;
43  import javax.persistence.ManyToMany;
44  import javax.persistence.NamedQueries;
45  import javax.persistence.NamedQuery;
46  import javax.persistence.OneToOne;
47  import javax.persistence.Table;
48  import javax.persistence.Transient;
49  import javax.persistence.UniqueConstraint;
50  
51  /**
52   * JPA-annotated user object.
53   */
54  @Entity
55  @Access(AccessType.FIELD)
56  @Table(
57      name = "oc_user",
58      uniqueConstraints = {
59          @UniqueConstraint(name = "UNQ_oc_user", columnNames = { "username", "organization" }),
60      }
61  )
62  @NamedQueries({
63      @NamedQuery(
64          name = "User.findByQuery",
65          query = "select u from JpaUser u where UPPER(u.username) like :query and u.organization.id = :org"
66      ),
67      @NamedQuery(
68          name = "User.findByIdAndOrg",
69          query = "select u from JpaUser u where u.id=:id and u.organization.id = :org"
70      ),
71      @NamedQuery(
72          name = "User.findByUsername",
73          query = "select u from JpaUser u where u.username=:u and u.organization.id = :org"
74      ),
75      @NamedQuery(
76          name = "User.findAll",
77          query = "select u from JpaUser u where u.organization.id = :org"
78      ),
79      @NamedQuery(
80          name = "User.findInsecureHash",
81          query = "select u from JpaUser u where length(u.password) = 32 and u.organization.id = :org"
82      ),
83      @NamedQuery(
84          name = "User.findAllByUserNames",
85          query = "select u from JpaUser u where u.organization.id = :org AND u.username IN :names"
86      ),
87      @NamedQuery(
88          name = "User.countAllByOrg",
89          query = "select COUNT(u) from JpaUser u where u.organization.id = :org"
90      ),
91      @NamedQuery(
92          name = "User.countAll",
93          query = "select COUNT(u) from JpaUser u"
94      ),
95  })
96  public class JpaUser implements User {
97  
98    @Id
99    @GeneratedValue
100   @Column(name = "id")
101   private Long id;
102 
103   @Column(name = "username", length = 128)
104   private String username;
105 
106   @Column(name = "name", length = 256)
107   private String name;
108 
109   @Column(name = "email", length = 256)
110   private String email;
111 
112   @Column(name = "manageable", nullable = false)
113   private boolean manageable = true;
114 
115   @Transient
116   private String provider;
117 
118   @Lob
119   @Column(name = "password", length = 65535)
120   private String password;
121 
122   @OneToOne()
123   @JoinColumn(name = "organization")
124   private JpaOrganization organization;
125 
126   @ManyToMany(cascade = { CascadeType.MERGE }, fetch = FetchType.LAZY)
127   @JoinTable(
128       name = "oc_user_role",
129       joinColumns = { @JoinColumn(name = "user_id") },
130       inverseJoinColumns = { @JoinColumn(name = "role_id") },
131       uniqueConstraints = {
132           @UniqueConstraint(name = "UNQ_oc_user_role", columnNames = { "user_id", "role_id" })
133       }
134   )
135   private Set<JpaRole> roles;
136 
137   /**
138    * No-arg constructor needed by JPA
139    */
140   public JpaUser() {
141   }
142 
143   /**
144    * Constructs a user with the specified username, password, name, email and provider.
145    *
146    * @param username
147    *          the username
148    * @param password
149    *          the password
150    * @param organization
151    *          the organization
152    * @param name
153    *          the name
154    * @param email
155    *          the email
156    * @param provider
157    *          the provider
158    * @param manageable
159    *          whether the user is manageable
160    */
161   public JpaUser(String username, String password, JpaOrganization organization, String name, String email,
162           String provider, boolean manageable) {
163     super();
164     this.username = username;
165     this.password = password;
166     this.organization = organization;
167     this.name = name;
168     this.email = email;
169     this.provider = provider;
170     this.manageable = manageable;
171     this.roles = new HashSet<JpaRole>();
172   }
173 
174   /**
175    * Constructs a user with the specified username, password, provider and roles.
176    *
177    * @param username
178    *          the username
179    * @param password
180    *          the password
181    * @param organization
182    *          the organization
183    * @param provider
184    *          the provider
185    * @param manageable
186    *          whether the user is manageable
187    * @param roles
188    *          the roles
189    */
190   public JpaUser(String username, String password, JpaOrganization organization, String provider, boolean manageable,
191           Set<JpaRole> roles) {
192     this(username, password, organization, null, null, provider, manageable);
193     for (Role role : roles) {
194       if (!Objects.equals(organization.getId(), role.getOrganizationId())) {
195         throw new IllegalArgumentException("Role " + role + " is not from the same organization!");
196       }
197     }
198     this.roles = roles;
199   }
200 
201   /**
202    * Constructs a user with the specified username, password, name, email, provider and roles.
203    *
204    * @param username
205    *          the username
206    * @param password
207    *          the password
208    * @param organization
209    *          the organization
210    * @param name
211    *          the name
212    * @param email
213    *          the email
214    * @param provider
215    *          the provider
216    * @param manageable
217    *          whether the user is manageable
218    * @param roles
219    *          the roles
220    */
221   public JpaUser(String username, String password, JpaOrganization organization, String name, String email,
222           String provider, boolean manageable, Set<JpaRole> roles) {
223     this(username, password, organization, name, email, provider, manageable);
224     for (Role role : roles) {
225       if (!Objects.equals(organization.getId(), role.getOrganizationId())) {
226         throw new IllegalArgumentException("Role " + role + " is not from the same organization ("
227                 + organization.getId() + ")");
228       }
229     }
230     this.roles = roles;
231   }
232 
233   public Long getId() {
234     return id;
235   }
236 
237   public void setId(Long id) {
238     this.id = id;
239   }
240 
241   /**
242    * Gets this user's clear text password.
243    *
244    * @return the user account's password
245    */
246   @Override
247   public String getPassword() {
248     return password;
249   }
250 
251   /**
252    * @see org.opencastproject.security.api.User#getUsername()
253    */
254   @Override
255   public String getUsername() {
256     return username;
257   }
258 
259   /**
260    * @see org.opencastproject.security.api.User#hasRole(String)
261    */
262   @Override
263   public boolean hasRole(String roleName) {
264     for (Role role : roles) {
265       if (role.getName().equals(roleName)) {
266         return true;
267       }
268     }
269     return false;
270   }
271 
272   /**
273    * @see org.opencastproject.security.api.User#getOrganization()
274    */
275   @Override
276   public Organization getOrganization() {
277     return organization;
278   }
279 
280   /**
281    * @see org.opencastproject.security.api.User#getRoles()
282    */
283   @Override
284   public Set<Role> getRoles() {
285     return new HashSet<Role>(roles);
286   }
287 
288   /**
289    * {@inheritDoc}
290    *
291    * @see java.lang.Object#equals(java.lang.Object)
292    */
293   @Override
294   public boolean equals(Object obj) {
295     if (!(obj instanceof User)) {
296       return false;
297     }
298     User other = (User) obj;
299     return username.equals(other.getUsername()) && organization.equals(other.getOrganization())
300             && EqualsUtil.eq(provider, other.getProvider());
301   }
302 
303   /**
304    * {@inheritDoc}
305    *
306    * @see java.lang.Object#hashCode()
307    */
308   @Override
309   public int hashCode() {
310     return Objects.hash(username, organization, provider);
311   }
312 
313   /**
314    * {@inheritDoc}
315    *
316    * @see java.lang.Object#toString()
317    */
318   @Override
319   public String toString() {
320     return new StringBuilder(username).append(":").append(organization).append(":").append(provider).toString();
321   }
322 
323   @Override
324   public String getName() {
325     return name;
326   }
327 
328   @Override
329   public String getEmail() {
330     return email;
331   }
332 
333   @Override
334   public String getProvider() {
335     return provider;
336   }
337 
338   public void setProvider(String provider) {
339     this.provider = provider;
340   }
341 
342   @Override
343   public boolean isManageable() {
344     return manageable;
345   }
346 
347   public void setManageable(boolean isManageable) {
348     this.manageable = isManageable;
349   }
350 
351 }