<commit_before>/*
 *  eXist Open Source Native XML Database
 *  Copyright (C) 2001 <NAME>
 *  <EMAIL>
 *  http://exist.sourceforge.net
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 *  $Id$
 */
package org.exist.security;

import java.util.ArrayList;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.exist.EXistException;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
import org.exist.security.xacml.ExistPDP;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.sync.Sync;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.LockException;
import org.exist.util.MimeType;
import org.exist.util.hashtable.Int2ObjectHashMap;
import org.exist.xmldb.XmldbURI;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * SecurityManager is responsible for managing users and groups.
 * 
 * There's only one SecurityManager for each database instance, which
 * may be obtained by {@link BrokerPool#getSecurityManager()}.
 * 
 * Users and groups are stored in the system collection, in document
 * users.xml. While it is possible to edit this file by hand, it
 * may lead to unexpected results, since SecurityManager reads 
 * users.xml only during database startup and shutdown.
 */
public class XMLSecurityManager implements SecurityManager {

	public final static String DBA_GROUP = "dba";
	public final static String DBA_USER = "admin";
	public final static String GUEST_GROUP = "guest";
	public final static String GUEST_USER = "guest";
	
	public final static User SYSTEM_USER = new User(DBA_USER, null, DBA_GROUP);
	
	private final static Logger LOG =
		Logger.getLogger(SecurityManager.class);

	private BrokerPool pool;
	private Int2ObjectHashMap groups = new Int2ObjectHashMap(65);
	private Int2ObjectHashMap users = new Int2ObjectHashMap(65);
	private int nextUserId = 0;
	private int nextGroupId = 0;

	private int defCollectionPermissions = Permission.DEFAULT_PERM;
    private int defResourcePermissions = Permission.DEFAULT_PERM;
    
    private ExistPDP pdp;

    public XMLSecurityManager() {
       
    }
	/**
	 * Initialize the security manager.
	 * 
	 * Checks if the file users.xml exists in the system collection of the database.
	 * If not, it is created with two default users: admin and guest.
	 *  
	 * @param pool
	 * @param sysBroker
	 */
    public void attach(BrokerPool pool, DBBroker sysBroker) {
       this.pool = pool;
       
       TransactionManager transact = pool.getTransactionManager();
       Txn txn = null;
       DBBroker broker = sysBroker;
       try {
          Collection sysCollection = broker.getCollection(XmldbURI.SYSTEM_COLLECTION_URI);
          if (sysCollection == null) {
             txn = transact.beginTransaction();
             sysCollection = broker.getOrCreateCollection(txn, XmldbURI.SYSTEM_COLLECTION_URI);
             sysCollection.setPermissions(0770);
             broker.saveCollection(txn, sysCollection);
             transact.commit(txn);
          }
          Document acl = sysCollection.getDocument(broker, ACL_FILE_URI);
          Element docElement = null;
          if (acl != null)
             docElement = acl.getDocumentElement();
          if (docElement == null) {
             LOG.debug("creating system users");
             User user = new User(DBA_USER, null);
             user.addGroup(DBA_GROUP);
             user.setUID(++nextUserId);
             users.put(user.getUID(), user);
             user = new User(GUEST_USER, GUEST_USER, GUEST_GROUP);
             user.setUID(++nextUserId);
             users.put(user.getUID(), user);
             addGroup(DBA_GROUP);
             addGroup(GUEST_GROUP);
             txn = transact.beginTransaction();
             save(broker, txn);
             transact.commit(txn);
          } else {
             LOG.debug("loading acl");
             Element root = acl.getDocumentElement();
             String version = root.getAttribute("version");
             int major = 0;
             int minor = 0;
             if (version!=null) {
                String [] numbers = version.split("\\.");
                major = Integer.parseInt(numbers[0]);
                minor = Integer.parseInt(numbers[1]);
             }
             NodeList nl = root.getChildNodes();
             Node node;
             Element next;
             User user;
             NodeList ul;
             String lastId;
             Group group;
             for (int i = 0; i < nl.getLength(); i++) {
                if(nl.item(i).getNodeType() != Node.ELEMENT_NODE)
                   continue;
                next = (Element) nl.item(i);
                if (next.getTagName().equals("users")) {
                   lastId = next.getAttribute("last-id");
                   try {
                      nextUserId = Integer.parseInt(lastId);
                   } catch (NumberFormatException e) {
                   }<commit_msg>DLN branch: fixed potential NPE during restore when reading users.xml.<commit_after>/*
 *  eXist Open Source Native XML Database
 *  Copyright (C) 2001 <NAME>
 *  <EMAIL>armstadt.de
 *  http://exist.sourceforge.net
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 *  $Id$
 */
package org.exist.security;

import java.util.ArrayList;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.exist.EXistException;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
import org.exist.security.xacml.ExistPDP;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.sync.Sync;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.LockException;
import org.exist.util.MimeType;
import org.exist.util.hashtable.Int2ObjectHashMap;
import org.exist.xmldb.XmldbURI;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * SecurityManager is responsible for managing users and groups.
 * 
 * There's only one SecurityManager for each database instance, which
 * may be obtained by {@link BrokerPool#getSecurityManager()}.
 * 
 * Users and groups are stored in the system collection, in document
 * users.xml. While it is possible to edit this file by hand, it
 * may lead to unexpected results, since SecurityManager reads 
 * users.xml only during database startup and shutdown.
 */
public class XMLSecurityManager implements SecurityManager {

	public final static String DBA_GROUP = "dba";
	public final static String DBA_USER = "admin";
	public final static String GUEST_GROUP = "guest";
	public final static String GUEST_USER = "guest";
	
	public final static User SYSTEM_USER = new User(DBA_USER, null, DBA_GROUP);
	
	private final static Logger LOG =
		Logger.getLogger(SecurityManager.class);

	private BrokerPool pool;
	private Int2ObjectHashMap groups = new Int2ObjectHashMap(65);
	private Int2ObjectHashMap users = new Int2ObjectHashMap(65);
	private int nextUserId = 0;
	private int nextGroupId = 0;

	private int defCollectionPermissions = Permission.DEFAULT_PERM;
    private int defResourcePermissions = Permission.DEFAULT_PERM;
    
    private ExistPDP pdp;

    public XMLSecurityManager() {
       
    }
	/**
	 * Initialize the security manager.
	 * 
	 * Checks if the file users.xml exists in the system collection of the database.
	 * If not, it is created with two default users: admin and guest.
	 *  
	 * @param pool
	 * @param sysBroker
	 */
    public void attach(BrokerPool pool, DBBroker sysBroker) {
       this.pool = pool;
       
       TransactionManager transact = pool.getTransactionManager();
       Txn txn = null;
       DBBroker broker = sysBroker;
       try {
          Collection sysCollection = broker.getCollection(XmldbURI.SYSTEM_COLLECTION_URI);
          if (sysCollection == null) {
             txn = transact.beginTransaction();
             sysCollection = broker.getOrCreateCollection(txn, XmldbURI.SYSTEM_COLLECTION_URI);
             sysCollection.setPermissions(0770);
             broker.saveCollection(txn, sysCollection);
             transact.commit(txn);
          }
          Document acl = sysCollection.getDocument(broker, ACL_FILE_URI);
          Element docElement = null;
          if (acl != null)
             docElement = acl.getDocumentElement();
          if (docElement == null) {
             LOG.debug("creating system users");
             User user = new User(DBA_USER, null);
             user.addGroup(DBA_GROUP);
             user.setUID(++nextUserId);
             users.put(user.getUID(), user);
             user = new User(GUEST_USER, GUEST_USER, GUEST_GROUP);
             user.setUID(++nextUserId);
             users.put(user.getUID(), user);
             addGroup(DBA_GROUP);
             addGroup(GUEST_GROUP);
             txn = transact.beginTransaction();
             save(broker, txn);
             transact.commit(txn);
          } else {
             LOG.debug("loading acl");
             Element root = acl.getDocumentElement();
             Attr version = root.getAttributeNode("version");
             int major = 0;
             int minor = 0;
             if (version!=null) {
                String [] numbers = version.getValue().split("\\.");
                major = Integer.parseInt(numbers[0]);
                minor = Integer.parseInt(numbers[1]);
             }
             NodeList nl = root.getChildNodes();
             Node node;
             Element next;
             User user;
             NodeList ul;
             String lastId;
             Group group;
             for (int i = 0; i < nl.getLength(); i++) {
                if(nl.item(i).getNodeType() != Node.ELEMENT_NODE)
                   continue;
                next = (Element) nl.item(i);
                if (next.getTagName().equals("users")) {
                   lastId = next.getAttribute("last-id");
                   try {
                      nextUserId = Integer.parseInt(lastId);
                   } catch (NumberFormatException e) {
                   }
{'fraction_non_alphanumeric': 0.09113175675675676, 'fraction_numerical': 0.006503378378378379, 'mean_word_length': 2.589269475598666, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 11}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5555419', 'n_tokens_mistral': 3347, 'n_tokens_neox': 3272, 'n_words': 981}