Pass credentials to karate .feature file from Jenkins server [duplicate] - jenkins-pipeline

I'd like to incorporate GitLab CI into my Karate testing. I'd like to loop through my tests with different user names and passwords to ensure our API endpoints are responding correctly to different users.
With that in mind, I'd like to be able to store the usernames and passwords as secure environment variables in GitLab (rather than in the karate-config as plain text) and have Karate pull them as needed from either the karate-config or the feature files.
Looking through the docs and StackOverflow questions, I haven't seen an example where it's being done.
Updating with new information
In regards to Peter's comment below, which is what I need I am trying to set it up as follows:
set client id in karate-config:
var client_id = java.lang.System.getenv('client_id');
in the actual config object:
clientId: client_id
In my feature file tried to access it:
* def client_id = clientId
It still comes through as null, unfortunately.

You can read environment variables in karate using karate.properties,
eg,
karate.properties['java.home']
If this helps you to read the environment variables that you are keeping securely on your gitlab, then you can use it in your karate-config for authentication.
But your config and environment variable will look cumbersome if you are having too many users.
If you want to run a few features with multiple users, I would suggest you look into this post,
Can we loop feature files and execute using multiple login users in karate
EDIT:
Using java interop as suggested by peter:
var systemPath = java.lang.System.getenv('PATH');
to see which are all variables are actually exposed try,
var evars= java.lang.System.getenv();
karate.log(evars);
and see the list of all environment variables.

Related

How to set the application domain in Heroku env var

Given an application URL on Heroru like app-123.herokuapp.com, how can I set this value into an environment variable?
I need to set an email template, with the correct links to the app, so there is no HTTP request information available, but I want to have the links with the correct URL.
I'm using Ruby on Rails and using an environment variable, but once I create review apps, with dynamic URL's I cannot rely on this.
Disclaimer: This works only for the review apps, as they are my concern when posting the question.
We can make use of the injected environment variables, as described in the documentation: https://devcenter.heroku.com/articles/github-integration-review-apps#injected-environment-variables
So, given that every application domain will be herokuapp.com we can guess the application address but concatenation of protocal, app and domain:
"https://#{HEROKU_APP_NAME}.herokuapp.com"

SFAuthorizationPluginView without UI

I have been crawling through various forums and blogs for an AuthorizationPlugin example or understanding which can show me how to create a mac authorization plugin that do not affect any UI components. I want to use it for a remote access kind of solution. I have been able to get NameAndPasswordPlugin example work. But I am not able to achieve below requirements:
Do not change the default UI. i.e not have any custom UI components
Ability to read and write into default UI fields, especially username (if any) and password
Work on need basis. i.e. I need the mechanism to pass through when remote access session is not ON. In that case I want it to fall back to loginwindow:login mechanism
Also how would it communicate with outside world ? I was not able to read or write into files from plugin. I saw an example where some pipes where used. not sure what the recommended method
You don't need a SFAuthorizationPluginView, you just need an authorization plugin. You insert your plugin into the list of plugins and it can read from contexts set by previous plugins and write to or create contexts for later plugins.
For example, if you are working with console login this bash command shows you what mechanisms are configured (mechanisms are instances of a plugin)
security authorizationdb read system.login.console
If you add your plugin after builtin:authenticate,privileged then you can use this code in your mechanismInvoke function to read the values.
err = mechanism->fPlugin->fCallbacks->GetHintValue(mechanism->fEngine, "username", &value);
if (err == noErr) {
//Log the event
os_log(OS_LOG_DEBUG, "Login for user '%{public}s'.",(const char *)value->data);
}
where mechanism->fPlugin->fCallbacks->GetHintValue and mechanism->fEngine are the callback and engineref you setup as part of your plugin. There is also a "SetContextValue" function for writing the username or password.
You will need to write an authorization plugin which will set the context values "username" (kAuthorizationEnvironmentUsername) and "password" (kAuthorizationEnvironmentPassword). Then set result as kAuthorizationResultAllow. You would also need to place your plugin just before loginwindow:login.

How can I authorize a Google Service Account without the default credentials file?

