EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.sql.conn]

COVERAGE SUMMARY FOR SOURCE FILE [GenericAuthorizer.java]

nameclass, %method, %block, %line, %
GenericAuthorizer.java100% (1/1)100% (11/11)91%  (201/221)96%  (68/71)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class GenericAuthorizer100% (1/1)100% (11/11)91%  (201/221)96%  (68/71)
GenericAuthorizer (String, LanguageConnectionContext, boolean): void 100% (1/1)100% (13/13)100% (6/6)
authorize (int): void 100% (1/1)84%  (46/55)94%  (15/16)
connectionMustRemainReadOnly (): boolean 100% (1/1)100% (13/13)100% (3/3)
externalRoutineException (int, int): StandardException 100% (1/1)100% (22/22)100% (10/10)
getAuthorizationId (): String 100% (1/1)100% (3/3)100% (1/1)
getDefaultAccessLevel (): int 100% (1/1)73%  (30/41)83%  (10/12)
getUserAccessLevel (): void 100% (1/1)100% (28/28)100% (8/8)
isReadOnlyConnection (): boolean 100% (1/1)100% (3/3)100% (1/1)
refresh (): void 100% (1/1)100% (16/16)100% (6/6)
setReadOnlyConnection (boolean, boolean): void 100% (1/1)100% (14/14)100% (5/5)
userOnAccessList (String): boolean 100% (1/1)100% (13/13)100% (3/3)

