Nacho4d - Programming notes

1. Installing GnuPG

On various Linux flavors it is apparently available by default. On macos we can brew it.

brew install gpg

2. Generate Keys

I strongly recommend not to use the short version --gen-key because it uses by default RSA algorithm which does not allow key signing. I recommend to use --full-generate-key and use kind "DSA and Elgamal" to generate the pair of keys (Public key and Private key). You will be required to enter a password, this password will be required every-time a message needs to be decrypted because it will use your private key.

Export private key

Import public key

To simply import the key we can use the --import command.

gpg --import OTHERID.pub.gpg

HOWEVER, at this point using this new key to decrypt something will lead to WARNings because the key is not verified, not trusted, not checked, etc. Please make sure you have the right key (check the fingerprint) and trust it. For full conceptual explanation see the official docs here and here

Import private key

We use the same --import command. gpg will recognize if key is private or public :)

gpg --import blake.secret.gpg
# (type password)

To see the list of private keys in the keyring:

gpg --list-secret-keys

Asymmetric encryption and decryption

Asymmetric cryptography means the message is encrypted with the public key and decrypted with the private key that is paired with that public key. This means, the sender cannot decrypt the message. Only the receiver can decrypt it (Off-course, unless the message was sent to self)

Encrypt a file

To asymmetrically encrypt a file we need to have the public key of the receiver in the keyring.

We can skip the --armor or -a option to have encrypted files in binary format.
Not recommended but we can skip the --sign or -s option to not sign it.
If --local-user or -u is skipped then the default key will be used.

Decrypt a file

To asymmetrically decrypt a file we must have the private key that corresponds to the public key that was used at encryption time.
To decrypt and verify the sign:

gpg --output file.doc --decrypt file.doc.gpg

This command will requires two things to succeed:

A kind of key able to sign (RSA does not do it, that is why I suggested to use DSA and Elgamal kind).

Option --sign or -s should be passed at encryption time.

Not recommended but if you need to skip sign verification:

gpg --output file.doc --skip-verify --decrypt file.doc.pgp

Symmetric Encryption

Encrypt a file (Symmetric encryption)

Symmetric encryption requires just a password. Anyone with this password should be able to decrypt to file.

gpg --output file.doc.gpg --symmetric file.doc
(enter password)

More

There are several ways of converting between arrays and lists but there are some gotchas when converting with non-streams methods. In reality, this kind of conversion should not happen that often (this could be an indicator of a bad/immature interface).
I barely remember all these methods and an extra reason if because of the lack of API asymmetry or consistency in Java constructors/factory methods.
For example, since there is Arrays.asList(...) I would expect Lists.asArray(...) but No!. There is mylist.toArray()!?.
The same problem is not gone when using streams but at least the result array/list does not have the pitfalls non-stream approaches have.

To me, it looks like using Streams is the easiest way of doing this kind of tasks since Java 8 is quite common nowadays :)

These are the packages I would be using...

import java.util.*;
import java.util.Arrays;

Creating arrays

Create array of ints (literal)

int[] array = {7, 8, 9};

Create array of ints (non literal ?)

int[] array = new int[3];
array[0] = 7;
array[0] = 8;
array[0] = 9;

Pretty print array:

String pretty = Arrays.toString(array);
System.out.println(pretty);

Creating lists

Create list of ints. Since List can hold only objects primitives must be boxed. In this case they are boxed into Integer.

More Links:

This is kind of old topic but information seems to be fussy to me, I couldn't find all the answers in a a single place so here are my notes....
Let's say we have a server which uses https but with a self signed certificate (オレオレ証明書), and your iOS app needs to do requests to it. Since iOS 8, if I well remember, iOS apps don't work with these servers without additional settings. Official info from Apple suggest creation of a certificate which means changes in server side which is not an option in my case.
Below I setup my app so requests can be done with an insecure certificate only to my server. This should be done only for development/testing purposes and should not be in production

Official (and poor) documentation regarding NSAppTransportSecurity can be found in InfoPlistKeyReference - CocoaKeys. Beware that key names are not even correct, see NSExceptionAllowsInsecureHTTPLoads, instead of NSTemporaryExceptionAllowsInsecureHTTPLoads, etc.

2. Make sure challenge is fulfilled in the WKWebView

Implement the navigation delegate. Remember, at least you should have a naive filter like below. Accepting everything is much more dangerous. This should be done only for testing/developing purposes.

Note: This framework (and below code) is not for directly zipping/unzipping files. The zip format is for compresssing various files and/or directories which require more metadata. The structure of a PKZip file.

Get and show current location

Get current location is a task of CoreLocation. We need to receive updates from CoreLocationManagerDelegate so render current location in our mapView.
Location itself will be stored in fromLocation and fromLocationAnnotation will be used to represent a pin at such location.

