mirror of https://github.com/gnosygnu/xowa
Sqlite: Add option for read-only detection [#509]
parent
7f76d8128d
commit
989ccde83a
@ -0,0 +1,50 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.caches; import gplx.*; import gplx.core.*;
|
||||
public class Lru_cache_root {
|
||||
private final Ordered_hash hash = Ordered_hash_.New();
|
||||
public Lru_cache Get_by_key(String key) {return (Lru_cache)hash.Get_by(key);}
|
||||
public void Add(Lru_cache grp) {
|
||||
hash.Add(grp.Key(), grp);
|
||||
}
|
||||
public void Del(String key) {
|
||||
hash.Del(key);
|
||||
}
|
||||
public void Clear_caches_all() {
|
||||
int len = hash.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Lru_cache grp = (Lru_cache)hash.Get_at(i);
|
||||
grp.Clear_all();
|
||||
}
|
||||
}
|
||||
public void Clear_caches_min() {
|
||||
int len = hash.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Lru_cache grp = (Lru_cache)hash.Get_at(i);
|
||||
grp.Clear_min(0);
|
||||
}
|
||||
}
|
||||
public String Print_contents(boolean grps_only_or_both) {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
int len = hash.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Lru_cache grp = (Lru_cache)hash.Get_at(i);
|
||||
grp.To_str(bfr, grps_only_or_both);
|
||||
}
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
public static final Lru_cache_root Instance = new Lru_cache_root();
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.ios.streams.*; import gplx.core.ios.atrs.*;
|
||||
import gplx.core.consoles.*; import gplx.core.criterias.*; import gplx.core.caches.*;
|
||||
import gplx.core.envs.*;
|
||||
public class IoEngineUtl {
|
||||
public int BufferLength() {return bufferLength;} public void BufferLength_set(int v) {bufferLength = v;} int bufferLength = 4096; // 0x1000
|
||||
public void DeleteRecycleGplx(IoEngine engine, IoEngine_xrg_recycleFil xrg) {
|
||||
Io_url recycleUrl = xrg.RecycleUrl();
|
||||
if (recycleUrl.Type_fil())
|
||||
engine.MoveFil(IoEngine_xrg_xferFil.move_(xrg.Url(), recycleUrl).Overwrite_(false).ReadOnlyFails_(true));
|
||||
else
|
||||
engine.MoveDirDeep(IoEngine_xrg_xferDir.move_(xrg.Url(), recycleUrl).Overwrite_(false).ReadOnlyFails_(true));
|
||||
}
|
||||
public void DeleteDirDeep(IoEngine engine, Io_url dirUrl, IoEngine_xrg_deleteDir args) {
|
||||
Console_adp usrDlg = args.UsrDlg();
|
||||
IoItmDir dir = engine.QueryDir(dirUrl); if (!dir.Exists()) return;
|
||||
for (Object subDirObj : dir.SubDirs()) {
|
||||
IoItmDir subDir = (IoItmDir)subDirObj;
|
||||
if (!args.SubDirScanCrt().Matches(subDir)) continue;
|
||||
if (args.Recur()) DeleteDirDeep(engine, subDir.Url(), args);
|
||||
}
|
||||
for (Object subFilObj : dir.SubFils()) {
|
||||
IoItmFil subFil = (IoItmFil)subFilObj;
|
||||
if (!args.MatchCrt().Matches(subFil)) continue;
|
||||
Io_url subFilUrl = subFil.Url();
|
||||
try {engine.DeleteFil_api(IoEngine_xrg_deleteFil.new_(subFilUrl).ReadOnlyFails_(args.ReadOnlyFails()));}
|
||||
catch (Exception exc) {usrDlg.Write_fmt_w_nl(Err_.Message_lang(exc));}
|
||||
}
|
||||
// all subs deleted; now delete dir
|
||||
if (!args.MatchCrt().Matches(dir)) return;
|
||||
try {engine.DeleteDir(dir.Url());}
|
||||
catch (Exception exc) {usrDlg.Write_fmt_w_nl(Err_.Message_lang(exc));}
|
||||
}
|
||||
public void XferDir(IoEngine srcEngine, Io_url src, IoEngine trgEngine, Io_url trg, IoEngine_xrg_xferDir args) {
|
||||
trgEngine.CreateDir(trg);
|
||||
IoItmDir srcDir = QueryDirDeep(srcEngine, IoEngine_xrg_queryDir.new_(src).Recur_(false));
|
||||
for (Object subSrcObj : srcDir.SubDirs()) {
|
||||
IoItmDir subSrc = (IoItmDir)subSrcObj;
|
||||
if (!args.SubDirScanCrt().Matches(subSrc)) continue;
|
||||
if (!args.MatchCrt().Matches(subSrc)) continue;
|
||||
Io_url subTrg = trg.GenSubDir_nest(subSrc.Url().NameOnly()); //EX: C:\abc\def\ -> C:\123\ + def\
|
||||
if (args.Recur()) XferDir(srcEngine, subSrc.Url(), trgEngine, subTrg, args);
|
||||
}
|
||||
IoItmList srcFils = IoItmList.list_(src.Info().CaseSensitive());
|
||||
for (Object srcFilObj : srcDir.SubFils()) {
|
||||
IoItmFil srcFil = (IoItmFil)srcFilObj;
|
||||
if (args.MatchCrt().Matches(srcFil)) srcFils.Add(srcFil);
|
||||
}
|
||||
for (Object srcFilObj : srcFils) {
|
||||
IoItmFil srcFil = (IoItmFil)srcFilObj;
|
||||
Io_url srcFilPath = srcFil.Url();
|
||||
Io_url trgFilPath = trg.GenSubFil(srcFilPath.NameAndExt()); //EX: C:\abc\fil.txt -> C:\123\ + fil.txt
|
||||
IoEngine_xrg_xferFil xferArgs = args.Type_move() ? IoEngine_xrg_xferFil.move_(srcFilPath, trgFilPath).Overwrite_(args.Overwrite()) : IoEngine_xrg_xferFil.copy_(srcFilPath, trgFilPath).Overwrite_(args.Overwrite());
|
||||
XferFil(srcEngine, xferArgs);
|
||||
}
|
||||
if (args.Type_move()) srcEngine.DeleteDirDeep(IoEngine_xrg_deleteDir.new_(src).Recur_(args.Recur()).ReadOnlyFails_(args.ReadOnlyFails()));// this.DeleteDirDeep(srcEngine, src, IoEngine_xrg_deleteItm.new_(src).Recur_(args.Recur()).ReadOnlyIgnored_(args.ReadOnlyIgnored()));
|
||||
}
|
||||
public void XferFil(IoEngine srcEngine, IoEngine_xrg_xferFil args) {
|
||||
Io_url src = args.Src(), trg = args.Trg();
|
||||
if (String_.Eq(srcEngine.Key(), trg.Info().EngineKey())) {
|
||||
if (args.Type_move())
|
||||
srcEngine.MoveFil(args);
|
||||
else
|
||||
srcEngine.CopyFil(args);
|
||||
}
|
||||
else {
|
||||
TransferStream(src, trg);
|
||||
if (args.Type_move()) srcEngine.DeleteFil_api(IoEngine_xrg_deleteFil.new_(src));
|
||||
}
|
||||
}
|
||||
public IoItmDir QueryDirDeep(IoEngine engine, IoEngine_xrg_queryDir args) {
|
||||
IoItmDir rv = IoItmDir_.top_(args.Url());
|
||||
rv.Exists_set(QueryDirDeepCore(rv, args.Url(), engine, args.Recur(), args.SubDirScanCrt(), args.DirCrt(), args.FilCrt(), args.UsrDlg(), args.DirInclude()));
|
||||
return rv;
|
||||
}
|
||||
static boolean QueryDirDeepCore(IoItmDir ownerDir, Io_url url, IoEngine engine, boolean recur, Criteria subDirScanCrt, Criteria dirCrt, Criteria filCrt, Console_adp usrDlg, boolean dirInclude) {
|
||||
if (usrDlg.Canceled_chk()) return false;
|
||||
if (usrDlg.Enabled()) usrDlg.Write_tmp(String_.Concat("scan: ", url.Raw()));
|
||||
IoItmDir scanDir = engine.QueryDir(url);
|
||||
for (Object subDirObj : scanDir.SubDirs()) {
|
||||
IoItmDir subDir = (IoItmDir)subDirObj;
|
||||
if (!subDirScanCrt.Matches(subDir)) continue;
|
||||
if (dirCrt.Matches(subDir)) {
|
||||
ownerDir.SubDirs().Add(subDir); // NOTE: always add subDir; do not use dirCrt here, else its subFils will be added to non-existent subDir
|
||||
}
|
||||
if (recur)
|
||||
QueryDirDeepCore(subDir, subDir.Url(), engine, recur, subDirScanCrt, dirCrt, filCrt, usrDlg, dirInclude);
|
||||
}
|
||||
for (Object subFilObj : scanDir.SubFils()) {
|
||||
IoItmFil subFil = (IoItmFil)subFilObj;
|
||||
if (filCrt.Matches(subFil)) ownerDir.SubFils().Add(subFil);
|
||||
}
|
||||
return scanDir.Exists();
|
||||
}
|
||||
void TransferStream(Io_url src, Io_url trg) {
|
||||
IoStream srcStream = null;
|
||||
IoStream trgStream = null;
|
||||
try {
|
||||
srcStream = IoEnginePool.Instance.Get_by(src.Info().EngineKey()).OpenStreamRead(src);
|
||||
trgStream = IoEngine_xrg_openWrite.new_(trg).Exec();
|
||||
srcStream.Transfer(trgStream, bufferLength);
|
||||
}
|
||||
finally {
|
||||
if (srcStream != null) srcStream.Rls();
|
||||
if (trgStream != null) trgStream.Rls();
|
||||
}
|
||||
}
|
||||
private static final Lru_cache Dir_cache = new Lru_cache(Bool_.Y, "gplx.ios.dir_cache", 128, 256);
|
||||
public static boolean Query_read_only(IoEngine engine, Io_url url, int read_only_type) {
|
||||
switch (read_only_type) {
|
||||
case Io_mgr.Read_only__basic__file:
|
||||
return engine.QueryFil(url).Attrib().ReadOnly();
|
||||
case Io_mgr.Read_only__basic__file_and_dirs:
|
||||
if (Op_sys.Cur().Tid_is_wnt()) // only examine owner_dirs if wnt
|
||||
return Query_read_only__file_and_dirs(engine, url);
|
||||
else
|
||||
return engine.QueryFil(url).Attrib().ReadOnly();
|
||||
case Io_mgr.Read_only__perms__file:
|
||||
return engine.Query_itm_atrs(url, Io_itm_atr_req.New__read_only()).Is_read_only();
|
||||
default:
|
||||
throw Err_.new_unhandled_default(read_only_type);
|
||||
}
|
||||
}
|
||||
private static boolean Query_read_only__file_and_dirs(IoEngine engine, Io_url url) {
|
||||
// if fil
|
||||
if (url.Type_fil()) {
|
||||
IoItmFil fil = engine.QueryFil(url);
|
||||
// if read-only, return true
|
||||
if (fil.ReadOnly())
|
||||
return true;
|
||||
// else, set to owner dir
|
||||
else
|
||||
url = url.OwnerDir();
|
||||
}
|
||||
|
||||
// loop until top
|
||||
while (url != Io_url_.Empty) {
|
||||
String dir_key = url.Raw();
|
||||
|
||||
// check cache first
|
||||
IoItmDir dir = (IoItmDir)Dir_cache.Get_or_null(dir_key);
|
||||
if (dir == null) {
|
||||
// not in cache; query file_system
|
||||
dir = engine.QueryDir(url);
|
||||
Dir_cache.Set(dir_key, dir, 1);
|
||||
}
|
||||
|
||||
// if read-only, return true
|
||||
if (dir.ReadOnly())
|
||||
return true;
|
||||
// else, set to owner dir
|
||||
else
|
||||
url = url.OwnerDir();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IoEngineUtl new_() {return new IoEngineUtl();} IoEngineUtl() {}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.ios.atrs; import gplx.*; import gplx.core.*; import gplx.core.ios.*;
|
||||
public class Io_itm_atr_req {
|
||||
Io_itm_atr_req(boolean ignore_errors, boolean check_read_only) {
|
||||
this.ignore_errors = ignore_errors;
|
||||
this.check_read_only = check_read_only;
|
||||
}
|
||||
public boolean Check_read_only() {return check_read_only;} private final boolean check_read_only;
|
||||
public boolean Is_read_only() {return is_read_only;} public void Is_read_only_(boolean v) {this.is_read_only = v;} private boolean is_read_only;
|
||||
public boolean Ignore_errors() {return ignore_errors;} private final boolean ignore_errors;
|
||||
public String To_str() {
|
||||
Keyval[] ary = new Keyval[2];
|
||||
ary[0] = Keyval_.new_("check_read_only", check_read_only);
|
||||
ary[1] = Keyval_.new_("is_read_only", is_read_only);
|
||||
return Keyval_.Ary_to_str(ary);
|
||||
}
|
||||
|
||||
public static Io_itm_atr_req New__read_only() {
|
||||
return new Io_itm_atr_req(true, true);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.ios.atrs; import gplx.*; import gplx.core.*; import gplx.core.ios.*;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.AclFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.util.Set;
|
||||
public abstract class Io_itm_atr_wkr {
|
||||
private final Path path;
|
||||
public Io_itm_atr_wkr(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
public Io_itm_atr_req Process(Io_itm_atr_req req) {
|
||||
try {
|
||||
if (req.Check_read_only())
|
||||
req.Is_read_only_(this.Is_read_only());
|
||||
}
|
||||
catch (Exception e) {
|
||||
Err err = Err_.new_wo_type("query_itm_atrs failed", "url", path.toString(), "atrs", req.To_str(), "e", Err_.Message_gplx_log(e));
|
||||
if (req.Ignore_errors()) { // https://stackoverflow.com/questions/25163174/get-generic-folder-permissions-like-generic-all-using-javas-aclfileattributev
|
||||
Gfo_usr_dlg_.Instance.Warn_many("", "", err.To_str__log());
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return req;
|
||||
}
|
||||
public abstract boolean Is_read_only();
|
||||
public static Io_itm_atr_wkr New(Io_url url) {
|
||||
File fil = new File(url.Xto_api());
|
||||
Path path = fil.toPath();
|
||||
Set<String> supported_views = path.getFileSystem().supportedFileAttributeViews();
|
||||
if (supported_views.contains("posix")) {
|
||||
return new Io_itm_atr_wkr__psx(path);
|
||||
}
|
||||
// WNT
|
||||
else if (supported_views.contains("acl")) {
|
||||
return new Io_itm_atr_wkr__acl(path);
|
||||
}
|
||||
else {
|
||||
String set_string = "";
|
||||
for (String view : supported_views) {
|
||||
set_string += view + ";";
|
||||
}
|
||||
throw Err_.new_unhandled(set_string);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.ios.atrs; import gplx.*; import gplx.core.*; import gplx.core.ios.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.AclEntry;
|
||||
import java.nio.file.attribute.AclEntryPermission;
|
||||
import java.nio.file.attribute.AclEntryType;
|
||||
import java.nio.file.attribute.AclFileAttributeView;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import gplx.core.primitives.Bool_obj_val;
|
||||
class Io_itm_atr_wkr__acl extends Io_itm_atr_wkr { private final AclFileAttributeView view;
|
||||
public Io_itm_atr_wkr__acl(Path path) {
|
||||
super(path);
|
||||
this.view = Files.getFileAttributeView(path, AclFileAttributeView.class);
|
||||
}
|
||||
@Override public boolean Is_read_only() {
|
||||
try {
|
||||
// convert AclEntry to Acl_entry
|
||||
List<AclEntry> list = view.getAcl();
|
||||
int len = list.size();
|
||||
Acl_entry[] ary = new Acl_entry[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
AclEntry under = list.get(i);
|
||||
ary[i] = new Acl_entry(under.principal().toString(), under.type(), under.permissions());
|
||||
}
|
||||
return !Is_permitted(ary, AclEntryPermission.WRITE_DATA);
|
||||
} catch (Exception e) {
|
||||
throw Err_.new_exc(e, "", "Is_read_only failed", "e", Err_.Message_lang(e));
|
||||
}
|
||||
}
|
||||
public static boolean Is_permitted(Acl_entry[] ary, AclEntryPermission permission) {
|
||||
boolean rv = false;
|
||||
Hash_adp principals = Hash_adp_.New();
|
||||
for (Acl_entry itm : ary) {
|
||||
Set<AclEntryPermission> permissions = itm.Permissions();
|
||||
switch (itm.Type()) {
|
||||
// If multiple ALLOW entries
|
||||
// * for same principal, return false if any of them do not have permission
|
||||
// * for diff principals, return true if any of them does have permissions
|
||||
case ALLOW: {
|
||||
// if current principal is forbidden, ignore entry; want to skip lists like Everyone:Forbidden:C:/folder;Everyone:Allowed;C:/
|
||||
Bool_obj_val forbidden = (Bool_obj_val)principals.Get_by(itm.Principal());
|
||||
if (forbidden != null) {
|
||||
continue;
|
||||
}
|
||||
if (!permissions.contains(permission) && !rv) {
|
||||
rv = false;
|
||||
principals.Add(itm.Principal(), Bool_obj_val.False);
|
||||
}
|
||||
else {
|
||||
rv = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// If any DENY entries, return false on first entry
|
||||
case DENY: {
|
||||
if (permissions.contains(permission)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Acl_entry {
|
||||
public Acl_entry(String principal, AclEntryType type, Set<AclEntryPermission> permissions) {
|
||||
this.principal = principal;
|
||||
this.type = type;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
public String Principal() {return principal;} private final String principal;
|
||||
public AclEntryType Type() {return type;} private final AclEntryType type;
|
||||
public Set<AclEntryPermission> Permissions() {return permissions;} private final Set<AclEntryPermission> permissions;
|
||||
}
|
||||
//#}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.ios.atrs; import gplx.*; import gplx.core.*; import gplx.core.ios.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
|
||||
import java.nio.file.attribute.AclEntryPermission;
|
||||
import java.nio.file.attribute.AclEntryType;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
public class Io_itm_atr_wkr__acl__tst {
|
||||
private final Io_itm_attrib_wkr__acl__fxt fxt = new Io_itm_attrib_wkr__acl__fxt();
|
||||
@Test public void Perm_exists() {
|
||||
fxt.Test__Is_permitted
|
||||
( Bool_.Y, AclEntryPermission.WRITE_DATA
|
||||
, fxt.Make__acl("Everyone", AclEntryType.ALLOW, AclEntryPermission.WRITE_DATA)
|
||||
);
|
||||
}
|
||||
@Test public void Perm_missing() {
|
||||
fxt.Test__Is_permitted
|
||||
( Bool_.N, AclEntryPermission.WRITE_DATA
|
||||
, fxt.Make__acl("Everyone", AclEntryType.ALLOW, AclEntryPermission.READ_DATA)
|
||||
);
|
||||
}
|
||||
@Test public void Deny_over_allow() {
|
||||
fxt.Test__Is_permitted
|
||||
( Bool_.N, AclEntryPermission.WRITE_DATA
|
||||
, fxt.Make__acl("Everyone", AclEntryType.ALLOW, AclEntryPermission.WRITE_DATA)
|
||||
, fxt.Make__acl("Everyone", AclEntryType.DENY , AclEntryPermission.WRITE_DATA)
|
||||
);
|
||||
}
|
||||
@Test public void Same_principal__perm_missing_over_perm_exists() {
|
||||
/*
|
||||
EX: SD card wherein acl_list has 2 entries
|
||||
* Entry[0] | //MACHINE/SHARE | Everyone:READ_DATA/READ_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/READ_ACL/SYNCHRONIZE:ALLOW
|
||||
* Entry[1] | DRIVE_NAME:/ | Everyone:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:ALLOW
|
||||
*/
|
||||
fxt.Test__Is_permitted
|
||||
( Bool_.N, AclEntryPermission.WRITE_DATA
|
||||
, fxt.Make__acl("Everyone", AclEntryType.ALLOW, AclEntryPermission.READ_DATA)
|
||||
, fxt.Make__acl("Everyone", AclEntryType.ALLOW, AclEntryPermission.READ_DATA, AclEntryPermission.WRITE_DATA)
|
||||
);
|
||||
}
|
||||
@Test public void Diff_principals__perm_exists_over_perm_missing() {
|
||||
/*
|
||||
EX: C drive wherein acl_list has 2 entries
|
||||
* Entry[0] | C:/ | Administrators:READ_DATA/WRITE_DATA
|
||||
* Entry[1] | C:/ | Everyone:READ_DATA
|
||||
*/
|
||||
fxt.Test__Is_permitted
|
||||
( Bool_.Y, AclEntryPermission.WRITE_DATA
|
||||
, fxt.Make__acl("Administrators", AclEntryType.ALLOW, AclEntryPermission.WRITE_DATA)
|
||||
, fxt.Make__acl("Users" , AclEntryType.ALLOW, AclEntryPermission.READ_DATA)
|
||||
);
|
||||
}
|
||||
}
|
||||
class Io_itm_attrib_wkr__acl__fxt {
|
||||
public void Test__Is_permitted(boolean expd, AclEntryPermission permission, Acl_entry... entries) {
|
||||
boolean actl = Io_itm_atr_wkr__acl.Is_permitted(entries, permission);
|
||||
Gftest.Eq__bool(expd, actl);
|
||||
}
|
||||
public Acl_entry Make__acl(String principal, AclEntryType type, AclEntryPermission... perms) {
|
||||
Set<AclEntryPermission> perm_set = new HashSet<AclEntryPermission>();
|
||||
for (AclEntryPermission perm : perms)
|
||||
perm_set.add(perm);
|
||||
return new Acl_entry(principal, type, perm_set);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.core.ios.atrs; import gplx.*; import gplx.core.*; import gplx.core.ios.*;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFileAttributes;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.Set;
|
||||
class Io_itm_atr_wkr__psx extends Io_itm_atr_wkr { private final PosixFileAttributeView view;
|
||||
public Io_itm_atr_wkr__psx(Path path) {
|
||||
super(path);
|
||||
this.view = Files.getFileAttributeView(path, PosixFileAttributeView.class);
|
||||
}
|
||||
@Override public boolean Is_read_only() {
|
||||
try {
|
||||
// ASSUME:a file is read-only if it is read-only; Note that the directory may need write-access, but not handling it now; REF:https://superuser.com/a/114611
|
||||
Set<PosixFilePermission> perms = view.readAttributes().permissions();
|
||||
int perm_flag = Psx__permissions_to_int(perms);
|
||||
return perm_flag == 0444;
|
||||
} catch (Exception e) {
|
||||
throw Err_.new_exc(e, "", "Is_read_only failed", "e", Err_.Message_lang(e));
|
||||
}
|
||||
}
|
||||
public static int Psx__permissions_to_int(Set<PosixFilePermission> psx_perms) {
|
||||
int rv = 0;
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.OWNER_READ)) ? 1 << 8 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.OWNER_WRITE)) ? 1 << 7 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.OWNER_EXECUTE)) ? 1 << 6 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.GROUP_READ)) ? 1 << 5 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.GROUP_WRITE)) ? 1 << 4 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.GROUP_EXECUTE)) ? 1 << 3 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.OTHERS_READ)) ? 1 << 2 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.OTHERS_WRITE)) ? 1 << 1 : 0);
|
||||
rv |= ((psx_perms.contains(PosixFilePermission.OTHERS_EXECUTE)) ? 1 : 0);
|
||||
return rv;
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in new issue