EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.engine]

COVERAGE SUMMARY FOR SOURCE FILE [User.java]

nameclass, %method, %block, %line, %
User.java100% (1/1)89%  (17/19)98%  (365/371)97%  (92/95)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class User100% (1/1)89%  (17/19)98%  (365/371)97%  (92/95)
getCreateSQLForCopy (Table, String): String 0%   (0/1)0%   (0/2)0%   (0/1)
getDropSQL (): String 0%   (0/1)0%   (0/2)0%   (0/1)
hasRight (Table, int): boolean 100% (1/1)98%  (79/81)96%  (23/24)
User (Database, int, String, boolean): void 100% (1/1)100% (10/10)100% (3/3)
checkAdmin (): void 100% (1/1)100% (7/7)100% (3/3)
checkOwnsNoSchemas (): void 100% (1/1)100% (33/33)100% (5/5)
checkRename (): void 100% (1/1)100% (1/1)100% (1/1)
checkRight (Table, int): void 100% (1/1)100% (11/11)100% (3/3)
checkSchemaAdmin (): void 100% (1/1)100% (9/9)100% (3/3)
getChildren (): ArrayList 100% (1/1)100% (46/46)100% (10/10)
getCreateSQL (): String 100% (1/1)100% (4/4)100% (1/1)
getCreateSQL (boolean): String 100% (1/1)100% (54/54)100% (10/10)
getType (): int 100% (1/1)100% (2/2)100% (1/1)
isAdmin (): boolean 100% (1/1)100% (3/3)100% (1/1)
removeChildrenAndResources (Session): void 100% (1/1)100% (41/41)100% (10/10)
setAdmin (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setSaltAndHash (byte [], byte []): void 100% (1/1)100% (7/7)100% (3/3)
setUserPasswordHash (byte []): void 100% (1/1)100% (26/26)100% (7/7)
validateUserPasswordHash (byte []): boolean 100% (1/1)100% (28/28)100% (6/6)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.engine;
7 
8import java.util.ArrayList;
9import java.util.Arrays;
10 
11import org.h2.api.ErrorCode;
12import org.h2.message.DbException;
13import org.h2.message.Trace;
14import org.h2.schema.Schema;
15import org.h2.security.SHA256;
16import org.h2.table.MetaTable;
17import org.h2.table.RangeTable;
18import org.h2.table.Table;
19import org.h2.table.TableView;
20import org.h2.util.MathUtils;
21import org.h2.util.New;
22import org.h2.util.StringUtils;
23import org.h2.util.Utils;
24 
25/**
26 * Represents a user object.
27 */
28public class User extends RightOwner {
29 
30    private final boolean systemUser;
31    private byte[] salt;
32    private byte[] passwordHash;
33    private boolean admin;
34 
35    public User(Database database, int id, String userName, boolean systemUser) {
36        super(database, id, userName, Trace.USER);
37        this.systemUser = systemUser;
38    }
39 
40    public void setAdmin(boolean admin) {
41        this.admin = admin;
42    }
43 
44    public boolean isAdmin() {
45        return admin;
46    }
47 
48    /**
49     * Set the salt and hash of the password for this user.
50     *
51     * @param salt the salt
52     * @param hash the password hash
53     */
54    public void setSaltAndHash(byte[] salt, byte[] hash) {
55        this.salt = salt;
56        this.passwordHash = hash;
57    }
58 
59    /**
60     * Set the user name password hash. A random salt is generated as well.
61     * The parameter is filled with zeros after use.
62     *
63     * @param userPasswordHash the user name password hash
64     */
65    public void setUserPasswordHash(byte[] userPasswordHash) {
66        if (userPasswordHash != null) {
67            if (userPasswordHash.length == 0) {
68                salt = passwordHash = userPasswordHash;
69            } else {
70                salt = new byte[Constants.SALT_LEN];
71                MathUtils.randomBytes(salt);
72                passwordHash = SHA256.getHashWithSalt(userPasswordHash, salt);
73            }
74        }
75    }
76 
77    @Override
78    public String getCreateSQLForCopy(Table table, String quotedName) {
79        throw DbException.throwInternalError();
80    }
81 
82    @Override
83    public String getCreateSQL() {
84        return getCreateSQL(true);
85    }
86 
87    @Override
88    public String getDropSQL() {
89        return null;
90    }
91 
92    /**
93     * Checks that this user has the given rights for this database object.
94     *
95     * @param table the database object
96     * @param rightMask the rights required
97     * @throws DbException if this user does not have the required rights
98     */
99    public void checkRight(Table table, int rightMask) {
100        if (!hasRight(table, rightMask)) {
101            throw DbException.get(ErrorCode.NOT_ENOUGH_RIGHTS_FOR_1, table.getSQL());
102        }
103    }
104 
105    /**
106     * See if this user has the given rights for this database object.
107     *
108     * @param table the database object, or null for schema-only check
109     * @param rightMask the rights required
110     * @return true if the user has the rights
111     */
112    public boolean hasRight(Table table, int rightMask) {
113        if (rightMask != Right.SELECT && !systemUser && table != null) {
114            table.checkWritingAllowed();
115        }
116        if (admin) {
117            return true;
118        }
119        Role publicRole = database.getPublicRole();
120        if (publicRole.isRightGrantedRecursive(table, rightMask)) {
121            return true;
122        }
123        if (table instanceof MetaTable || table instanceof RangeTable) {
124            // everybody has access to the metadata information
125            return true;
126        }
127        if (table != null) {
128            if (hasRight(null, Right.ALTER_ANY_SCHEMA)) {
129                return true;
130            }
131            String tableType = table.getTableType();
132            if (Table.VIEW.equals(tableType)) {
133                TableView v = (TableView) table;
134                if (v.getOwner() == this) {
135                    // the owner of a view has access:
136                    // SELECT * FROM (SELECT * FROM ...)
137                    return true;
138                }
139            } else if (tableType == null) {
140                // function table
141                return true;
142            }
143            if (table.isTemporary() && !table.isGlobalTemporary()) {
144                // the owner has all rights on local temporary tables
145                return true;
146            }
147        }
148        if (isRightGrantedRecursive(table, rightMask)) {
149            return true;
150        }
151        return false;
152    }
153 
154    /**
155     * Get the CREATE SQL statement for this object.
156     *
157     * @param password true if the password (actually the salt and hash) should
158     *            be returned
159     * @return the SQL statement
160     */
161    public String getCreateSQL(boolean password) {
162        StringBuilder buff = new StringBuilder("CREATE USER IF NOT EXISTS ");
163        buff.append(getSQL());
164        if (comment != null) {
165            buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
166        }
167        if (password) {
168            buff.append(" SALT '").
169                append(StringUtils.convertBytesToHex(salt)).
170                append("' HASH '").
171                append(StringUtils.convertBytesToHex(passwordHash)).
172                append('\'');
173        } else {
174            buff.append(" PASSWORD ''");
175        }
176        if (admin) {
177            buff.append(" ADMIN");
178        }
179        return buff.toString();
180    }
181 
182    /**
183     * Check the password of this user.
184     *
185     * @param userPasswordHash the password data (the user password hash)
186     * @return true if the user password hash is correct
187     */
188    boolean validateUserPasswordHash(byte[] userPasswordHash) {
189        if (userPasswordHash.length == 0 && passwordHash.length == 0) {
190            return true;
191        }
192        if (userPasswordHash.length == 0) {
193            userPasswordHash = SHA256.getKeyPasswordHash(getName(), new char[0]);
194        }
195        byte[] hash = SHA256.getHashWithSalt(userPasswordHash, salt);
196        return Utils.compareSecure(hash, passwordHash);
197    }
198 
199    /**
200     * Check if this user has admin rights. An exception is thrown if he does
201     * not have them.
202     *
203     * @throws DbException if this user is not an admin
204     */
205    public void checkAdmin() {
206        if (!admin) {
207            throw DbException.get(ErrorCode.ADMIN_RIGHTS_REQUIRED);
208        }
209    }
210 
211    /**
212     * Check if this user has schema admin rights. An exception is thrown if he
213     * does not have them.
214     *
215     * @throws DbException if this user is not a schema admin
216     */
217    public void checkSchemaAdmin() {
218        if (!hasRight(null, Right.ALTER_ANY_SCHEMA)) {
219            throw DbException.get(ErrorCode.ADMIN_RIGHTS_REQUIRED);
220        }
221    }
222 
223    @Override
224    public int getType() {
225        return DbObject.USER;
226    }
227 
228    @Override
229    public ArrayList<DbObject> getChildren() {
230        ArrayList<DbObject> children = New.arrayList();
231        for (Right right : database.getAllRights()) {
232            if (right.getGrantee() == this) {
233                children.add(right);
234            }
235        }
236        for (Schema schema : database.getAllSchemas()) {
237            if (schema.getOwner() == this) {
238                children.add(schema);
239            }
240        }
241        return children;
242    }
243 
244    @Override
245    public void removeChildrenAndResources(Session session) {
246        for (Right right : database.getAllRights()) {
247            if (right.getGrantee() == this) {
248                database.removeDatabaseObject(session, right);
249            }
250        }
251        database.removeMeta(session, getId());
252        salt = null;
253        Arrays.fill(passwordHash, (byte) 0);
254        passwordHash = null;
255        invalidate();
256    }
257 
258    @Override
259    public void checkRename() {
260        // ok
261    }
262 
263    /**
264     * Check that this user does not own any schema. An exception is thrown if
265     * he owns one or more schemas.
266     *
267     * @throws DbException if this user owns a schema
268     */
269    public void checkOwnsNoSchemas() {
270        for (Schema s : database.getAllSchemas()) {
271            if (this == s.getOwner()) {
272                throw DbException.get(ErrorCode.CANNOT_DROP_2, getName(), s.getName());
273            }
274        }
275    }
276 
277}

[all classes][org.h2.engine]
EMMA 2.0.5312 (C) Vladimir Roubtsov