Some Updates On “LDAP Authentication With Phoenix”

There’s an excellent write-up on authenticating users against an LDAP database with Phoenix which was created by Richard Nyström.  For some reason even though it’s barely a year old, there seem to be a few points that are either out of date or simply incorrect. I worked through his example and I wanted to share a few amendments to his original code in the interests of other developers who may want to use LDAP with Phoenix.

First the set up of Phoenix


mix phx.new ldap_example # was mix phoenix.new ldap_example
...
Fetch and install dependencies? [Yn] Y

cd ldap_example

mix ecto.create (configure your db in config/dev.exs if needed)

mix phx.gen.schema User users username:string name:string email:string
# was
# mix phoenix.gen.model User users username:string name:string email:string

mix ecto.migrate

Next change is in the session_controller.ex file:


#was LdapExample.SessionController

defmodule LdapExampleWeb.SessionController do

#was LdapExample.Web, :controller

use LdapExampleWeb, :controller
alias LdapExample.{User, Repo, Ldap}

def new(conn, _params) do
render conn, "new.html", changeset: User.login_changeset
end

def create(conn, %{"user" => params}) do
username = params["username"]
password = params["password"]
case Ldap.authenticate(username, password) do
:ok -> handle_sign_in(conn, username)
_ -> handle_error(conn)
end
end

defp handle_sign_in(conn, username) do
{:ok, user} = insert_or_update_user(username)
conn
|> put_flash(:info, "Logged in.")
|> Guardian.Plug.sign_in(user)
|> redirect(to: page_path(conn, :index))
end

defp insert_or_update_user(username) do
{:ok, ldap_entry} = Ldap.get_by_uid(username)
user_attributes = Ldap.to_map(ldap_entry)
user = Repo.get_by(User, username: username)
changeset =
case user do
nil -> User.changeset(%User{}, user_attributes)
_ -> User.changeset(user, user_attributes)
end
Repo.insert_or_update changeset
end

defp handle_error(conn) do
conn
|> put_flash(:error, "Wrong username or password")
|> redirect(to: page_path(conn, :new))
end

def delete(conn, _params) do
Guardian.Plug.sign_out(conn)
|> put_flash(:info, "Logged out successfully.")
|> redirect(to: "/")
end
end

The changes to user.ex are not made in the web/model/user.ex; rather they’re made in the existing user.ex file.

And finally a change to session_view.ex

#was LdapExample.SessionView

defmodule LdapExampleWeb.SessionView do

use LdapExampleWeb, :view

end

Quick Elixir Tip

I use Samuel Tonini’s Alchemist (and Elixir mode) to make myself much more productive with Elixir and Emacs.  But one thing that I’ve found to be a minor annoyance is that whenever I start up Emacs I have to set the scratch buffer to be in Elixir mode and I then need to change the comment characters.

Thanks to this excellent tip I no longer have to do this.  I’ve modified my ~/.emacs to add these lines to the bottom:


