package org.basex.core; import static org.basex.core.Text.*; import static org.basex.util.Token.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import org.basex.io.IO; import org.basex.io.IOFile; import org.basex.io.in.DataInput; import org.basex.io.out.DataOutput; import org.basex.util.Table; import org.basex.util.Util; import org.basex.util.list.StringList; import org.basex.util.list.TokenList; /** * This class organizes all users. * * @author BaseX Team 2005-12, BSD License * @author Andreas Weiler */ public final class Users { /** User array. */ private final List<User> list = new ArrayList<User>(0); /** Filename; set to {@code null} if the instance handles local users. */ private IOFile file; /** * Constructor for global users. * @param global global flag */ public Users(final boolean global) { if(!global) return; file = new IOFile(Prop.HOME, IO.BASEXSUFFIX + "perm"); if(!file.exists()) { // define default admin user with all rights list.add(new User(ADMIN, token(md5(ADMIN)), User.ADMIN)); } else { DataInput in = null; try { in = new DataInput(file); read(in); } catch(final IOException ex) { Util.errln(ex); } finally { if(in != null) try { in.close(); } catch(final IOException ex) { } } } } /** * Reads users from disk. * @param in input stream * @throws IOException I/O exception */ public synchronized void read(final DataInput in) throws IOException { final int s = in.readNum(); for(int u = 0; u < s; ++u) { final User user = new User(string(in.readToken()), in.readToken(), in.readNum()); list.add(user); } } /** * Writes global permissions to disk. */ public synchronized void write() { if(file == null) return; try { final DataOutput out = new DataOutput(file); write(out); out.close(); } catch(final IOException ex) { Util.debug(ex); } } /** * Stores a user and encrypted password. * @param usern user name * @param pass password * @return success of operation */ public synchronized boolean create(final String usern, final String pass) { // check if user exists already return get(usern) == null && create(new User(usern, token(pass), User.NONE)); } /** * Adds the specified user. * @param user user to be added * @return success of operation */ public synchronized boolean create(final User user) { list.add(user); write(); return true; } /** * Changes the password of a user. * @param usern user name * @param pass password * @return success of operation */ public synchronized boolean alter(final String usern, final String pass) { // check if user exists already final User user = get(usern); if(user == null) return false; user.password = token(pass); write(); return true; } /** * Drops a user from the list. * @param user user reference * @return success flag */ public synchronized boolean drop(final User user) { if(!list.remove(user)) return false; write(); return true; } /** * Returns a user reference with the specified name. * @param usern user name * @return success of operation */ public synchronized User get(final String usern) { for(final User user : list) if(user.name.equals(usern)) return user; return null; } /** * Returns all users that match the specified pattern. * @param pattern user pattern * @return user list */ public synchronized String[] find(final Pattern pattern) { final StringList sl = new StringList(); for(final User u : list) { if(pattern.matcher(u.name).matches()) sl.add(u.name); } return sl.toArray(); } /** * Writes permissions to disk. * @param out output stream; if set to null, the global rights are written * @throws IOException I/O exception */ public synchronized void write(final DataOutput out) throws IOException { // skip writing of local rights out.writeNum(list.size()); for(final User user : list) { out.writeToken(token(user.name)); out.writeToken(user.password); out.writeNum(user.perm); } } /** * Returns information on all users. * @param users optional second list * @return user information */ public synchronized byte[] info(final Users users) { final Table table = new Table(); table.description = USERS; final int sz = file == null ? 3 : 5; for(int u = 0; u < sz; ++u) table.header.add(USERHEAD[u]); for(final User user : list) { if(users != null) if(users.get(user.name) == null) continue; final TokenList tl = new TokenList(); tl.add(user.name); tl.add(user.perm(User.READ) ? "X" : ""); tl.add(user.perm(User.WRITE) ? "X" : ""); if(sz == 5) { tl.add(user.perm(User.CREATE) ? "X" : ""); tl.add(user.perm(User.ADMIN) ? "X" : ""); } table.contents.add(tl); } table.sort(); table.toTop(token(ADMIN)); return table.finish(); } }