Previous method adds an MKPointAnnotation to the mapView. MKMapView will render the default annotation view for the given annotation. So far we our current location :)

Customize the pin

To customize the view we need to implement MKMapViewDelegate method.
When we add MKAnnotation (usually a MKPointAnnotation) the map view will consult its delegate to see if there is a view for the given annotation. If we return nil or do not implement the delegate method is will draw the default view (a red pin).
Usually you want to create a view with some extra information special to the location (For example number of likes for that place, an explanation of the place, etc) and a way to pass data from your model to the view is via a subclass of MKAnnotation. Each MKAnnotationView object will have a reference to an MKAnnotation so we have put data here.

I am using a regular MKAnnotationView and simply customizing the image according the given data (I am creating an UIImage on the fly). In my small app I have just a few annotations so this does not cost me anything. If performance becomes a problem then we should create subclass MKAnnotationView and render things there rather than setting a different UIImage every time, to really reuse it.
If you are curious about image(text: annotation.label) check code here.

Get and show location from an address

The act of find coordinates from a address text is called Geo Coding. Happily there is a geocoder class in CoreLocation so lets use it:

2. Generate swagger file

This looks a bit lengthy. but IMO should work for most people. Please adjust locations to have a list of all packages where your endpoints classes are (or swagger file will contain 0 endpoints). This should be inside build/plugins

I have attached generate goal of this plugin to the compile phase. Hence we should be able to generate target/generated-docs/swagger/swagger.yaml file with:

mvn compile

2. Generate asciidoc file

I set the input to be the output of the previous plugin. Also set the output file (not output directory) so everything is concatenated in a single file. Place this inside build/plugins after swagger-maven-plugin.

Recently I use flex-box a lot. Flex-box is kind of UIStackView in iOS (Flex-box spec was first than UIStackView).
I wrote some samples so I don't forget specially about flex-grow, flex-shrink and flex-basisJSBin - Flexbox examples - https://jsbin.com/kosajor
-- Sorry I don't have a PRO account so embedded code is not available :(

The devops service of Bluemix is nice but at this moment it uses java 7 by default.
In order to compile to Java 8 we should modify the pom.xml so maven will try to use java8 when compiling (sames as this post in Japanese):

We should also modify the configuration of the build stage in the pipeline. We need to set JAVA_HOME so maven can find it (At first I tried to do set JBP_CONFIG_IBMJDKas adviced via the manifest.yaml but it didn't work).

There are some features in WAS Liberty Server (like apiDiscovery-1.0) that require stuff (like keyStore and basicRegistry) that will require passwords. If those passwords are note encoded we get warnings. It is was not clear to me how to encode a password. These are my notes :)

Encoding a password

We need the securityUtility command from bin directory of the server installation directory. And simply use encode subcommand. Since I am using the default key store defaultKeyStore everything is very simple:

I usually use Visual Code for coding in javascript and other client-side development. That means that I usually have .vscode/launch.json, .vscode/launch.json and jsconfig.json which are good for development but not needed in the final war file (created when doing mvn -B package)

I realized all code and stuff I write here does not have a license. I never really thought of such necessity since code I write here are usually just chunks of code, not finished products. But some people might mentioned recently. So today I am releasing all this work under the BSD Zero Clause License (0BSD).

Basically, it allows unlimited freedom with the software without the requirements to include the copyright notice, license text, or disclaimer in either source or binary forms.

Copyright (C) 2016 by Guillermo Ignacio Enriquez Gutierrez <nacho4d@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Notes

In IBM WAS Liberty the cookie can be configured via server.xml too. In httpSession, cookieSecure and cookieHttpOnly are by default false and true respectively. See www.ibm.com/support/knowledgecenter/ja. I personally prefer not to touch the server.xml as much as possible.

What are Cloudant Analizers?

Analyzers are settings which define how to recognize terms within text. This can be helpful if you need to index multiple languages.

I decided to try some of the analyzers and put my results here. Test text has two completely different languages (English and Japanese) and some other symbols which I think it is enough to find out how different analysers behave.

Experiment

We're caught in a trap\n
I can't walk out\n
Because I love you too much baby♬.\n
Sent by nacho@email.com at 2016-07-07 18:00:29 +0900 ★\n
はまった罠から\n
出られないんだ\n
ほんとに君に首ったけなんだ♬.\n
２０１６年７月７日１８時０分２９秒にnacho@email.jpより ★

I added new lines \n, ♬★ marks, an email and a timestamp to make it more interesting ;-]

Commentaries

The only notorious difference between standard and classic is the treat of "2016-07-07" and emails. standard got the emails wrong.

