![JAR search and dependency download from the Maven repository](/logo.png)
info.kwarc.sally4.lmh.impl.LMHMultiUserStore Maven / Gradle / Ivy
Show all versions of mhw-base Show documentation
package info.kwarc.sally4.lmh.impl;
import info.kwarc.sally4.lmh.factories.LMH;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.attribute.DosFileAttributes;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
import java.nio.file.attribute.UserDefinedFileAttributeView;
import java.util.EnumSet;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LMHMultiUserStore {
LMH lmhRoot;
File usersRoot;
File lmhBase;
Logger log = LoggerFactory
.getLogger("info.kwarc.sally4.lmh.impl.LMHMultiUserStore");
public LMHMultiUserStore(LMH lmh) {
this.lmhRoot = lmh;
lmhBase = lmhRoot.getLMHRootFile();
usersRoot = new File(lmhBase, "users");
init();
}
void init() {
if (!usersRoot.exists()) {
usersRoot.mkdir();
}
}
void createSymLink(File targetParent, File sourceParent, String dirName) throws IOException {
Files.createSymbolicLink(targetParent.toPath().resolve(dirName), lmhBase.toPath().resolve(dirName));
}
/**
* Copies a directory.
*
* NOTE: This method is not thread-safe.
*
*
* @param source
* the directory to copy from
* @param target
* the directory to copy into
* @throws IOException
* if an I/O error occurs
*/
private static void copyDirectory(final Path source, final Path target)
throws IOException {
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS),
Integer.MAX_VALUE, new FileVisitor() {
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes sourceBasic) throws IOException {
Path targetDir = Files.createDirectories(target
.resolve(source.relativize(dir)));
AclFileAttributeView acl = Files.getFileAttributeView(dir,
AclFileAttributeView.class);
if (acl != null)
Files.getFileAttributeView(targetDir,
AclFileAttributeView.class).setAcl(acl.getAcl());
DosFileAttributeView dosAttrs = Files.getFileAttributeView(
dir, DosFileAttributeView.class);
if (dosAttrs != null) {
DosFileAttributes sourceDosAttrs = dosAttrs
.readAttributes();
DosFileAttributeView targetDosAttrs = Files
.getFileAttributeView(targetDir,
DosFileAttributeView.class);
targetDosAttrs.setArchive(sourceDosAttrs.isArchive());
targetDosAttrs.setHidden(sourceDosAttrs.isHidden());
targetDosAttrs.setReadOnly(sourceDosAttrs.isReadOnly());
targetDosAttrs.setSystem(sourceDosAttrs.isSystem());
}
FileOwnerAttributeView ownerAttrs = Files
.getFileAttributeView(dir, FileOwnerAttributeView.class);
if (ownerAttrs != null) {
FileOwnerAttributeView targetOwner = Files
.getFileAttributeView(targetDir,
FileOwnerAttributeView.class);
targetOwner.setOwner(ownerAttrs.getOwner());
}
PosixFileAttributeView posixAttrs = Files
.getFileAttributeView(dir, PosixFileAttributeView.class);
if (posixAttrs != null) {
PosixFileAttributes sourcePosix = posixAttrs
.readAttributes();
PosixFileAttributeView targetPosix = Files
.getFileAttributeView(targetDir,
PosixFileAttributeView.class);
targetPosix.setPermissions(sourcePosix.permissions());
targetPosix.setGroup(sourcePosix.group());
}
UserDefinedFileAttributeView userAttrs = Files
.getFileAttributeView(dir,
UserDefinedFileAttributeView.class);
if (userAttrs != null) {
UserDefinedFileAttributeView targetUser = Files
.getFileAttributeView(targetDir,
UserDefinedFileAttributeView.class);
for (String key : userAttrs.list()) {
ByteBuffer buffer = ByteBuffer.allocate(userAttrs
.size(key));
userAttrs.read(key, buffer);
buffer.flip();
targetUser.write(key, buffer);
}
}
// Must be done last, otherwise last-modified time may be
// wrong
BasicFileAttributeView targetBasic = Files
.getFileAttributeView(targetDir,
BasicFileAttributeView.class);
targetBasic.setTimes(sourceBasic.lastModifiedTime(),
sourceBasic.lastAccessTime(),
sourceBasic.creationTime());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
Files.copy(file, target.resolve(source.relativize(file)),
StandardCopyOption.COPY_ATTRIBUTES);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult
visitFileFailed(Path file, IOException e)
throws IOException {
throw e;
}
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException e) throws IOException {
if (e != null) throw e;
return FileVisitResult.CONTINUE;
}
});
}
void copyDir(File targetParent, File sourceParent, String dirName) throws IOException {
File sFile = new File(sourceParent, dirName);
File dFile = new File(targetParent, dirName);
copyDirectory(sFile.toPath(), dFile.toPath());
}
public LMHImpl initUser(String userId, String sshKey) {
File userRoot = new File(usersRoot, userId);
if (userRoot.exists()) {
try {
return new LMHImpl(userRoot.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
userRoot.mkdir();
try {
Files.createDirectory(userRoot.toPath().resolve("MathHub"));
} catch (IOException e1) {
}
try {
copyDir(userRoot, lmhBase, "bin");
copyDir(userRoot, lmhBase, "ext");
copyDir(userRoot, lmhBase, "lmh");
createSymLink(userRoot, lmhBase, "sty");
createSymLink(userRoot, lmhBase, "styles");
new File(FilenameUtils.concat(userRoot.getAbsolutePath(), "bin/lmh")).setExecutable(true);
File sshFile = new File(FilenameUtils.concat(userRoot.getAbsolutePath(), "bin/myssh"));
FileUtils.writeStringToFile(sshFile, "#!/bin/sh\nexec /usr/bin/ssh -i "+sshFile.getParentFile().getAbsolutePath()+"/key \"$@\"");
sshFile.setExecutable(true);
File keyFile = new File(FilenameUtils.concat(userRoot.getAbsolutePath(), "bin/key"));
FileUtils.writeStringToFile(keyFile, sshKey);
Files.setPosixFilePermissions(keyFile.toPath(), PosixFilePermissions.fromString("rw-------"));
} catch (IOException e) {
e.printStackTrace();
log.error("Error initializing repository ", e);
}
try {
return new LMHImpl(userRoot.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}