(setq initial-major-mode 'elixir-mode)

(setq initial-scratch-message "\
# This buffer is for notes you don't want to save, and for Elixir code.
# If you want to create a file, visit that file with C-x C-f,
# then enter the text in that file's own buffer.")

And when I get a scratch buffer I’m all good to go with Elixir!

Making Exrm Work On Windows

So as many of you will know I’m very interested in Elixir.  I also want to see it work better on Windows.  There are a few of us that have been working on it.

I’ve also been very interested in how one can deploy an Elixir app on a machine which doesn’t have Erlang and Elixir already installed.  While most of us don’t mind having to have Erlang and Elixir around because we are doing development work, it would be much more secure to only have to deploy the binaries that need to be deployed for an app.

Since I started on Elixir one of the nicest folks in the community (and that’s saying something) has been Paul Schoenfelder. When I was first struggling to learn Elixir, Paul very patiently helped me to get started.  So I became aware of one of the utilities that Paul built: EXRM.  Exrm is a tool to automate the production of a package of the needed Elixir and Erlang binaries to deploy an app. It allows a developer to deploy his or her Elixir app with only the needed runtime files so that the target machine doesn’t have to have Elixir or Erlang installed.

So I asked Paul what I could do to sort of return the favor for the help he gave me when I started and he mentioned that he wasn’t as pleased as he might be with the support for Windows in EXRM.  So I started digging into EXRM to see what I might do to get it working on Windows.

A few instructive things I spotted right away. I noticed that the way the Windows batch files were constructed they will not work correctly if they’re not run from the correct directory. I mention this for others who may try to use EXRM on Windows.

Spaces In Directory Names

I noted also that there were several places where directories containing spaces and too many characters were also a problem. The original developers of the batch files wrapped double quotes around all the directory names. If you decide to build Windows batch files, please note that wrapping double quotes around directory names is a bit error prone and tough to get right.  Hence I opted to modify all the various places where they had double quoted directory names to using 8.3 versions of the names.  That fixed up all the references to directories so that everything was found correctly.

Getting Services Working

Next there was the question of getting Windows Services working for Erlang. While digging into the batch files I discovered that basically the issue hinged on the installation of the service.  Once the service was installed correctly, it looked as if the rest of the operations on the services (starting, stopping, restarting etc.) would work correctly.

I had to hunt around for a while to figure out what I needed to do to get the service to install correctly.  I finally figured out that what was happening was the wrong parameter was getting passed as the binary to be started when the service gets started.  And so I repaired it.

A Few More Details

You’ll also need to unblock the erl.exe and epmd.exe files for the Windows Firewall.  You can wait for Windows to prompt you or you can proactively unblock them via this escript.

You may also need to deploy msvcr100.dll to your deployment machine as well.  If it’s a Windows 10 machine you may need to do this.

So we’re almost ready to roll the changes into EXRM so we can get people to be able to deploy Elixir apps on Windows.

I will continue to work with Paul on improving support for EXRM on Windows.  Keep watching this space; we’ve got some interesting ideas we’ll be trying to roll out in the next few months or so.

 

 

 

Rebar3 Beta1 on Chocolatey NuGet

I had a need for the Erlang build tool rebar for a project I was trying to start on; a bit of pen testing via Elixir.  I was going to pull down the rebar3 script from the site and fix it up for myself and it occurred to me that others might want a way to get the script easily too.  So rather than just building something to work for myself, I took a little extra time and built a Chocolatey NuGet package for Rebar3-Beta1.

The package takes care of insuring you’ve got Erlang first although honestly I can’t imagine anyone interested in Rebar that wouldn’t already have Erlang on their machine.  It also takes care of setting up a shortcut for Rebar and putting it in the path.  And, of course, like everything else in CNG, it also handles uninstalling the tool if you decide you no longer want or need it.

For now the package is still awaiting moderation on CNG but please feel free to pull it down and give it a try.  Feedback is a gift and I hope some of you will share that gift with me.

Rebar3 on ChocolateyNuGet

Configuring Elixir For Development

One of the more exciting new functional languages of the last couple of years is a marriage of Erlang and Ruby called Elixir.  Besides adding an arguably better syntax with which to program the Erlang VM (also known as the BEAM VM), Elixir adds meta-programming, addresses issues Erlang had with dealing with Unicode strings, and adds few other nice touches.  It’s nice icing on the Erlang cake.  Joe Armstrong, the creator of Erlang, has gone on record as endorsing Elixir. I leave it to those who are interested in reading Mr. Armstrong’s comments to read for themselves; tl; dr he likes Elixir just like he likes Erlang.

So I’ve been wanting to play with Elixir for a while and when I want to play with a new language, I often configure a quick command prompt set up with the proper development environment.  It’s halfway between creating a new VM and not doing anything special. So if others care to build an elixir command prompt, here are the steps.  Note that you can stop before installing Elixir and have a great Erlang environment to play around with.

1.) Install Erlang. You can download a nice Windows installer package for Erlang from Erlang Solutions.

2.) Once erlang is installed, you’ll want to grab the prebuilt zip of Elixir from the Elixir GitHub repository.

3.) Create a powershell script to configure the environment.  Here’s mine:

Set-Variable -Name elixirBase -option Readonly -value "C:/dev/elixir_0.12.4"
Set-Variable -Name erlangBase -option Readonly -value "C:/Program Files/erl5.10.2"
Set-Variable -Name gitPath -option Readonly -value "c:/program files (x86)/git"

$env:Path = "$erlangBase/bin;$elixirBase/bin;$gitPath/bin;"

Set-Variable is the Powershell analog of setting an environment variable.  $env:Path is the actual Path environment variable in this case.  Since the environment will only apply for the duration of the Powershell session, I simply replace the existing Path with one set up specifically for the Elixir/Erlang combo. I named the file ElixirSetup.ps1; it’s convention for Powershell scripts to have a ps1 extension.  NB: These paths are on my machine and they’re for a slightly older version of Erlang (as of this writing current version installs to elr5.10.4).

Basically if I’m going to do a command prompt on Windows, Powershell is the way to go.  It remedies countless failings of the old cmd shell.

4.) Create a new shortcut with the following command line:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -File C:\Users\Onorio_Development\Documents\WindowsPowerShell\ElixirSetup.ps1

Obviously you’ll want to replace these values with the correct values for your particular machine.

Once you get the shortcut set up and going, there are a few things to test.  You can run the Erlang REPL by typing erl at the command prompt.  You can test the Elixir REPL by typing iex.bat at the command prompt.  You have to type the entire name (with the .bat extension) due to there being an iex alias present in Powershell.

Elixir includes a nice little project management tool called mix which was inspired by Clojure’s Leiningen.  Mix basically lets you create a small skeleton of an Elixir project complete with a .gitignore file and a README.md as well as a skeleton unit test.

I hope others will consider this an invitation to start playing with Elixir and learning more about both Elixir and Erlang.

EDIT:

One annoyance that I discovered after I wrote this post is that the native Powershell terminal doesn’t support ANSI escape sequences.  IEx uses ANSI escape sequences and this is a real annoyance.  So I did some digging and found that ConEmu has nice support for ANSI and it remedies the issue with IEx very nicely.  There are other ways of getting support for the ANSI escape sequences as well but this is a nice robust remedy for the problem.

