]> git.mxchange.org Git - juser-login-core.git/blob - src/org/mxchange/jusercore/model/user/UserUtils.java
Removed dependency on jcore.jar as this is not for JavaEE applications
[juser-login-core.git] / src / org / mxchange / jusercore / model / user / UserUtils.java
1 /*
2  * Copyright (C) 2016 Roland Haeder
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 package org.mxchange.jusercore.model.user;
18
19 import java.io.Serializable;
20 import java.security.SecureRandom;
21 import java.text.MessageFormat;
22 import java.util.Random;
23 import org.apache.commons.codec.digest.Crypt;
24 import org.mxchange.jusercore.container.login.LoginContainer;
25 import org.mxchange.jusercore.container.login.UserLoginContainer;
26
27 /**
28  * An utilities class for users
29  * <p>
30  * @author Roland Haeder<roland@mxchange.org>
31  */
32 public class UserUtils implements Serializable {
33
34         /**
35          * Password alphabet
36          */
37         private static final String PASSWORD_ALPHABET = "abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXZY0123456789-/?!_+#@"; //NOI18N
38
39         /**
40          * Minimum password length
41          */
42         private static final Integer PASSWORD_MINIMUM_LENGTH = 5;
43
44         /**
45          * Random number generator
46          */
47         private static final Random RANDOM_NUMBER_GENERATOR;
48
49         /**
50          * Serial number
51          */
52         private static final long serialVersionUID = 18_356_847_120_972L;
53
54         /**
55          * Static initializer
56          */
57         static {
58                 // Init RNG
59                 RANDOM_NUMBER_GENERATOR = new SecureRandom();
60         }
61
62         /**
63          * Creates a pseudo-random password with given length
64          * <p>
65          * @param length Length of the password
66          * <p>
67          * @return Pseudo-random password
68          */
69         public static String createRandomPassword (final Integer length) {
70                 // Parameter should be valid
71                 if (null == length) {
72                         // Throw NPE
73                         throw new NullPointerException("length is null"); //NOI18N
74                 } else if (length < PASSWORD_MINIMUM_LENGTH) {
75                         // To weak passwords
76                         throw new IllegalArgumentException(MessageFormat.format("Password length {0} is to short, minimum: {1}", length, PASSWORD_MINIMUM_LENGTH)); //NOI18N
77                 }
78
79                 // Init variable
80                 StringBuilder password = new StringBuilder(length);
81
82                 // Start creating it
83                 for (int i = 0; i < length; i++) {
84                         // Generate random number
85                         int pos = RANDOM_NUMBER_GENERATOR.nextInt(PASSWORD_ALPHABET.length());
86
87                         // Get char at this position and add it to the final password
88                         password.append(String.valueOf(PASSWORD_ALPHABET.charAt(pos)));
89                 }
90
91                 // Should have the wanted length
92                 assert (password.length() == length) : MessageFormat.format("Password length {0} doesn't match requested: {1}", password.length(), length); //NOI18N
93
94                 // Return it
95                 return password.toString();
96         }
97
98         /**
99          * Hashes given user password and adds a salt to it
100          * <p>
101          * @param userPassword User password to be hashed
102          * <p>
103          * @return Hashed user password
104          */
105         public static String encryptPassword (final String userPassword) {
106                 // Is it null or empty?
107                 if (null == userPassword) {
108                         // Throw NPE
109                         throw new NullPointerException("userPassword is null"); //NOI18N
110                 } else if (userPassword.isEmpty()) {
111                         // Empty passwords are hardcoded not allowed due to security risks
112                         throw new IllegalArgumentException("userPassword is empty"); //NOI18N
113                 }
114
115                 // Generate large number
116                 String number = Long.toString(RANDOM_NUMBER_GENERATOR.nextLong() * 10_000_000_000L);
117
118                 // Generate salt
119                 String salt = Crypt.crypt(number);
120
121                 // First encrypt password
122                 String encryptedPassword = Crypt.crypt(userPassword, salt);
123
124                 // Return it
125                 return encryptedPassword;
126         }
127
128         /**
129          * Checks if password from container matches the updatedUser's password
130          * <p>
131          * @param container Container holding user instance and unencrypted password
132          * @param updatedUser Updated user instance from database
133          * <p>
134          * @return Whether the password matches
135          */
136         public static boolean ifPasswordMatches (final LoginContainer container, final User updatedUser) {
137                 // Validate parameters
138                 if (null == container) {
139                         // Throw NPE
140                         throw new NullPointerException("container is null"); //NOI18N
141                 } else if (null == updatedUser) {
142                         // And again NPE ...
143                         throw new NullPointerException("updatedUser is null"); //NOI18N
144                 } else if (container.getUser() == null) {
145                         // NPE for user in container
146                         throw new NullPointerException("container.user is null"); //NOI18N
147                 } else if (container.getUserPassword() == null) {
148                         // NPE for user password in container
149                         throw new NullPointerException("container.userPassword is null"); //NOI18N
150                 } else if (container.getUserPassword().isEmpty()) {
151                         // Empty password in container
152                         throw new IllegalArgumentException("container.userPassword is empty"); //NOI18N
153                 }
154
155                 // First encrypt password
156                 String encryptedPassword = Crypt.crypt(container.getUserPassword(), updatedUser.getUserEncryptedPassword());
157
158                 // Is it matching?
159                 return encryptedPassword.equals(updatedUser.getUserEncryptedPassword());
160         }
161
162         /**
163          * Checks if password from container matches with from user instance.
164          * <p>
165          * @param container Container holding user instance and unencrypted password
166          * <p>
167          * @return Whether it maches
168          */
169         public static boolean ifPasswordMatches (final UserLoginContainer container) {
170                 // Validate parameters
171                 if (null == container) {
172                         // Throw NPE
173                         throw new NullPointerException("container is null"); //NOI18N
174                 } else if (container.getUser() == null) {
175                         // NPE for user in container
176                         throw new NullPointerException("container.user is null"); //NOI18N
177                 } else if (container.getUserPassword() == null) {
178                         // NPE for user password in container
179                         throw new NullPointerException("container.userPassword is null"); //NOI18N
180                 } else if (container.getUserPassword().isEmpty()) {
181                         // Empty password in container
182                         throw new IllegalArgumentException("container.userPassword is empty"); //NOI18N
183                 }
184
185                 // First encrypt password
186                 String encryptedPassword = Crypt.crypt(container.getUserPassword(), container.getUser().getUserEncryptedPassword());
187
188                 // Is it matching?
189                 return encryptedPassword.equals(container.getUser().getUserEncryptedPassword());
190         }
191
192         /**
193          * No instance from this class
194          */
195         private UserUtils () {
196         }
197 }