email looks like standard but with the emails right

whitespace looks like a good option when text has symbols (ie.: ♬, ★). There are still there as tokens!

keyword just one token. I think it would be useful for exact match searches

None of the analyzers, not even keyword preserved the new line character \n.

Several occurrences of the same string are valid. (ie.: "i" and "★")

I find funny "we're" became "we'r" when english was used. Also "baby" became "babi".

Japanese words were tokenized as characters in english. Makes really hard (if possible) to do a useful search using Japanese

I am depressed that spanish didn't get my name "nacho" right. For some reason it became "nach". I guess it is trying to get the root of it, since there is also nacha, nachito, nachita, nachos, nachas, etc.

cjk (chinese/japanese/korean) complete broke the japanese words. I know it is hard to parse Japanese but cjk is not helping at all here.

I have no idea why I tried arabic I literally have 0 knowledge of the language to comment something about it.

Create application

Next, we add platforms. Here I only add iOS and Android but there are a lot more.

cordova platform add ios --save
cordova platform add android --save

Working with git

I am not really into Cordova applications but as any other platforms I tend to have my repositories the smallest possible.
There should be a command that downloads all dependencies so all users are able to have the same environment in the end.
For such reason I ignore everything in platforms/ and plugins/ directories

My .gitignore:

platforms/
plugins/

The command that will make my environment ready will be:

cordova prepare

It copies files for specified platforms, or all platforms, so that the project is ready to build with each SDK.

Result

This is not a fully automated command for making merge request, instead it is tiny helper command that will take you to the right place in the browser to complete your merge request with one click.

BTW, Why not to do everything with Gitlab API?
It is fully possible. Actually I was trying to do so but in the way I realized that is not what I need because in a merge request you want to set a description (writing a description in the terminal is not better than doing it in the browser), you also will want to assign somebody to review your code (searching for other gitlab users in the terminal is not easier than the browser pulldown menu), you probably want to have a milestone, and maybe other details...

If you still want to do it fully programatically I have some hints at the end of this post :p

Setup

Copy above script as git-mr and place it somewhere in the $PATH and make sure it has executable permissions using chmod

chmod +x ~/.bin/git-mr

Usage

git push origin -u feature/myfeature
git mr

Voilà!(browsers opens and you are just one click away from completing your merge request)
If you still want to do it programatically with Gitlab API, we need a project id an authentication token to be able to call create merge request API.

POST /projects/:id/merge_requests

Get Authentication Token

We can request the user to enter his/her login and password once and store that in the keychain. Below code is how to retrieve a previously stored password from the keychain

Get Project ID

I have tried doing ${GROUP}/${PROJECT_NAME} and ${GROUP}%2F${PROJECT_NAME} without luck so I got the project by using project search API. Unfortunately gitlab search API is not very powerful yet so we need to search results and get the id of the project that exactly matches our project. Here I am using jq

Creating a new Liberty Server

Create a server using the Wizard.
Click File > New > Server
Click Next

Select WebSphere Application Server Liberty
Click Next

Select Install from an archive or repository
Click Next

Enter the Destination path (This will be the place where the server will live)
Select Download and install a new runtime environment from ibm.com
Select WAS Liberty V8.5.5.9 with Java EE 7 Full Support
Click Next

Click Install for the following bundles:

Base Bundle

Liberty Core Bundle

V9 Bundle for Java EE 7 Full Support

V9 Bundle for Java EE 7 Web Profile

Click Next

Accept the terms
Click Next

Select Stand-alone server
Click Next

Enter a name for your server. I usually leave it as defaultServer
Click Finish

Finally a confirmation alert will show. Now we have our Liberty server installed in Eclipse. Almost ready :)

Adding a simple keyStore

Since we have javaee-7.0 feature enabled we need to add a keystore, otherwise we will not get rid of the following error:

The enabled features require that a keyStore element and a user registry are defined in the server configuration. Use the server configuration editor to add these items.

We can do as the comments and create a properly encoded password but for development we can do just:

So the other day I wrote this, apparently not a good approach these days.
This is probably the official (current) way of creating a web app project.
The following instructions are specific for WebSphere Application Server Liberty Profile.
Much of these information is based on the following sites/posts/answer:

At this point we have created the project but it seems it is a bit broken. At written here we can get rid of the following error by modifying the pom.xml

ArtifactDescriptorException: Failed to read artifact descriptor for com.ibm.tools.target:was-liberty:pom:LATEST: VersionResolutionException: Failed to resolve version for com.ibm.tools.target:was-liberty:pom:LATEST: Could not find metadata com.ibm.tools.target:was-liberty/maven-metadata.xml in local (/Users/paulbastide/.m2/repository)