Permalink
Browse files

Initial verison of aMember Pro Omniauth strategy

  • Loading branch information...
meanphil committed Jul 4, 2012
0 parents commit 67ed43d54bb69cb7e640e301eaa78e2bc6c6f654
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in omniauth-amember_pro.gemspec
+gemspec
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 TODO: Write your name
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
+# OmniAuth aMember Pro Strategy
+
+This gem provides a dead simple way to authenticate to aMember Pro using OmniAuth.
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+```ruby
+gem 'omniauth-amember_pro'
+```
+
+## Usage
+
+First, you will need an aMember Pro or two. Once you do that, you can use it like so:
+
+```ruby
+use OmniAuth::Builder do
+ provider :amember_pro
+end
+```
+
+## Auth Hash Schema
+
+The following information is provided back to you for this provider:
+
+```ruby
+{
+ uid: '12345',
+ info: {
+ nickname: 'login', # may be email
+ email: 'someone@example.com'
+ },
+ credentials: {
+ token: 'thetoken' # can be used to auth to the API
+ },
+ extra: { raw_info: raw_api_response }
+}
+```
+
@@ -0,0 +1,2 @@
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
+$:.push File.dirname(__FILE__) + '/../lib'
+
+require 'omniauth-amember_pro'
+require 'sinatra'
+
+use Rack::Session::Cookie
+use OmniAuth::Builder do
+ provider :amember_pro, :auth_url => "http://www.example.org/amember/", :api_key => "XXXXXXXXXXXXXXXX"
+ end
+
+get '/' do
+ "<a href='/auth/amember_pro'>Log in with AMember</a>"
+end
+
+post '/auth/amember_pro/callback' do
+ content_type 'text/plain'
+ request.env['omniauth.auth'].inspect
+end
+
+get '/auth/failure' do
+ if params['message'] == "invalid_credentials"
+ "Wrong username and password!"
+ else
+ "Unknown failure"
+ end
+end
+
@@ -0,0 +1,6 @@
+require 'multi_json'
+require 'faraday'
+require 'omniauth-amember_pro/amember_api_wrapper'
+
+require 'omniauth'
+require 'omniauth/strategies/amember_pro'
@@ -0,0 +1,68 @@
+class AmemberApiWrapper
+
+ attr_accessor :api_key, :auth_url, :conn
+
+ def initialize(options)
+ @auth_url = options.auth_url
+
+ # Ensure URL has trailing slash, so URI concatenation works later on
+ @auth_url += '/' if @auth_url[-1] != '/'
+
+ @api_key = options.api_key
+ @conn = Faraday.new(:url => auth_url)
+ end
+
+ def login!(username, password)
+ result = perform_request('check-access/by-login-pass', {
+ login: username,
+ pass: password
+ })
+ if result["ok"] == true
+ @username = username
+ true
+ else
+ false
+ end
+ end
+
+ def user_info
+ if @username
+ perform_request('users', {
+ "_filter[login]" => @username
+ })["0"]
+ else
+ raise "User not logged in"
+ end
+ end
+private
+
+ def perform_request(action, params = {})
+ uri = URI.parse(auth_url)
+ endpoint = URI.join(uri, 'api/', action.gsub(/^\//, ''))
+
+ response = conn.get do |req|
+ req.url endpoint.path
+ req.params = { "_key" => api_key }.merge(params)
+ end
+
+ ret = {}
+ if response.status == 200
+ MultiJson.load(response.body)
+ else
+ raise InvalidServerResponse.new("Server responded with code #{response.status}")
+ end
+
+ rescue MultiJson::DecodeError => e
+ raise InvalidJsonResponse.new("Couldn't parse login response: #{e.message[0..30]}")
+ end
+
+
+
+
+ class InvalidJsonResponse < StandardError
+ end
+
+ class InvalidServerResponse < StandardError
+ end
+
+end
@@ -0,0 +1,5 @@
+module OmniAuth
+ module AMemberPro
+ VERSION = "0.0.1"
+ end
+end
@@ -0,0 +1,70 @@
+
+module OmniAuth
+ module Strategies
+ class AmemberPro
+ include OmniAuth::Strategy
+
+ option :name, "amember_pro"
+ option :fields, [ :username, :password ]
+ option :auth_url
+ option :api_key
+
+ # Set this to true when you configure Rails/Sinatra to use OmniAuth
+ # if you want to provide your own login form
+ # option :form, true
+
+ def request_phase
+ form = OmniAuth::Form.new(:title => "User Info", :url => callback_path)
+ form.text_field "Username", 'username'
+ form.password_field "Password", 'password'
+ form.button "Sign In"
+ form.to_response
+ end
+
+ def callback_phase
+ api = AmemberApiWrapper.new(options)
+
+ if api.login!(username, password)
+ @raw_info = api.user_info
+ super
+ else
+ fail!(:invalid_credentials)
+ end
+ end
+
+ uid do
+ raw_info['user_id']
+ end
+
+ info do
+ {
+ 'name' => "%s %s" % [ raw_info['name_f'], raw_info['name_l'] ],
+ 'email' => raw_info['email'],
+ 'nickname' => raw_info['username'],
+ 'first_name' => raw_info['name_f'],
+ 'last_name' => raw_info['name_l'],
+ 'location' => raw_info['region']
+ }
+ end
+
+ extra do
+ {
+ :soba_member_id => raw_info['membership_number'],
+ :raw_info => raw_info
+ }
+ end
+
+ %w(username password).each do |field|
+ define_method field do
+ request[field]
+ end
+ end
+
+ private
+ def raw_info
+ @raw_info
+ end
+
+ end
+ end
+end
@@ -0,0 +1,21 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/omniauth-amember_pro/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Phil Murray"]
+ gem.email = ["pmurray@nevada.net.nz"]
+ gem.description = %q{OmniAuth strategy for Open2view REST Auth}
+ gem.summary = %q{OmniAuth strategy for Open2view REST Auth}
+ gem.homepage = "https://www.nevada.net.nz/"
+
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ gem.files = `git ls-files`.split("\n")
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ gem.name = "omniauth-amember_pro"
+ gem.require_paths = ["lib"]
+ gem.version = OmniAuth::AMemberPro::VERSION
+
+ gem.add_dependency 'omniauth', '~> 1.0'
+ gem.add_dependency 'faraday'
+ gem.add_dependency 'multi_json'
+end

0 comments on commit 67ed43d

Please sign in to comment.