I have a Google Service Account that my app uses to retrieve data from Google Analytics.
When I created the account I downloaded a client_secrets file with all the necessary information for authorization via OAuth, and I recorded the path to this file in an environment variable called GOOGLE_APPLICATION_CREDENTIALS as per Google's documentation.
I can now get an authenticated client like this:
authorization = Google::Auth.get_application_default(scopes)
This method reads the credentials out of the file, which works locally, but my app is hosted on Heroku where file storage is impossible.
The documentation states that I can either provide this file (can’t), run my app on an official Google Service (won’t), or experience an error.
How can I authenticate my service account without the client_secrets file?
I found the answer in the source code of the google-auth-library-ruby gem.
It turns out that there is another option: take the values from the client_secrets file and put them in environment variables named GOOGLE_ACCOUNT_TYPE, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_EMAIL and GOOGLE_PRIVATE_KEY respectively.
If these keys are populated, the credentials will load from there. Not a whisper of this in the docs, though.
Since this is one of the main results that returns when searching google for "google service credentials ruby," I thought I would add my very recent experience to the list of possible answers.
Though you can do the method mentioned in the first answer, I found an alternate solution that works well with Heroku. I know it has been somewhat mentioned in another post, but the key thing that was left out was how to properly store the full GOOGLE_APPLICATION_CREDENTIALS .json file so that it can all be kept within one env on Heroku and not have special characters blow up your app when tryin to
I detail my steps below:
Obtain your GOOGLE_APPLICATION_CREDENTIALS json file by following Google's instructions here: Getting Started with Authentication
That will, of course, contain a json object with all the spaces, line returns, and quotations that heroku simply doesn't need. So, strip out all spaces and line breaks...AND PAY ATTENTION HERE -> EXCEPT FOR THE LINE BREAKS WITHIN THE 'BEGIN PRIVATE KEY' SEGMENT. Basically turn the json into one long string. Use whatever method you feel comfortable with.
Once you have a single line json file with whitespace and line breaks removed, you will need to add it to Heroku by running the following command:
heroku config:set GOOGLE_APPLICATION_CREDENTIALS="$(< /Users/whoever/Downloads/[CREDENTIAL_JSON_FILENAME].json)" --app your-app
For my situation, I needed to have the service account available on initialization, so I placed this in an initializer in my rails app:
GOOGLE_SERVICE_ACCOUNT_CREDENTIALS=Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: StringIO.new(ENV['GOOGLE_APPLICATION_CREDENTIALS'])
)
Notice the StringIO.new() method. the #make_creds wants a file. So, fake it as such by using StringIO.new.
This method works perfectly.
If you need this to work differently on your local machine, you can always store the .json somewhere in the project and reference it through a file location string. Here is my full initializer:
require 'googleauth'
#https://www.rubydoc.info/github/google/google-auth-library-ruby/Google/Auth/ServiceAccountCredentials
if Rails.env == "test"
GOOGLE_SERVICE_ACCOUNT_CREDENTIALS =
Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: File.open('lib/google/google_application_credentials.json')
)
elsif Rails.env != "development"
GOOGLE_SERVICE_ACCOUNT_CREDENTIALS =
Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: StringIO.new(ENV['GOOGLE_APPLICATION_CREDENTIALS'])
)
end
If you are using a gem like dotenv you can store the formatted json string as an ENV or you can just reference the file location in the ENV
I hope this helps someone.
I found this
require "google/cloud/bigquery"
ENV["BIGQUERY_PROJECT"] = "my-project-id"
ENV["BIGQUERY_CREDENTIALS"] = "path/to/keyfile.json"
bigquery = Google::Cloud::Bigquery.new
more detail:
https://github.com/googleapis/google-cloud-ruby/blob/master/google-cloud-bigquery/AUTHENTICATION.md

where to store api key in Django

I currently build web app which is using external MongoDb via Mongolabs.
The api is based on personal key using in urls. As docs says e.g.:
Here’s an example of a complete Resource URL:
https://api.mongolab.com/api/1/databases?apiKey=**2E81PUmPFI84t7UIc_5YdldAp1ruUPKye**
So the question is how to securely store such api key 2E81PUmPFI84t7UIc_5YdldAp1ruUPKye
Reading Django docs about Cross Site Request Forgery but stil do not understand where the key is recorded.
There are two ways to do this.
One way is to have a local_settings.py file that's imported in the main settings.py file and put into .gitignore so it's not in git. Some people however think this isn't good practice, because it might tempt to put complex things in there that aren't in VCS, so people effectively have different environments. I however am fine with it.
try:
from local_settings import *
except ImportError:
pass # No local_settings file
The other way (recommended by dislikers of the first way) is by setting it via environment variables, and reading these in settings.py.
MONGO_API_KEY = os.environ['MONGO_API_KEY']
You'd then have to pass the environment variable somehow though. E.g. via uwsgi's environ setting, or by setting it in your bash with export, or via another way.
I would load it in the settings file from an environment variable. Have a look at the Django Settings
One alternative is to use the library django-fernet-fields that uses the library cryptography.
The usage is very simple. In your model you need to add a new field:
from django.db import models
from fernet_fields import EncryptedTextField
class MyModel(models.Model):
apikey = EncryptedTextField()
By default, the field is going to be encrypted using the SECRET_KEY from your settings. So if you change it or lose it, you will not be able to access your data.
For better security, you can save your SECRET_KEY as an environment variable, and then pass it to the settings file.
import os
SECRET_KEY = os.environ.get('APP_SECRET_KEY', 'unsafe-secret-key')
django-fernet-fields
Quick answer:
Store in .env
Read in settings.py

How should I store my api key on heroku so that it still stays secret instead of embedding in web page code

I have built a flak app, locally I have stored it as environment variable, but I do not know how should I store my api key on heroku so that it still stays secret instead of embedding in web page code ?
Any help will be greatly appreciated.
You can store your api-key as environment variables as these are perfectly secure:
go to you local folder and run heroku config:set key_one=value_one key_two=value_two and more.
Note: run above commands in the same folder which points to your repository.
once you set the environment variable you can access this key value pair in you code directly as:
var api_key = process.env.key_one;
You can also easily add or edit your config variables from your heroku app’s Settings tab, look here at Heroku's official documentation.

Resources