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