Setting variables in IF-statements (Batch)? - if-statement

Ok i got this basic IF-statement. I want to set a user role, based on it's username. It does look like though, that the set statement never gets executed and therefore i got an empty echo.
if "%username%" == "admin" (
set role = "admin"
) else (
set role = "user"
)
echo %role%
Did I miss something or may it be that Windows just does not support that?

Remove the spaces. You are now setting a value to the environment variable role (with a trailing space that Stack Overflow won't show). Also, the role becomes "admin" (including quotes and a leading space, that is, again, not visible here).
You can verify this by running set without parameters from the command line. It will give you a list of all variables, in which you can clearly see the undesired spaces.
if "%username%" == "admin" (
set role=admin
) else (
set role=user
)
echo %role%
The only reason you still need quotes with an if statement, is that the statement would become invalid if %username% didn't exist/was empty. In that case, the line would become:
if == admin (
... Which is of course invalid. It doesn't even need to be quotes, you could also write:
if %username%XYZ == adminXYZ (

Related

Regex to match within specific block

I am trying to match a string between two other strings. The document looks something like this (there are many more lines in the real config):
#config-version=user=user1
#conf_file_ver=1311784161
#buildno=123
#global_vdom=adsf
config system global
set admin-something
set admintimeout 8289392839823
set alias "F5"
set gui-theme mariner
set hostname "something"
end
config system accprofile
edit "prof_admin"
set secfabgrp read
set ftviewgrp read
set vpngrp read
set utmgrp read
set wifi read
next
end
config system np6xlite
edit "np6xlite_0"
next
end
config system interface
edit "dmz"
set vdom "asdf"
set ip 1.1.1.1 255.255.255.0
set type physical
set role dmz
next
edit "wan1"
set vdom "root"
set ip 2.2.2.2 255.255.255.255
set type physical
set alias "jklk5"
set role wan
next
end
config system physical-switch
edit "sw0"
set age-val 0
next
end
config system virtual-switch
edit "lan"
set physical-switch "sw0"
config port
edit "port2"
next
edit "port3"
next
edit "port4"
next
edit "port5"
next
edit "port6"
next
end
next
end
config system custom-language
edit "en"
set filename "en"
next
edit "fr"
set filename "fr"
next
end
config system admin
edit "user1"
set vdom "root"
set password ENC SH2Tb1/aYYJB2U9ER2f5Ykj1MtE6U=
next
edit "user2"
set trusthost1 255.255.255.255 255.255.255.224
set trusthost2 255.255.255.254 255.255.255.224
next
end
config system ha
set override
end
config system replacemsg-image
edit "logo_fnet"
set image-type gif
set image-base64 ''
next
edit "logo_fguard_wf"
set image-type gif
set image-base64 ''
next
edit "logo_fw_auth"
set image-base64 ''
next
edit "logo_v2_fnet"
set image-base64 ''
next
edit "logo_v2_fguard_wf"
set image-base64 ''
next
edit "logo_v2_fguard_app"
set image-base64 ''
next
end
I care about every "edit" block between "config system admin" and its corresponding "end". Each "edit" block represents a user and I need to know if a user block (edit "" ...stuff on new lines... next) is missing the "set password" line.
This expression (multiline) captures the "edit "en"..." under "config system custom-language":
\h*edit ".*\n(?:\h*+(?!next|set password).*\n)*\h*next\n
Now I need to make sure to ignore any config sections before or after "config system admin". I tried this:
(?<=config system admin\n)\h*edit ".*\n(?:\h*+(?!next|set password).*\n)*\h*next\n(?=end)
That change results in zero matches. But if I change the lookbehind to:
(?<=config system custom-language\n)
Then I get a match, but it is in the wrong config block again. I tried sticking [\S\s] in front, but that results in zero matches:
[\S\s](?<=config system admin\n)\h*edit ".*\n(?:\h*+(?!next|set password).*\n)*\h*next\n(?=end)
How do I take the "set password" matching and make sure it only happens in between "config system admin" and its corresponding "end". I only need the first result, but getting multiple is fine. I am using PCRE2.
The following pattern will starts with edit, stops before end or edit, and will not allow password, config system or set filename.
It is a bit long and clumsy but it does find regular users if the word password is absent and does not match the 2 opening blocks.
As noted it the comments it could malfunction if the keywords are found elsewhere in the file.
/edit((?!edit)(?!(edit|password|config sys|set filename))[\w\W])*(?=(edit|end))/gm
If you have the possibility to use a simple script, bash for example, that could read line by line we could build something simple that would be more reliable.
I think you want to work on this task from two levels. First, find the data that is in those config blocks, and then examine the users within them.
Here's something that is far simpler that may do what you need.
First, you want to look only at the lines between "config system admin" and "end", so use awk to find those.
$ awk '/^config system admin/,/^end/' config.txt
config system admin
edit "user1"
set vdom "root"
set password ENC SH2Tb1/aYYJB2U9ER2f5Ykj1MtE6U=
next
edit "user2"
set trusthost1 255.255.255.255 255.255.255.224
set trusthost2 255.255.255.254 255.255.255.224
next
end
Now search those results for either "edit" or "set password":
$ awk '/^config system admin/,/^end/' config.txt | grep -E 'edit|set password'
edit "user1"
set password ENC SH2Tb1/aYYJB2U9ER2f5Ykj1MtE6U=
edit "user2"
You can now eyeball the results and see who has set a password and who hasn't.
If you need to get more precise, then you can write a little more code to find "edit" lines that aren't followed by "set password".
In any case, the key is to break the problem into smaller problems.
Update based on your new example text:
(?<=config system admin.*?)(edit "[^"]+"(?!.*?set password.*?next).*?next)(?=.*?end)
It requires the global and singleline flags. If you can't use singleline, replace dot (.) with [\s\S].
Explanation:
(?<=config system admin.*?) - look behind for 'config system admin' followed by any characters (non greedy)
edit "[^"]+" - match 'edit' and a username
(?!.*?set password.*?next) - look ahead for NOT 'set password', followed by any characters and 'next'
.*?next - match any characters and 'next'
(?=.*?end) - look ahead for any characters and 'end'
This should give you the text between 'edit' and 'end' when there's no 'set password' between.

Matching text between strings and missing string

I have a firewall config file and am trying to write an expression that will match when a user does not have a password.
The config is long, but a snippet of it looks like this:
config system custom-language
edit "en"
set filename "en"
next
more lines
could be many lines
end
config system admin
edit "user1"
set trusthost1 1.1.1.1 255.255.255.254
set vdom "root"
maybe more lines
maybe many more lines
set password ENC asdfasdfadsfasdfadsfasdf
next
edit "user2"
set trusthost1 1.1.1.1 255.255.255.254
set vdom "root"
maybe more lines here too
next
end
config system replacemsg-image
edit "logo_fnet"
set image-type gif
set image-base64 ''
next
end
other lines
end
Note that user2 is missing "set password ENC...". I know that I only want to match text between "config system admin" and its corresponding "end". I also know that each user starts with "edit "<username>"" and ends with "next".
I have the following regex, which at least starts at the rights spot (config system admin) but seems to be matching on both user blocks (and "config system replacemsg-img" for some reason):
(config\ssystem\sadmin(\n|.)*)(edit\s\".*\"(\n|.)*(?!set\spassword\sENC)(\n|.)*next)(\n|.)*end
How would I write the expression so it only returns true because "user2" (in this example) is missing "set password ENC"? I am using PCRE2.
EDIT:
After some additional work, I have the following (not working, but maybe closer?) expression:
(?<=(config\ssystem\sadmin))((\n)(\s+edit\s\".*\"(\n))((.|\n)*)((?!set\spassword).)*)(\nend)?
This begins the capture at "config system admin". But, in the regex testers I tried, it also highlights all the way down to the last "end", instead of stopping at the first for some reason.

Django user has_perm returning false even though group has permission

I'm running into a problem where I've created a Group with certain permissions, and successfully added a user to that group, but when I check user.has_perm with that permission, I'm getting False.
I've even tried things like saving the user and re-fetching them from the database to avoid caching issues, but it makes no difference.
The terminal output below should give an idea of what's happening
# Get a group from the database and check its permissions
> special_group = Group.objects.get(name="special_group")
> a_perm = special_group.permissions.all()[0]
> a_perm.codename
'some.permission'
# Get a user from that group and check if they have those permissions
> a_user = special_group.user_set.all()[0]
> a_user.has_perm(a_perm.codename)
False
> a_perm.codename in a_user.get_group_permissions()
False
# Curiously, get_group_permission sort of returns what we need
> a_user.get_group_permissions()
{'ContentType object.some.permission'}
# If we essentially coax the group_permissions into a list and pull an item out of there, has_perm returns true, but this string is different to a_perm.codename
> a_user.has_perm(list(a_user.get_group_permissions())[0])
True
Does anyone know why has_perm isn't behaving as I'm expecting? We are using Django 1.10.3.

CALABASH - Renaming screenshot filenames without the iterator

In Calabash you can take a screenshot and rename it to whatever you want and save it to any directory like so:
screenshot({:prefix => "some/directory", :name=>"some_name.png"})
However it will always save as some_name_0.png and the next one will be some_name_1.png.
Does anyone know how to rename the filename completely without the iterator?
You can also just pass text from your steps on what to save the screendump as.
I have done this to easily set the prefix and name and only take the screendumps when I add "capture=true" to the start command.
def take_picture(prefix, name)
if ENV["capture"] == 'true'
screenshot(options={:prefix=>prefix, :name=>name})
end
end
And from the steps I call it like this(this is example does not add special prefix:
take_picture("","SettingsMenu1")
In lib/calabash-cucumber/failure_helpers.rb the iterator is defined via ##screenshot_count ||= 0 then ##screenshot_count += 1
So I just overwrite that.

Varnish: Remove Some Cookies Issue

I am using Varnish 3.0.5 and Apache 2.4.6 with PHP 5.4.21
I have read the documentation here which says
Varnish will, in the default configuration, not cache a object coming from the backend with a Set-Cookie header present. Also, if the client sends a Cookie header, Varnish will bypass the cache and go directly to the backend.
So, in an effort to have Varnish cash pages, I need to remove the non-important cookies being sent to Varnish from the client. At present, there is only one cookie being sent as depicted here:
My default.vcl file has the following code, which is supposed to remove the cookie(s) whose name starts with the underscore character, or whose name is "has_js":
sub vcl_recv {
# //Remove all cookies that begin with an underscore
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_\.a-z0-9]+|has_js)=[^;]*", "");
# //Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s", "");
# unset req.http.Cookie;
...
I have tested the regex from this application and it finds a match for the cookie being sent from the client as noted in the image above.
When I run
]# varnishes
from the command line, I find that I have no "hits" only "misses". However, if I uncomment the
unset req.http.Cookie;
line, so that it removes all the Cookies (of which there should be only one, I assume from the image above) I get the hits I'd expect.
I'm hoping someone can point me in the right direction as to what I may be missing?
Thanks.
The problem with the code above is this line in the default.vcl that gets called later on:
if (req.http.Authorization || req.http.Cookie) {
# /* Not cacheable by default */
return (pass);
}
It is commented out, but still gets called as part of the default behavior of Varnish.
As you can see, it is asking if
req.http.Cookie
exists. In the code provided in the question, the variable will still exist, but will be an empty string. This empty string will still pass the logical test in the default Varnish behavior. As a result, the following code must be added after the code which removes the undesirable cookies:
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_\.a-z0-9]+|has_js)=[^;]*", "");
# //Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
Now, if the req.http.Cookie is empty, the object will be removed and Varnish will cache as expected.