1
0
Fork 0
mirror of https://github.com/omniauth/omniauth.git synced 2022-11-09 12:31:49 -05:00

Added skeleton for oa-identity as well as the basics for the model mixin.

This commit is contained in:
Michael Bleigh 2011-05-02 11:47:13 -05:00
parent 378cd36e0f
commit 158dab3bef
13 changed files with 255 additions and 1 deletions

2
oa-identity/.rspec Normal file
View file

@ -0,0 +1,2 @@
--format=nested
--colour

3
oa-identity/Gemfile Normal file
View file

@ -0,0 +1,3 @@
source "http://rubygems.org"
gemspec

View file

@ -0,0 +1,41 @@
# OmniAuth Identity
The OmniAuth Identity gem provides a way for applications to utilize a
traditional login/password based authentication system without the need
to give up the simple authentication flow provided by OmniAuth. Identity
is designed on purpose to be as featureless as possible: it provides the
basic construct for user management and then gets out of the way.
## Usage
You use `oa-identity` just like you would any other OmniAuth provider:
as a Rack middleware. The basic setup would look something like this:
use OmniAuth::Builder do
provider :identity
end
Next, you need to create a model that will be able to persist the
information provided by the user. By default, this model should be a
class called `Identity` and should respond to the following API:
Identity.create(
:name => 'x',
:password => 'y',
:confirm_password => 'y'
)
identity = Identity.authenticate('key', 'password')
# => Identity instance if correct
# => false if incorrect
identity.user_info # => {'name' => '...', 'nickname' => '...'}
identity.uid # => must be unique to the application
To make things easier, you can inherit your model from the ones provided
for popular ORMs which will automatically provide the default setup
necessary. For example:
class Identity < OmniAuth::Identity::Model::ActiveRecord
login_key :nickname
end

8
oa-identity/Rakefile Normal file
View file

@ -0,0 +1,8 @@
require 'bundler'
Bundler::GemHelper.install_tasks
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task :default => :spec
task :test => :spec

View file

@ -0,0 +1 @@
require 'omniauth/identity'

View file

@ -0,0 +1,17 @@
require 'omniauth/core'
module OmniAuth
module Strategies
autoload :Identity, 'omniauth/strategies/identity'
end
module Identity
autoload :Model, 'omniauth/identity/model'
module Models
autoload :ActiveRecord, 'omniauth/identity/models/active_record'
# autoload :MongoMapper, 'omniauth/identity/models/mongo_mapper'
# autoload :Mongoid, 'omniauth/identity/models/mongoid'
end
end
end

View file

@ -0,0 +1,66 @@
module OmniAuth
module Identity
# This module provides an includable interface for implementing the
# necessary API for OmniAuth Identity to properly locate identities
# and provide all necessary information. All methods marked as
# abstract must be implemented in the including class for things to
# work properly.
module Model
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
# Locate an identity given its unique login key.
#
# @abstract
# @param [String] key The unique login key.
# @return [Model] An instance of the identity model class.
def locate(key)
raise NotImplementedError
end
# Authenticate a user with the given key and password.
#
# @param [String] key The unique login key provided for a given identity.
# @param [String] password The presumed password for the identity.
# @return [Model] An instance of the identity model class.
def authenticate(key, password)
locate(key).authenticate(password)
end
end
# Returns self if the provided password is correct, false
# otherwise.
#
# @abstract
# @param [String] password The password to check.
# @return [self or false] Self if authenticated, false if not.
def authenticate(password)
raise NotImplementedError
end
SCHEMA_ATTRIBUTES = %w(name email nickname first_name last_name location description image phone)
# A hash of as much of the standard OmniAuth schema as is stored
# in this particular model. By default, this will call instance
# methods for each of the attributes it needs in turn, ignoring
# any for which `#respond_to?` is `false`.
#
# If `first_name`, `nickname`, and/or `last_name` is provided but
# `name` is not, it will be automatically calculated.
#
# @return [Hash] A string-keyed hash of user information.
def user_info
info = SCHEMA_ATTRIBUTES.inject({}) do |hash,attribute|
hash[attribute] = send(attribute) if respond_to?(attribute)
hash
end
info['name'] ||= [info['first_name'], info['last_name']].join(' ').strip if info['first_name'] || info['last_name']
info['name'] ||= info['nickname']
info
end
end
end
end

