How to robustly set Django secret key as environment variable - django

My Django project's secret key contains special characters such as #, #, ^, * etc. I'm trying to set this as an env variable at /etc/environment.
I include the following in the file:
export SECRET_KEY='zotpbek!*t_abkrfdpo!*^##plg6qt-x6(%dg)9p(qoj_r45y8'
I.e. I included single quotes around the string since it contains special characters (also prescribed by this SO post). I exit the file and do source /etc/environment. Next I type env in the terminal: SECRET__KEY correctly shows.
I log out and log back in. I type env again.
This time SECRET_KEY still shows, but is cut off beyond the # character. It's excluding everything beyond (and including) the # character.
How do I fix this issue? Trying with double quotes didn't alleviate anything either. My OS is Ubuntu 14.04 LTS.
p.s. I'm aware environment variables don't support access control; there's a bunch of reasons not to set the Django secret key as an env var. For the purposes of this ques, let's put that on the back burner.

This isn't a Django problem per se. According to this question Escape hash mark (#) in /etc/environment you can't use a "#" in /etc/environment.
I would recommend that you keep regenerating your secret key until you get one without #s -- that should fix the problem. Django Extensions has a command generate_secret_key for this. The side effect of changing the secret key is that current sessions will become invalid, that is, unless you are using it other places in your application.

Easiest way is to generate one using python3 in you linux terminal with following inline script:
python3 -c 'import random; print("".join([random.choice("abcdefghijklmnopqrstuvwxyz0123456789!#%^&*-_") for i in range(50)]))'
this will generate secret key without unsafe characters

As per the django-environ documention you can use unsafe characters in .env file.
https://django-environ.readthedocs.io/en/latest/index.html#tips
To use unsafe characters you have to encode with urllib.parse.encode before you set into .env file.
Example:- admin#123 = admin%28123

Related

What does it mean by the last dash in $(gcc -xc++ -E -v -)? [duplicate]

Examples:
Create an ISO image and burn it directly to a CD.
mkisofs -V Photos -r /home/vivek/photos | cdrecord -v dev=/dev/dvdrw -
Change to the previous directory.
cd -
Listen on port 12345 and untar data sent to it.
nc -l -p 12345 | tar xvzf -
What is the purpose of the dash and how do I use it?
If you mean the naked - at the end of the tar command, that's common on many commands that want to use a file.
It allows you to specify standard input or output rather than an actual file name.
That's the case for your first and third example. For example, the cdrecord command is taking standard input (the ISO image stream produced by mkisofs) and writing it directly to /dev/dvdrw.
With the cd command, every time you change directory, it stores the directory you came from. If you do cd with the special - "directory name", it uses that remembered directory instead of a real one. You can easily switch between two directories quite quickly by using that.
Other commands may treat - as a different special value.
It's not magic. Some commands interpret - as the user wanting to read from stdin or write to stdout; there is nothing special about it to the shell.
- means exactly what each command wants it to mean. There are several common conventions, and you've seen examples of most of them in other answers, but none of them are 100% universal.
There is nothing magic about the - character as far as the shell is concerned (except that the shell itself, and some of its built-in commands like cd and echo, use it in conventional ways). Some characters, like \, ', and ", are "magical", having special meanings wherever they appear. These are "shell metacharacters". - is not like that.
To see how a given command uses -, read the documentation for that command.
It means to use the program's standard input stream.
In the case of cd, it means something different: change to the prior working directory.
The magic is in the convention. For millennia, people have used '-' to distinguish options from arguments, and have used '-' in a filename to mean either stdin or stdout, as appropriate. Do not underestimate the power of convention!

zshrc doesn't convert \u into hostname

