@@ -52,9 +52,12 @@ class Acl {
|
||||
val acl = Acl()
|
||||
try {
|
||||
acl.fromId(CUSTOM_RULES)
|
||||
if (!acl.bypass) {
|
||||
acl.subnets.clear()
|
||||
acl.hostnames.clear()
|
||||
}
|
||||
} catch (_: FileNotFoundException) { }
|
||||
acl.bypass = true
|
||||
acl.bypassHostnames.clear() // everything is bypassed
|
||||
return acl
|
||||
}
|
||||
fun save(id: String, acl: Acl) = getFile(id).writeText(acl.toString())
|
||||
@@ -83,32 +86,33 @@ class Acl {
|
||||
|
||||
@DatabaseField(generatedId = true)
|
||||
var id = 0
|
||||
val bypassHostnames = SortedList(String::class.java, StringSorter)
|
||||
val proxyHostnames = SortedList(String::class.java, StringSorter)
|
||||
val hostnames = SortedList(String::class.java, StringSorter)
|
||||
val subnets = SortedList(Subnet::class.java, SubnetSorter)
|
||||
val urls = SortedList(URL::class.java, URLSorter)
|
||||
|
||||
@DatabaseField
|
||||
var bypass = false
|
||||
|
||||
fun fromAcl(other: Acl): Acl {
|
||||
bypassHostnames.clear()
|
||||
for (item in other.bypassHostnames.asIterable()) bypassHostnames.add(item)
|
||||
proxyHostnames.clear()
|
||||
for (item in other.proxyHostnames.asIterable()) proxyHostnames.add(item)
|
||||
fun clear(): Acl {
|
||||
hostnames.clear()
|
||||
subnets.clear()
|
||||
for (item in other.subnets.asIterable()) subnets.add(item)
|
||||
urls.clear()
|
||||
return this
|
||||
}
|
||||
|
||||
fun fromAcl(other: Acl): Acl {
|
||||
clear()
|
||||
for (item in other.hostnames.asIterable()) hostnames.add(item)
|
||||
for (item in other.subnets.asIterable()) subnets.add(item)
|
||||
for (item in other.urls.asIterable()) urls.add(item)
|
||||
bypass = other.bypass
|
||||
return this
|
||||
}
|
||||
fun fromReader(reader: Reader, defaultBypass: Boolean = false): Acl {
|
||||
bypassHostnames.clear()
|
||||
proxyHostnames.clear()
|
||||
subnets.clear()
|
||||
urls.clear()
|
||||
clear()
|
||||
bypass = defaultBypass
|
||||
val proxyHostnames by lazy { SortedList(String::class.java, StringSorter) }
|
||||
val bypassHostnames by lazy { SortedList(String::class.java, StringSorter) }
|
||||
val bypassSubnets by lazy { SortedList(Subnet::class.java, SubnetSorter) }
|
||||
val proxySubnets by lazy { SortedList(Subnet::class.java, SubnetSorter) }
|
||||
var hostnames: SortedList<String>? = if (defaultBypass) proxyHostnames else bypassHostnames
|
||||
@@ -142,6 +146,7 @@ class Acl {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (item in (if (bypass) proxyHostnames else bypassHostnames).asIterable()) this.hostnames.add(item)
|
||||
for (item in (if (bypass) proxySubnets else bypassSubnets).asIterable()) this.subnets.add(item)
|
||||
return this
|
||||
}
|
||||
@@ -154,11 +159,12 @@ class Acl {
|
||||
if (bypass != child.bypass) {
|
||||
Log.w(TAG, "Imported network ACL has a conflicting mode set. " +
|
||||
"This will probably not work as intended. URL: $url")
|
||||
child.subnets.clear() // subnets for the different mode are discarded
|
||||
// rules for the different mode are discarded
|
||||
child.hostnames.clear()
|
||||
child.subnets.clear()
|
||||
child.bypass = bypass
|
||||
}
|
||||
for (item in child.bypassHostnames.asIterable()) bypassHostnames.add(item)
|
||||
for (item in child.proxyHostnames.asIterable()) proxyHostnames.add(item)
|
||||
for (item in child.hostnames.asIterable()) hostnames.add(item)
|
||||
for (item in child.subnets.asIterable()) subnets.add(item)
|
||||
}
|
||||
urls.clear()
|
||||
@@ -167,21 +173,11 @@ class Acl {
|
||||
|
||||
override fun toString(): String {
|
||||
val result = StringBuilder()
|
||||
result.append(if (bypass) "[bypass_all]\n" else "[proxy_all]\n")
|
||||
val bypassList = (if (bypass) bypassHostnames.asIterable().asSequence() else
|
||||
subnets.asIterable().asSequence().map(Subnet::toString) + proxyHostnames.asIterable().asSequence()).toList()
|
||||
val proxyList = (if (bypass) subnets.asIterable().asSequence().map(Subnet::toString) +
|
||||
proxyHostnames.asIterable().asSequence() else bypassHostnames.asIterable().asSequence()).toList()
|
||||
if (bypassList.isNotEmpty()) {
|
||||
result.append("[bypass_list]\n")
|
||||
result.append(bypassList.joinToString("\n"))
|
||||
result.append('\n')
|
||||
}
|
||||
if (proxyList.isNotEmpty()) {
|
||||
result.append("[proxy_list]\n")
|
||||
result.append(proxyList.joinToString("\n"))
|
||||
result.append('\n')
|
||||
}
|
||||
result.append(if (bypass) "[bypass_all]\n[proxy_list]\n" else "[proxy_all]\n[bypass_list]\n")
|
||||
result.append(subnets.asIterable().joinToString("\n"))
|
||||
result.append('\n')
|
||||
result.append(hostnames.asIterable().joinToString("\n"))
|
||||
result.append('\n')
|
||||
result.append(urls.asIterable().joinToString("") { "#IMPORT_URL <$it>\n" })
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
@@ -132,20 +132,20 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
override fun onBindViewHolder(holder: AclRuleViewHolder, i: Int) {
|
||||
val j = i - acl.subnets.size()
|
||||
if (j < 0) holder.bind(acl.subnets[i]) else {
|
||||
val k = j - acl.proxyHostnames.size()
|
||||
if (k < 0) holder.bind(acl.proxyHostnames[j]) else holder.bind(acl.urls[k])
|
||||
val k = j - acl.hostnames.size()
|
||||
if (k < 0) holder.bind(acl.hostnames[j]) else holder.bind(acl.urls[k])
|
||||
}
|
||||
}
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = AclRuleViewHolder(LayoutInflater
|
||||
.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false))
|
||||
override fun getItemCount(): Int = acl.subnets.size() + acl.proxyHostnames.size() + acl.urls.size()
|
||||
override fun getItemCount(): Int = acl.subnets.size() + acl.hostnames.size() + acl.urls.size()
|
||||
override fun getSectionTitle(i: Int): String {
|
||||
val j = i - acl.subnets.size()
|
||||
return try {
|
||||
(if (j < 0) acl.subnets[i].address.hostAddress.substring(0, 1) else {
|
||||
val k = j - acl.proxyHostnames.size()
|
||||
val k = j - acl.hostnames.size()
|
||||
if (k < 0) {
|
||||
val hostname = acl.proxyHostnames[j]
|
||||
val hostname = acl.hostnames[j]
|
||||
// don't convert IDN yet
|
||||
PATTERN_DOMAIN.find(hostname)?.value?.replace("\\.", ".") ?: hostname
|
||||
} else acl.urls[k].host
|
||||
@@ -179,9 +179,9 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
return index
|
||||
}
|
||||
fun addHostname(hostname: String): Int {
|
||||
val old = acl.proxyHostnames.size()
|
||||
val index = acl.subnets.size() + acl.proxyHostnames.add(hostname)
|
||||
if (old != acl.proxyHostnames.size()) {
|
||||
val old = acl.hostnames.size()
|
||||
val index = acl.subnets.size() + acl.hostnames.add(hostname)
|
||||
if (old != acl.hostnames.size()) {
|
||||
notifyItemInserted(index)
|
||||
apply()
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
}
|
||||
fun addURL(url: URL): Int {
|
||||
val old = acl.urls.size()
|
||||
val index = acl.subnets.size() + acl.proxyHostnames.size() + acl.urls.add(url)
|
||||
val index = acl.subnets.size() + acl.hostnames.size() + acl.urls.add(url)
|
||||
if (old != acl.urls.size()) {
|
||||
notifyItemInserted(index)
|
||||
apply()
|
||||
@@ -201,7 +201,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
var result: Int? = null
|
||||
if (acl.bypass) acl.subnets.asIterable().asSequence().map { addSubnet(it) }
|
||||
.forEach { if (result == null) result = it }
|
||||
(acl.proxyHostnames.asIterable().asSequence().map { addHostname(it) } +
|
||||
(acl.hostnames.asIterable().asSequence().map { addHostname(it) } +
|
||||
acl.urls.asIterable().asSequence().map { addURL(it) })
|
||||
.forEach { if (result == null) result = it }
|
||||
return result
|
||||
@@ -227,10 +227,10 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
undoManager.remove(Pair(i, acl.subnets[i]))
|
||||
acl.subnets.removeItemAt(i)
|
||||
} else {
|
||||
val k = j - acl.proxyHostnames.size()
|
||||
val k = j - acl.hostnames.size()
|
||||
if (k < 0) {
|
||||
undoManager.remove(Pair(j, acl.proxyHostnames[j]))
|
||||
acl.proxyHostnames.removeItemAt(j)
|
||||
undoManager.remove(Pair(j, acl.hostnames[j]))
|
||||
acl.hostnames.removeItemAt(j)
|
||||
} else {
|
||||
undoManager.remove(Pair(k, acl.urls[k]))
|
||||
acl.urls.removeItemAt(k)
|
||||
@@ -247,12 +247,12 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
apply()
|
||||
}
|
||||
is String -> {
|
||||
notifyItemRemoved(acl.subnets.size() + acl.proxyHostnames.indexOf(item))
|
||||
acl.proxyHostnames.remove(item)
|
||||
notifyItemRemoved(acl.subnets.size() + acl.hostnames.indexOf(item))
|
||||
acl.hostnames.remove(item)
|
||||
apply()
|
||||
}
|
||||
is URL -> {
|
||||
notifyItemRemoved(acl.subnets.size() + acl.proxyHostnames.size() + acl.urls.indexOf(item))
|
||||
notifyItemRemoved(acl.subnets.size() + acl.hostnames.size() + acl.urls.indexOf(item))
|
||||
acl.urls.remove(item)
|
||||
apply()
|
||||
}
|
||||
@@ -271,7 +271,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
fun selectAll() {
|
||||
selectedItems.clear()
|
||||
selectedItems.addAll(acl.subnets.asIterable())
|
||||
selectedItems.addAll(acl.proxyHostnames.asIterable())
|
||||
selectedItems.addAll(acl.hostnames.asIterable())
|
||||
selectedItems.addAll(acl.urls.asIterable())
|
||||
onSelectedItemsUpdated()
|
||||
notifyDataSetChanged()
|
||||
@@ -386,7 +386,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
selectedItems.forEach {
|
||||
when (it) {
|
||||
is Subnet -> acl.subnets.add(it)
|
||||
is String -> acl.proxyHostnames.add(it)
|
||||
is String -> acl.hostnames.add(it)
|
||||
is URL -> acl.urls.add(it)
|
||||
}
|
||||
}
|
||||
@@ -432,7 +432,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
|
||||
R.id.action_import_gfwlist -> {
|
||||
val acl = Acl().fromId(Acl.GFWLIST)
|
||||
if (!acl.bypass) acl.subnets.asIterable().forEach { adapter.addSubnet(it) }
|
||||
acl.proxyHostnames.asIterable().forEach { adapter.addHostname(it) }
|
||||
acl.hostnames.asIterable().forEach { adapter.addHostname(it) }
|
||||
acl.urls.asIterable().forEach { adapter.addURL(it) }
|
||||
true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user