View file

@ -0,0 +1,11 @@
require 'active_record'
module OmniAuth
module Identity
module Models
class ActiveRecord << ::ActiveRecord::Base
include OmniAuth::Identity::Model
end
end
end
end

View file

@ -0,0 +1,7 @@
module OmniAuth
module Strategies
class Identity
include OmniAuth::Strategy
end
end
end

View file

@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../../lib/omniauth/version', __FILE__)
Gem::Specification.new do |gem|
gem.add_runtime_dependency 'oa-core', OmniAuth::Version::STRING
gem.add_development_dependency 'maruku', '~> 0.6'
gem.add_development_dependency 'simplecov', '~> 0.4'
gem.add_development_dependency 'rack-test', '~> 0.5'
gem.add_development_dependency 'rake', '~> 0.8'
gem.add_development_dependency 'rspec', '~> 2.5'
gem.add_development_dependency 'yard', '~> 0.6'
gem.add_development_dependency 'ZenTest', '~> 4.5'
gem.name = 'oa-identity'
gem.version = OmniAuth::Version::STRING
gem.description = %q{Internal authentication handlers for OmniAuth.}
gem.summary = gem.description
gem.email = ['michael@intridea.com', 'sferik@gmail.com']
gem.homepage = 'http://github.com/intridea/omniauth'
gem.authors = ['Michael Bleigh', 'Erik Michaels-Ober']
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.require_paths = ['lib']
gem.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if gem.respond_to? :required_rubygems_version=
end

View file

@ -0,0 +1,60 @@
require 'spec_helper'
class ExampleModel
include OmniAuth::Identity::Model
end
describe OmniAuth::Identity::Model do
context 'Class Methods' do
subject{ ExampleModel }
describe '.locate' do
it('should be abstract'){ lambda{ subject.locate('abc') }.should raise_error(NotImplementedError) }
end
describe '.authenticate' do
it 'should call locate and then authenticate' do
mocked_instance = mock('ExampleModel', :authenticate => 'abbadoo')
subject.should_receive(:locate).with('example').and_return(mocked_instance)
subject.authenticate('example','pass').should == 'abbadoo'
end
end
end
context 'Instance Methods' do
subject{ ExampleModel.new }
describe '#authenticate' do
it('should be abstract'){ lambda{ subject.authenticate('abc') }.should raise_error(NotImplementedError) }
end
describe '#user_info' do
it 'should include attributes that are set' do
subject.stub!(:name).and_return('Bob Bobson')
subject.stub!(:nickname).and_return('bob')
subject.user_info.should == {
'name' => 'Bob Bobson',
'nickname' => 'bob'
}
end
it 'should automatically set name off of first and last name' do
subject.stub!(:first_name).and_return('Bob')
subject.stub!(:last_name).and_return('Bobson')
subject.user_info['name'].should == 'Bob Bobson'
end
it 'should automatically set name off of nickname' do
subject.stub!(:nickname).and_return('bob')
subject.user_info['name'] == 'bob'
end
it 'should not overwrite a provided name' do
subject.stub!(:name).and_return('Awesome Dude')
subject.stub!(:first_name).and_return('Frank')
subject.user_info['name'].should == 'Awesome Dude'
end
end
end
end

View file

@ -0,0 +1,12 @@
require 'simplecov'
SimpleCov.start
require 'rspec'
require 'rack/test'
require 'omniauth/identity'
require 'omniauth/test'
RSpec.configure do |config|
config.include Rack::Test::Methods
config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
end

View file

@ -1,6 +1,6 @@
require 'fileutils'
PROJECTS = %w(oa-core oa-basic oa-enterprise oa-more oa-oauth oa-openid omniauth)
PROJECTS = %w(oa-core oa-basic oa-enterprise oa-identity oa-more oa-oauth oa-openid omniauth)
def root
File.expand_path('../../', __FILE__)