Provisioning a VM with Scala and SBT

So I’ve been giving a little more time and attention to both Scala and Vagrant.  Vagrant is a nice way to manage development environments via the use of VM’s and Scala, of course, is a great hybrid of OO and FP.  One of the things I’ve done is to start working on a provisioning script for Vagrant so I can always get myself a development environment with Scala without much trouble.  So here’s the steps I follow.

One time steps:

1.) Get Vagrant

2.) Get Virtual Box (or some other VM management tool).

3.) Install both of those packages on your development machine.

4.) Create a new development directory on your dev machine.

5.) Run vagrant init <boxname> <box definition> in the development directory. You can find more detail on this command here and you can find a great list of base box definitions here.

6.) Edit the vagrantfile installed in the development directory to add this line:

config.vm.provision “shell”, path:”provision.sh”

7.) Add the following provision.sh file in the same directory as the vagrantfile.


#!/usr/bin/env bash
# Onorio Catenacci 3 January 2014

echo "Installing scala and setting it up . . . "

apt-get update > /dev/null 2>&1
apt-get install -y scala > /dev/null 2>&1

# Thanks to pardigmatic on StackOverflow for this procedure to install
# SBT via apt-get on Ubuntu
# See here: http://stackoverflow.com/questions/13711395/install-sbt-on-ubuntu

echo "Installing SBT . . ."
debfile="repo-deb-build-0002.deb"
wget http://apt.typesafe.com/"$debfile" > /dev/null 2>&1
dpkg -i "$debfile" > /dev/null 2>&1
apt-get update > /dev/null 2>&1
apt-get install -y sbt > /dev/null 2>&1

basevim="/home/vagrant/.vim"

echo "Setting up VIM for syntax highlighting"
#Create directories for vim syntax highlighting then fetch the files from github
#Credit where credit's due, one liner is from blog posting by Bruce Snyder
#http://bsnyderblog.blogspot.com/2012/12/vim-syntax-highlighting-for-scala-bash.html

mkdir -p "$basevim"/{ftdetect,indent,syntax} && for d in ftdetect indent syntax ; do wget --no-check-certificate -O "$basevim"/$d/scala.vim https://raw.github.com/scala/scala-dist/master/tool-support/src/vim/$d/scala.vim; done > /dev/null 2>&1

rm -f "$debfile"

8.) Start the vm via the vagrant up –provision command.  This will force the provision.sh file to be run to install scala, sbt and the proper vim bindings for correct syntax highlighting of scala code.  This way everytime you initialize the vm (via the vagrant init in the development directory) scala, sbt and the proper bindings for scala syntax highlighting will be automatically installed.

9.) One more thing; you can log in to the machine with vagrant ssh.  When you do, you may want to change the amount of memory that sbt asks for in its startup.  In this particular case you should be able to run $vim /usr/bin/sbt and modify these two lines:

local mem=${1:-1536}

and

declare –r default_sbt_mem=1536

On my machine [edit: it’s an Ubuntu 13.10 VM] in particular I had to set this to 512 [edit: turns out 256 works even better] on both lines in order to get sbt to start successfully.  I can’t give you a particular number which is guaranteed to work—play around with this until you find the right value.

Why I Am Not A Fan of Screen Sharing For User Group Meetings

So I want to capture these thoughts while I can for whatever value they may have to myself or others in the future.

Last night we did a coding dojo on building Android apps with F#.  Reluctantly, after a little cajoling from a co-worker I decided to add a Google Hangout to the meeting.  NB: While I specifically mention Google Hangout don’t misunderstand; the problems I’m addressing have been problems with pretty much any teleconferencing solution I’ve had experience with.  AnyMeeting, WebEx etc. etc. etc. all seem to have the same issues.

So I don’t think it went particularly well (others may feel differently).  And I think I’ve finally figured out my issues with the screen share/videoconferencing approach.

The technology still has some rough edges. Repeatedly last night I was sharing a screen to show people on-line some point that I was discussing.  And repeatedly the screen share simply stopped by itself. The video conferencing portion just stopped working by itself at some points too.  This issue will go away as the technology improves, of course, but we’ll also ask more from the tech so this issue will never really resolve completely.

The speaker’s focus is split. For me, the bigger issue was trying to help the developers in the room (coding dojo) and trying to assist the developers online.  There was no way I could simply talk to the people online and also address the people in the room.

The speaker ends up having to run the video conference. This is a relatively tough issue to address because the speaker has the slide deck and the speaker knows which examples he (or she) is going to show so they end up running the video conference from their machine.  It’s tough enough to give an intelligent talk without having to worry about the side issues of when you should share your screen and when you should be showing the video feed and such.  I think if I were to do this at a user group meeting again there would be a designated video conf assistant and I’d practice things with that video conf assistant at least three or four times before the actual presentation.

If others have thoughts or suggestions on these issues, please feel free to comment.  Perhaps I’m simply not seeing what may be simple answers to these issues.