]> git.mxchange.org Git - juser-login-core.git/blob - src/org/mxchange/jusercore/model/user/UserUtils.java
82a041b74892f175f4d72d71af48cde69e9f9871
[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.security.SecureRandom;
20 import java.text.MessageFormat;
21 import java.util.Random;
22 import org.apache.commons.codec.digest.Crypt;
23 import org.mxchange.jcore.BaseFrameworkSystem;
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 extends BaseFrameworkSystem {
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          * Static initializer
51          */
52         static {
53                 // Init RNG
54                 RANDOM_NUMBER_GENERATOR = new SecureRandom();
55         }
56
57         /**
58          * Creates a pseudo-random password with given length
59          * <p>
60          * @param length Length of the password
61          * <p>
62          * @return Pseudo-random password
63          */
64         public static String createRandomPassword (final Integer length) {
65                 // Parameter should be valid
66                 if (null == length) {
67                         // Throw NPE
68                         throw new NullPointerException("length is null"); //NOI18N
69                 } else if (length < PASSWORD_MINIMUM_LENGTH) {
70                         // To weak passwords
71                         throw new IllegalArgumentException(MessageFormat.format("Password length {0} is to short, minimum: {1}", length, PASSWORD_MINIMUM_LENGTH)); //NOI18N
72                 }
73
74                 // Init variable
75                 StringBuilder password = new StringBuilder(length);
76
77                 // Start creating it
78                 for (int i = 0; i < length; i++) {
79                         // Generate random number
80                         int pos = RANDOM_NUMBER_GENERATOR.nextInt(PASSWORD_ALPHABET.length());
81
82                         // Get char at this position and add it to the final password
83                         password.append(String.valueOf(PASSWORD_ALPHABET.charAt(pos)));
84                 }
85
86                 // Should have the wanted length
87                 assert (password.length() == length) : MessageFormat.format("Password length {0} doesn't match requested: {1}", password.length(), length); //NOI18N
88
89                 // Return it
90                 return password.toString();
91         }
92
93         /**
94          * Hashes given user password and adds a salt to it
95          * <p>
96          * @param userPassword User password to be hashed
97          * <p>
98          * @return Hashed user password
99          */
100         public static String encryptPassword (final String userPassword) {
101                 // Is it null or empty?
102                 if (null == userPassword) {
103                         // Throw NPE
104                         throw new NullPointerException("userPassword is null"); //NOI18N
105                 } else if (userPassword.isEmpty()) {
106                         // Empty passwords are hardcoded not allowed due to security risks
107                         throw new IllegalArgumentException("userPassword is empty"); //NOI18N
108                 }
109
110                 // Generate large number
111                 String number = Long.toString(RANDOM_NUMBER_GENERATOR.nextLong() * 10_000_000_000L);
112
113                 // Generate salt
114                 String salt = Crypt.crypt(number);
115
116                 // First encrypt password
117                 String encryptedPassword = Crypt.crypt(userPassword, salt);
118
119                 // Return it
120                 return encryptedPassword;
121         }
122
123         /**
124          * Checks if password from container matches the updatedUser's password
125          * <p>
126          * @param container   Container holding user instance and unencrypted password
127          * @param updatedUser Updated user instance from database
128          * <p>
129          * @return Whether the password matches
130          */
131         public static boolean ifPasswordMatches (final LoginContainer container, final User updatedUser) {
132                 // Validate parameters
133                 if (null == container) {
134                         // Throw NPE
135                         throw new NullPointerException("container is null"); //NOI18N
136                 } else if (null == updatedUser) {
137                         // And again NPE ...
138                         throw new NullPointerException("updatedUser is null"); //NOI18N
139                 } else if (container.getUser() == null) {
140                         // NPE for user in container
141                         throw new NullPointerException("container.user is null"); //NOI18N
142                 } else if (container.getUserPassword() == null) {
143                         // NPE for user password in container
144                         throw new NullPointerException("container.userPassword is null"); //NOI18N
145                 } else if (container.getUserPassword().isEmpty()) {
146                         // Empty password in container
147                         throw new IllegalArgumentException("container.userPassword is empty"); //NOI18N
148                 }
149
150                 // First encrypt password
151                 String encryptedPassword = Crypt.crypt(container.getUserPassword(), updatedUser.getUserEncryptedPassword());
152
153                 // Is it matching?
154                 return encryptedPassword.equals(updatedUser.getUserEncryptedPassword());
155         }
156
157         /**
158          * Checks if password from container matches with from user instance.
159          * <p>
160          * @param container   Container holding user instance and unencrypted password
161          * <p>
162          * @return Whether it maches
163          */
164         public static boolean ifPasswordMatches (final UserLoginContainer container) {
165                 // Validate parameters
166                 if (null == container) {
167                         // Throw NPE
168                         throw new NullPointerException("container is null"); //NOI18N
169                 } else if (container.getUser() == null) {
170                         // NPE for user in container
171                         throw new NullPointerException("container.user is null"); //NOI18N
172                 } else if (container.getUserPassword() == null) {
173                         // NPE for user password in container
174                         throw new NullPointerException("container.userPassword is null"); //NOI18N
175                 } else if (container.getUserPassword().isEmpty()) {
176                         // Empty password in container
177                         throw new IllegalArgumentException("container.userPassword is empty"); //NOI18N
178                 }
179
180                 // First encrypt password
181                 String encryptedPassword = Crypt.crypt(container.getUserPassword(), container.getUser().getUserEncryptedPassword());
182
183                 // Is it matching?
184                 return encryptedPassword.equals(container.getUser().getUserEncryptedPassword());
185         }
186
187         /**
188          * No instance from this class
189          */
190         private UserUtils () {
191         }
192 }