There is a problem with my .zshrc file. I want to customise my .zshrc on macOS Catalina. Therefore I added the following to my .zshrc:
export PS1='[\u#\h \$'
Then I called source .zshrc and got the following output:
Is there any solution to display the user and hostname properly?
http://zsh.sourceforge.net/Guide/zshguide02.html#l19
PS1='%n#%m %(!:#:$) '
%(!:#:$) allows you to change the default prompt symbol from % to $ (which it seems you are wanting to do) and still keep # for root.
If you just want to keep the default zsh prompt symbol, use:
PS1='%n#%m %# '
Not sure why you have '[' in there. If you would like to use square brackets around the username and host:
PS1='[%n#%m] %(!:#:$) '
If you would like the current directory in your prompt, add %c.
Also there's no need to use export.

Environment variables in Google Cloud Build

We want to migrate from Bitbucket Pipelines to Google Cloud Build to test, build and push Docker images.
How can we use environment variables without a CryptoKey? For example:
- printf "https://registry.npmjs.org/:_authToken=${NPM_TOKEN}\nregistry=https://registry.npmjs.org" > ~/.npmrc
To use environment variables in the args portion of your build steps you need:
"a shell to resolve environment variables with $$" (as mentioned in the example code here)
and you also need to be careful with your usage of quotes (use single quotes)
See below the break for a more detailed explanation of these two points.
While the Using encrypted resources docs that David Bendory also linked to (and which you probably based your assumption on) show how to do this using an encrypted environment variable specified via secretEnv, this is not a requirement and it works with normal environment variables too.
In your specific case you'll need to modify your build step to look something like this:
# you didn't show us which builder you're using - this is just one example of
# how you can get a shell using one of the supported builder images
- name: 'gcr.io/cloud-builders/docker'
entrypoint: 'bash'
args: ['-c', 'printf "https://registry.npmjs.org/:_authToken=%s\nregistry=https://registry.npmjs.org" $$NPM_TOKEN > ~/.npmrc']
Note the usage of %s in the string to be formatted and how the environment variable is passed as an argument to printf. I'm not aware of a way that you can include an environment variable value directly in the format string.
Alternatively you could use echo as follows:
args: ['-c', 'echo "https://registry.npmjs.org/:_authToken=$${NPM_TOKEN}\nregistry=https://registry.npmjs.org" > ~/.npmrc']
Detailed explanation:
My first point at the top can actually be split in two:
you need a shell to resolve environment variables, and
you need to escape the $ character so that Cloud Build doesn't try to perform a substitution here
If you don't do 2. your build will fail with an error like: Error merging substitutions and validating build: Error validating build: key in the template "NPM_TOKEN" is not a valid built-in substitution
You should read through the Substituting variable values docs and make sure that you understand how that works. Then you need to realise that you are not performing a substitution here, at least not a Cloud Build substitution. You're asking the shell to perform a substitution.
In that context, 2. is actually the only useful piece of information that you'll get from the Substituting variable values docs (that $$ evaluates to the literal character $).
My second point at the top may be obvious if you're used to working with the shell a lot. The reason for needing to use single quotes is well explained by these two questions. Basically: "You need to use single quotes to prevent interpolation happening in your calling shell."
That sounds like you want to use Encrypted Secrets: https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials

Setting file paths with Lua/C++

I have xml profiles stored in a folder that are switched dynamically. But the behavior is absolute path and I need a relative path. The lua code is written to work with both windows paths (back slashes) and with mac paths (forward slashes).
On my mac the path might be /folder/folder/profile1.xml. In normal application the program will return a file/location of profile1.xml. And it will find the next profile in the same folder.
If I direct the application to a new folder using a relative link such as ../profile2.xml then the program will find the new profile and returns the file/location as ../profile2.xml. Then it will not find the next profile within the same folder... it's either looking for the next profile out a step (../) or within the original folder as set by the application. I want it to find the next requested profile within this new folder location.
The existing code that sets the current profile and profile path is this:
local loadedprofile = '' --set by application
local profilepath = '' --set by application and modified below
The relevant switching functions seem to be:
local function setDirectory(value)
profilepath = value
end
local function setFile(value)
if loadedprofile ~= value then
doprofilechange(value)
end
end
local function setFullPath(value)
local path, profile = value:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
profilepath = path
if profile ~= loadedprofile then
doprofilechange(profile)
end
I'm thinking I might need to modify the match criteria of the third function to remove the ../. Maybe something like this removing the optional .'s
local function setFullPath(value)
local path, profile = value:match("(.-)([^\\/]-([^%.\\/]*))$")
profilepath = path
if profile ~= loadedprofile then
doprofilechange(profile)
end
I really have no clue as to how to write this code, I'm just trying to tweak this open source code (MIDI2LR) to suit my needs. In my rudimentary understanding of the code it seems the match criteria is overly convoluted. But I would like to know if I am reading it right. I interpret it as:
:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
(.-) --minimal return
( )$ --from the end of profile path
[^\\/]- --starts with \ or \\ or /, 0 or more occurrences first result
%.? --through, with dots optional
[^%.\\/]* --starts with . or \ or \\ or /, 0 or more occurrences all results
If I am reading it right it would seem the first "starts with" is entirely redundant, or that the "from the end" should be associated with the second "starts with."
I have commented out the setFullPath function without the desired results which makes me think that a match requirement might be needed added to the setDirectory function.
Any help is greatly appreciated as I am in way over my head. Thanks!
Your reading of the match is incorrect, here is a more accurate version:
:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
(.-) -- Match and grab everything up until the first non slash character
( )$ -- Grab everything up until the end
[^\\/]- -- Starts with any character OTHER THAN \ or /, 0 or more occurrences first result
%.? -- single dot optional in the middle of the name (for dot in something.ext)
[^%.\\/]* -- Any character OTHER THAN . or \ or /, 0 or more occurrences
A few notes - %. is a literal dot. [^xyz] is the inverse class, so every character other than x, y, or z. \\ is actually just one backslash, this is due to the escaping in a string.
This simpler version would break it in a similar way that is easier to work with: value:match("(.-)([^\\/]+)$")
You may want to provide more information on the profile loading behavior, its hard to tell what you need the code to do. What value would path and profile have in the example you give?

Change WiFi WPA2 passkey from a script

I'm using Raspbian Wheezy, but this is not a Raspberry Pi specific question.
I am developing a C application, which allows the user to change their WiFi Password.
I did not find a ready script/command for this, so I'm trying to use sed.
I pass the SSID name and new key to a bash script, and the key is replaced for the that ssid block within *etc/wpa_supplicant/wpa_supplicant.conf.*.
My application runs as root.
A sample block is shown below.
network={
ssid="MY_SSID"
scan_ssid=1
psk="my_ssid_psk"
}
so far I've tried the following (I've copied the wpa_supplicant.conf to wpa.txt for trying) :
(1) This tries to do the replacement between a range, started when my SSID is detected, and ending when the closing brace, followed by a newline.
SSID="TRIMURTI"
PSK="12345678"
sed -n "1 !H;1 h;$ {x;/ssid=\"${SSID}\"/,/}\n/ s/[[:space:]]*psk=.*\n/\n psk=\"${PSK}\"\n/p;}" wpa.txt
and
(2) This tries to 'remember' the matched pattern, and reproduce it in the output, but with the new key.
SSID="TRIMURTI"
PSK="12345678"
sed -n "1 !H; 1 h;$ {x;s/\(ssid=\"${SSID}\".*psk=\).*\n/\1\"${PSK}\"/p;}" wpa.txt
I have used hold & pattern buffers as the pattern can span multiple lines.
Above, the first example seems to ignore the range & replaces the 1st instance, and then truncates the rest of the file.
The second example replaces the last found psk value & truncates the file thereafter.
So I need help in correcting the above code, or trying a different solution.
If we can assume the fields will always be in a strict order where the ssid= goes before psk=, all you really need is
sed "/^[[:space:]]*ssid=\"$SSID\"[[:space:]]*$/,/}/s/^\([[:space:]]*psk=\"\)[^\"]*/\1$PSK/" wpa.txt
This is fairly brittle, though. If the input is malformed, or if the ssid goes after the psk in your block, it will break. The proper solution (which however is severe overkill in this case) is to have a proper parser for the input format; while that is in theory possible in sed, it would be much simpler if you were to swtich a higher-level language like Python or Perl, or even Awk.
The most useful case is update a password or other value in configuration is to utilize wpa_cli. E.g.:
wpa_cli -i "wlan0" set_network "0" psk "\"Some5Strong1Pass"\"
wpa_cli -i "wlan0" save_config
The save_config method is required to update cfg file: /etc/wpa_supplicant/wpa_supplicant.conf