1/*
2 
3   Derby - Class org.apache.derby.impl.sql.conn.GenericAuthorizer
4 
5   Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.sql.conn;
22 
23import org.apache.derby.iapi.sql.Activation;
24import org.apache.derby.iapi.reference.Property;
25import org.apache.derby.iapi.util.IdUtil;
26import org.apache.derby.iapi.util.StringUtil;
27import org.apache.derby.iapi.services.sanity.SanityManager;
28import org.apache.derby.iapi.error.StandardException;
29import org.apache.derby.iapi.sql.conn.Authorizer;
30import org.apache.derby.iapi.reference.SQLState;
31import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
32import org.apache.derby.iapi.services.property.PropertyUtil;
33import org.apache.derby.iapi.services.property.PersistentSet;
34import org.apache.derby.catalog.types.RoutineAliasInfo;
35import org.apache.derby.iapi.sql.dictionary.DataDictionary;
36import org.apache.derby.iapi.sql.dictionary.StatementPermission;
37import org.apache.derby.iapi.store.access.TransactionController;
38 
39import java.util.Properties;
40import java.util.List;
41import java.util.Iterator;
42 
43class GenericAuthorizer
44implements Authorizer
45{
46        //
47        //Enumerations for user access levels.
48        private static final int NO_ACCESS = 0;
49        private static final int READ_ACCESS = 1;
50        private static final int FULL_ACCESS = 2;
51        
52        //
53        //Configurable userAccessLevel - derived from Database level
54        //access control lists + database boot time controls.
55        private int userAccessLevel;
56 
57        //
58        //Connection's readOnly status
59    boolean readOnlyConnection;
60 
61        private final LanguageConnectionContext lcc;
62        
63        private final String authorizationId; //the userName after parsing by IdUtil 
64        
65        GenericAuthorizer(String authorizationId, 
66                                                     LanguageConnectionContext lcc,
67                                                 boolean sqlConnection)
68                 throws StandardException
69        {
70                this.lcc = lcc;
71                this.authorizationId = authorizationId;
72 
73                //we check the access level only if this is coming from a sql
74                //connection, not internal logSniffer or StageTrunc db connection
75                if(sqlConnection)
76                        refresh();
77        }
78 
79        /*
80          Return true if the connection must remain readOnly
81          */
82        private boolean connectionMustRemainReadOnly()
83        {
84                if (lcc.getDatabase().isReadOnly() ||
85                        (userAccessLevel==READ_ACCESS))
86                        return true;
87                else
88                        return false;
89        }
90 
91        /**
92          Used for operations that do not involve tables or routines.
93     
94          @see Authorizer#authorize
95          @exception StandardException Thrown if the operation is not allowed
96        */
97        public void authorize( int operation) throws StandardException
98        {
99                authorize( (Activation) null, operation);
100        }
101 
102        /**
103          @see Authorizer#authorize
104          @exception StandardException Thrown if the operation is not allowed
105         */
106        public void authorize( Activation activation, int operation) throws StandardException
107        {
108                int sqlAllowed = lcc.getStatementContext().getSQLAllowed();
109 
110                switch (operation)
111                {
112                case Authorizer.SQL_ARBITARY_OP:
113                case Authorizer.SQL_CALL_OP:
114                        if (sqlAllowed == RoutineAliasInfo.NO_SQL)
115                                throw externalRoutineException(operation, sqlAllowed);
116                        break;
117                case Authorizer.SQL_SELECT_OP:
118                        if (sqlAllowed > RoutineAliasInfo.READS_SQL_DATA)
119                                throw externalRoutineException(operation, sqlAllowed);
120                        break;
121 
122                // SQL write operations
123                case Authorizer.SQL_WRITE_OP:
124                case Authorizer.PROPERTY_WRITE_OP:
125                        if (isReadOnlyConnection())
126                                throw StandardException.newException(SQLState.AUTH_WRITE_WITH_READ_ONLY_CONNECTION);
127                        if (sqlAllowed > RoutineAliasInfo.MODIFIES_SQL_DATA)
128                                throw externalRoutineException(operation, sqlAllowed);
129                        break;
130 
131                // SQL DDL operations
132                case Authorizer.JAR_WRITE_OP:
133                case Authorizer.SQL_DDL_OP:
134                         if (isReadOnlyConnection())
135                                throw StandardException.newException(SQLState.AUTH_DDL_WITH_READ_ONLY_CONNECTION);
136 
137                        if (sqlAllowed > RoutineAliasInfo.MODIFIES_SQL_DATA)
138                                throw externalRoutineException(operation, sqlAllowed);
139                        break;
140 
141                default:
142                        if (SanityManager.DEBUG)
143                                SanityManager.THROWASSERT("Bad operation code "+operation);
144                }
145        if( activation != null)
146        {
147            List requiredPermissionsList = activation.getPreparedStatement().getRequiredPermissionsList();
148            DataDictionary dd = lcc.getDataDictionary();
149 
150            // DBA can access any object. Ignore requiredPermissionsList for DBA
151            if( requiredPermissionsList != null && ! requiredPermissionsList.isEmpty() && 
152                                !authorizationId.equals(dd.getAuthorizationDBA()))
153            {
154                for( Iterator iter = requiredPermissionsList.iterator();
155                     iter.hasNext();)
156                {
157                    ((StatementPermission) iter.next()).check( lcc, authorizationId, false);
158                }                    
159            }
160                }
161        }
162 
163        private static StandardException externalRoutineException(int operation, int sqlAllowed) {
164 
165                String sqlState;
166                if (sqlAllowed == RoutineAliasInfo.READS_SQL_DATA)
167                        sqlState = SQLState.EXTERNAL_ROUTINE_NO_MODIFIES_SQL;
168                else if (sqlAllowed == RoutineAliasInfo.CONTAINS_SQL)
169                {
170                        switch (operation)
171                        {
172                        case Authorizer.SQL_WRITE_OP:
173                        case Authorizer.PROPERTY_WRITE_OP:
174                        case Authorizer.JAR_WRITE_OP:
175                        case Authorizer.SQL_DDL_OP:
176                                sqlState = SQLState.EXTERNAL_ROUTINE_NO_MODIFIES_SQL;
177                                break;
178                        default:
179                                sqlState = SQLState.EXTERNAL_ROUTINE_NO_READS_SQL;
180                                break;
181                        }
182                }
183                else
184                        sqlState = SQLState.EXTERNAL_ROUTINE_NO_SQL;
185 
186                return StandardException.newException(sqlState);
187        }
188        
189 
190        /**
191          @see Authorizer#getAuthorizationId
192          */
193        public String getAuthorizationId()
194        {
195                return authorizationId;
196        }
197 
198        private void getUserAccessLevel() throws StandardException
199        {
200                userAccessLevel = NO_ACCESS;
201                if (userOnAccessList(Property.FULL_ACCESS_USERS_PROPERTY))
202                        userAccessLevel = FULL_ACCESS;
203 
204                if (userAccessLevel == NO_ACCESS &&
205                        userOnAccessList(Property.READ_ONLY_ACCESS_USERS_PROPERTY))
206                        userAccessLevel = READ_ACCESS;
207 
208                if (userAccessLevel == NO_ACCESS)
209                        userAccessLevel = getDefaultAccessLevel();
210        }
211 
212        private int getDefaultAccessLevel() throws StandardException
213        {
214                PersistentSet tc = lcc.getTransactionExecute();
215 
216                String modeS = (String)
217                        PropertyUtil.getServiceProperty(
218                                                                        tc,
219                                                                        Property.DEFAULT_CONNECTION_MODE_PROPERTY);
220                if (modeS == null)
221                        return FULL_ACCESS;
222                else if(StringUtil.SQLEqualsIgnoreCase(modeS, Property.NO_ACCESS))
223                        return NO_ACCESS;
224                else if(StringUtil.SQLEqualsIgnoreCase(modeS, Property.READ_ONLY_ACCESS))
225                        return READ_ACCESS;
226                else if(StringUtil.SQLEqualsIgnoreCase(modeS, Property.FULL_ACCESS))
227                        return FULL_ACCESS;
228                else
229                {
230                        if (SanityManager.DEBUG)
231                                SanityManager.THROWASSERT("Invalid value for property "+
232                                                                                  Property.DEFAULT_CONNECTION_MODE_PROPERTY+
233                                                                                  " "+
234                                                                                  modeS);
235                         return FULL_ACCESS;
236                }
237        }
238 
239        private boolean userOnAccessList(String listName) throws StandardException
240        {
241                PersistentSet tc = lcc.getTransactionExecute();
242                String listS = (String)
243                        PropertyUtil.getServiceProperty(tc, listName);
244                return IdUtil.idOnList(authorizationId,listS);
245        }
246 
247        /**
248          @see Authorizer#isReadOnlyConnection
249         */
250        public boolean isReadOnlyConnection()
251        {
252                return readOnlyConnection;
253        }
254 
255        /**
256          @see Authorizer#isReadOnlyConnection
257          @exception StandardException Thrown if the operation is not allowed
258         */
259        public void setReadOnlyConnection(boolean on, boolean authorize)
260                 throws StandardException
261        {
262                if (authorize && !on) {
263                        if (connectionMustRemainReadOnly())
264                                throw StandardException.newException(SQLState.AUTH_CANNOT_SET_READ_WRITE);
265                }
266                readOnlyConnection = on;
267        }
268 
269        /**
270          @see Authorizer#refresh
271          @exception StandardException Thrown if the operation is not allowed
272          */
273        public void refresh() throws StandardException
274        {
275                getUserAccessLevel();
276                if (!readOnlyConnection)
277                        readOnlyConnection = connectionMustRemainReadOnly();
278 
279                // Is a connection allowed.
280                if (userAccessLevel == NO_ACCESS)
281                        throw StandardException.newException(SQLState.AUTH_DATABASE_CONNECTION_REFUSED);
282        }
283}

[all classes][org.apache.derby.impl.sql.conn]
EMMA 2.0.5312 (C) Vladimir Roubtsov