001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.command.ddl;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.constant.ErrorCode;
011: import org.h2.engine.Database;
012: import org.h2.engine.Right;
013: import org.h2.engine.RightOwner;
014: import org.h2.engine.Role;
015: import org.h2.engine.Session;
016: import org.h2.message.Message;
017: import org.h2.table.Table;
018: import org.h2.util.ObjectArray;
019:
020: /**
021: * This class represents the statements
022: * GRANT RIGHT,
023: * GRANT ROLE,
024: * REVOKE RIGHT,
025: * REVOKE ROLE
026: */
027: public class GrantRevoke extends DefineCommand {
028:
029: /**
030: * The operation type to grant a right.
031: */
032: public static final int GRANT = 0;
033:
034: /**
035: * The operation type to revoke a right.
036: */
037: public static final int REVOKE = 1;
038:
039: private ObjectArray roleNames;
040: private int operationType;
041: private int rightMask;
042: private ObjectArray tables = new ObjectArray();
043: private RightOwner grantee;
044:
045: public GrantRevoke(Session session) {
046: super (session);
047: }
048:
049: public void setOperationType(int operationType) {
050: this .operationType = operationType;
051: }
052:
053: /**
054: * Add the specified right bit to the rights bitmap.
055: *
056: * @param right the right bit
057: */
058: public void addRight(int right) {
059: this .rightMask |= right;
060: }
061:
062: /**
063: * Add the specified role to the list of roles.
064: *
065: * @param roleName the role
066: */
067: public void addRoleName(String roleName) {
068: if (roleNames == null) {
069: roleNames = new ObjectArray();
070: }
071: roleNames.add(roleName);
072: }
073:
074: public void setGranteeName(String granteeName) throws SQLException {
075: Database db = session.getDatabase();
076: grantee = db.findUser(granteeName);
077: if (grantee == null) {
078: grantee = db.findRole(granteeName);
079: if (grantee == null) {
080: throw Message
081: .getSQLException(
082: ErrorCode.USER_OR_ROLE_NOT_FOUND_1,
083: granteeName);
084: }
085: }
086: }
087:
088: public int update() throws SQLException {
089: session.getUser().checkAdmin();
090: session.commit(true);
091: Database db = session.getDatabase();
092: if (roleNames != null) {
093: for (int i = 0; i < roleNames.size(); i++) {
094: String name = (String) roleNames.get(i);
095: Role grantedRole = db.findRole(name);
096: if (grantedRole == null) {
097: throw Message.getSQLException(
098: ErrorCode.ROLE_NOT_FOUND_1, name);
099: }
100: if (operationType == GRANT) {
101: grantRole(grantedRole);
102: } else if (operationType == REVOKE) {
103: revokeRole(grantedRole);
104: } else {
105: throw Message.getInternalError("type="
106: + operationType);
107: }
108: }
109: } else {
110: if (operationType == GRANT) {
111: grantRight();
112: } else if (operationType == REVOKE) {
113: revokeRight();
114: } else {
115: throw Message.getInternalError("type=" + operationType);
116: }
117: }
118: return 0;
119: }
120:
121: private void grantRight() throws SQLException {
122: Database db = session.getDatabase();
123: for (int i = 0; i < tables.size(); i++) {
124: Table table = (Table) tables.get(i);
125: Right right = grantee.getRightForTable(table);
126: if (right == null) {
127: int id = getObjectId(true, true);
128: right = new Right(db, id, grantee, rightMask, table);
129: grantee.grantRight(table, right);
130: db.addDatabaseObject(session, right);
131: } else {
132: right.setRightMask(right.getRightMask() | rightMask);
133: }
134: }
135: }
136:
137: private void grantRole(Role grantedRole) throws SQLException {
138: if (grantee.isRoleGranted(grantedRole)) {
139: throw Message.getSQLException(
140: ErrorCode.ROLE_ALREADY_GRANTED_1, grantedRole
141: .getSQL());
142: }
143: if (grantee instanceof Role) {
144: Role granteeRole = (Role) grantee;
145: if (grantedRole.isRoleGranted(granteeRole)) {
146: // TODO role: should be 'cyclic role grants are not allowed'
147: throw Message.getSQLException(
148: ErrorCode.ROLE_ALREADY_GRANTED_1, grantedRole
149: .getSQL());
150: }
151: }
152: Database db = session.getDatabase();
153: int id = getObjectId(true, true);
154: Right right = new Right(db, id, grantee, grantedRole);
155: db.addDatabaseObject(session, right);
156: grantee.grantRole(session, grantedRole, right);
157: }
158:
159: private void revokeRight() throws SQLException {
160: for (int i = 0; i < tables.size(); i++) {
161: Table table = (Table) tables.get(i);
162: Right right = grantee.getRightForTable(table);
163: if (right == null) {
164: throw Message
165: .getSQLException(ErrorCode.RIGHT_NOT_FOUND);
166: }
167: int mask = right.getRightMask();
168: if ((mask & rightMask) != rightMask) {
169: throw Message
170: .getSQLException(ErrorCode.RIGHT_NOT_FOUND);
171: }
172: int newRight = mask ^ rightMask;
173: Database db = session.getDatabase();
174: if (newRight == 0) {
175: db.removeDatabaseObject(session, right);
176: } else {
177: right.setRightMask(newRight);
178: db.update(session, right);
179: }
180: }
181: }
182:
183: private void revokeRole(Role grantedRole) throws SQLException {
184: Right right = grantee.getRightForRole(grantedRole);
185: if (right == null) {
186: throw Message.getSQLException(ErrorCode.RIGHT_NOT_FOUND);
187: }
188: Database db = session.getDatabase();
189: db.removeDatabaseObject(session, right);
190: }
191:
192: public boolean isTransactional() {
193: return false;
194: }
195:
196: /**
197: * Add the specified table to the list of tables.
198: *
199: * @param table the table
200: */
201: public void addTable(Table table) {
202: tables.add(table);
203: }
204:
205: }
|