├── .gitignore ├── .rspec ├── .travis.yml ├── Gemfile ├── README.md ├── Rakefile ├── lib ├── omniauth-meetup.rb ├── omniauth-meetup │ └── version.rb └── omniauth │ └── strategies │ └── meetup.rb ├── omniauth-meetup.gemspec └── spec ├── omniauth └── strategies │ └── meetup_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | .rvmrc 6 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format=progress 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.8.7 3 | - 1.9.2 4 | - 1.9.3 5 | - ree 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | # Specify your gem's dependencies in omniauth-meetup.gemspec 4 | gemspec 5 | 6 | group :development, :test do 7 | gem 'rake' 8 | gem 'rspec' 9 | gem 'simplecov' 10 | end 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OmniAuth Meetup 2 | 3 | [![Build 4 | Status](https://secure.travis-ci.org/tapster/omniauth-meetup.png)](http://travis-ci.org/tapster/omniauth-meetup) 5 | 6 | `OmniAuth::Strategies::Meetup` is an OmniAuth strategy for authenticating to 7 | meetup.com with OAuth2. Read detailed information about the meetup.com 8 | implementation of OAuth2 9 | [here](http://www.meetup.com/meetup_api/auth/#oauth2) 10 | 11 | ## Installing 12 | 13 | Add to your `Gemfile`: 14 | 15 | ```ruby 16 | gem 'omniauth-meetup' 17 | ``` 18 | 19 | Then `bundle install`. 20 | 21 | ## Usage 22 | 23 | To get started you will need to register an OAuth Consumer in your 24 | meetup.com account 25 | [here](http://www.meetup.com/meetup_api/oauth_consumers/) 26 | 27 | Here's a quick example, adding the middleware to a Rails app in 28 | `config/initializers/omniauth.rb`: 29 | 30 | ```ruby 31 | Rails.application.config.middleware.use OmniAuth::Builder do 32 | provider :meetup, ENV['MEETUP_KEY'], ENV['MEETUP_SECRET'] 33 | end 34 | ``` 35 | or with Devise 36 | 37 | ```ruby 38 | config.omniauth :meetup, ENV['MEETUP_KEY'], ENV['MEETUP_SECRET'], callback_url: 'http://example.com/users/auth/meetup/callback' 39 | ``` 40 | **Starting from version 1.4 in omniauth-oauth2 you must provide same callback url you have provided on API dashboard otherwise authentication won't work.** 41 | 42 | You can then implement your authentication as usual with OmniAuth as 43 | shown in the excellent [Railscast 44 | 241](http://railscasts.com/episodes/241-simple-omniauth) 45 | 46 | ##Authentication Hash 47 | 48 | Here's an example *Authentication Hash* available in 49 | `request.env['omniauth.auth']`: 50 | 51 | ```ruby 52 | {"provider"=>"meetup", 53 | "uid"=>0, 54 | "info"=> 55 | {"id"=>0, 56 | "name"=>"elvis", 57 | "photo_url"=>"http://photos3.meetupstatic.com/photos/member_pic_0.jpeg"}, 58 | "credentials"=> 59 | {"token"=>"abc123...", # OAuth 2.0 access_token, which you may wish to store 60 | "refresh_token"=>"bcd234...", # This token can be used to refresh your access_token later 61 | "expires_at"=>1324720198, # when the access token expires (Meetup tokens expire in 1 hour) 62 | "expires"=>true}, 63 | "extra"=> 64 | {"raw_info"=> 65 | {"lon"=>-90.027181, 66 | "link"=>"http://www.meetup.com/members/0", 67 | "lang"=>"en_US", 68 | "photo"=> 69 | {"photo_link"=> "http://photos3.meetupstatic.com/photos/member_pic_0.jpeg", 70 | "highres_link"=> "http://photos1.meetupstatic.com/photos/member_pic_0_hires.jpeg", 71 | "thumb_link"=> "http://photos1.meetupstatic.com/photos/member_pic_0_thumb.jpeg", 72 | "photo_id"=>0}, 73 | "city"=>"Memphis", 74 | "country"=>"us", 75 | "visited"=>1325001005000, 76 | "id"=>0, 77 | "topics"=>[], 78 | "joined"=>1147652858000, 79 | "name"=>"elvis", 80 | "other_services"=>{"twitter"=>{"identifier"=>"@elvis"}}, 81 | "lat"=>35.046677 82 | } 83 | } 84 | } 85 | ``` 86 | 87 | ## License 88 | 89 | Copyright (c) 2011 by Miles Woodroffe 90 | 91 | Permission is hereby granted, free of charge, to any person obtaining a 92 | copy of this software and associated documentation files (the 93 | "Software"), to deal in the Software without restriction, including 94 | without limitation the rights to use, copy, modify, merge, publish, 95 | distribute, sublicense, and/or sell copies of the Software, and to 96 | permit persons to whom the Software is furnished to do so, subject to 97 | the following conditions: 98 | 99 | The above copyright notice and this permission notice shall be included 100 | in all copies or substantial portions of the Software. 101 | 102 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 103 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 104 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 105 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 106 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 107 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 108 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 109 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | require 'rspec/core/rake_task' 4 | 5 | RSpec::Core::RakeTask.new do |t| 6 | end 7 | 8 | task default: :spec 9 | -------------------------------------------------------------------------------- /lib/omniauth-meetup.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth-meetup/version' 2 | require 'omniauth/strategies/meetup' 3 | -------------------------------------------------------------------------------- /lib/omniauth-meetup/version.rb: -------------------------------------------------------------------------------- 1 | module Omniauth 2 | module Meetup 3 | VERSION = '0.0.8'.freeze 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/omniauth/strategies/meetup.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth-oauth2' 2 | 3 | module OmniAuth 4 | module Strategies 5 | # Meetup omniauth-oauth2 strategy 6 | class Meetup < OmniAuth::Strategies::OAuth2 7 | option :name, 'meetup' 8 | 9 | option :client_options, 10 | site: 'https://api.meetup.com', 11 | authorize_url: 'https://secure.meetup.com/oauth2/authorize', 12 | token_url: 'https://secure.meetup.com/oauth2/access' 13 | 14 | def request_phase 15 | super 16 | end 17 | 18 | uid { raw_info['id'] } 19 | 20 | info do 21 | { 22 | id: raw_info['id'], 23 | name: raw_info['name'], 24 | photo_url: meetup_photo_url, 25 | image: meetup_photo_url, 26 | urls: { public_profile: raw_info['link'] }, 27 | description: raw_info['bio'], 28 | location: meetup_location 29 | } 30 | end 31 | 32 | extra do 33 | { 'raw_info' => raw_info } 34 | end 35 | 36 | def callback_url 37 | # Fixes regression in omniauth-oauth2 v1.4.0 by https://github.com/intridea/omniauth-oauth2/commit/85fdbe117c2a4400d001a6368cc359d88f40abc7 38 | options[:callback_url] || (full_host + script_name + callback_path) 39 | end 40 | 41 | def raw_info 42 | @raw_info ||= JSON.parse(access_token.get('/2/member/self').body) 43 | end 44 | 45 | private 46 | 47 | def meetup_location 48 | [raw_info['city'], raw_info['state'], raw_info['country']].reject do |v| 49 | !v || v.empty? 50 | end.join(', ') 51 | end 52 | 53 | def meetup_photo_url 54 | raw_info.key?('photo') ? raw_info['photo']['photo_link'] : nil 55 | end 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /omniauth-meetup.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | Gem::Specification.new do |gem| 3 | gem.name = 'omniauth-meetup' 4 | gem.version = '0.0.8' 5 | gem.authors = ['Miles Woodroffe'] 6 | gem.email = ['miles@thespecials.com'] 7 | gem.homepage = 'http://github.com/tapster/omniauth-meetup' 8 | gem.description = 'Meetup.com authentication handler for OmniAuth' 9 | gem.summary = gem.description 10 | 11 | gem.require_paths = ['lib'] 12 | gem.files = ['.gitignore', '.rspec', '.travis.yml', 'Gemfile', 'README.md', 'Rakefile', 'lib/omniauth-meetup.rb', 'lib/omniauth-meetup/version.rb', 'lib/omniauth/strategies/meetup.rb', 'omniauth-meetup.gemspec'] 13 | gem.test_files = ['./spec/omniauth/strategies/meetup_spec.rb', 'spec/spec_helper.rb'] 14 | 15 | # specify any dependencies here; for example: 16 | gem.add_dependency 'omniauth', '~> 1.0' 17 | gem.add_dependency 'omniauth-oauth2', '~> 1.0' 18 | gem.add_development_dependency 'rspec', '~> 2.7' 19 | gem.add_development_dependency 'rack-test' 20 | gem.add_development_dependency 'webmock' 21 | end 22 | -------------------------------------------------------------------------------- /spec/omniauth/strategies/meetup_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe OmniAuth::Strategies::Meetup do 4 | subject do 5 | OmniAuth::Strategies::Meetup.new(nil, @options || {}) 6 | end 7 | 8 | describe '#client' do 9 | it 'has a correct api url' do 10 | expect(subject.client.site).to eq('https://api.meetup.com') 11 | end 12 | 13 | it 'has a correct api authorization url' do 14 | expect(subject.client.options[:authorize_url]).to eq('https://secure.meetup.com/oauth2/authorize') 15 | end 16 | 17 | it 'has a correct api token auth url' do 18 | expect(subject.client.options[:token_url]).to eq('https://secure.meetup.com/oauth2/access') 19 | end 20 | end 21 | 22 | describe '#callback_path' do 23 | it 'has a correct callback path' do 24 | expect(subject.callback_path).to eq('/auth/meetup/callback') 25 | end 26 | end 27 | 28 | describe '#uid' do 29 | it 'returns the uid from raw_info' do 30 | allow(subject).to receive(:raw_info).and_return('id' => '999') 31 | expect(subject.uid).to eq('999') 32 | end 33 | end 34 | 35 | describe '#info' do 36 | it 'returns the name from raw_info' do 37 | allow(subject).to receive(:raw_info).and_return('name' => 'Bert') 38 | expect(subject.info[:name]).to eq('Bert') 39 | end 40 | 41 | it 'returns the photo_url from raw_info if available' do 42 | allow(subject).to receive(:raw_info).and_return('photo' => { 'photo_link' => 'http://meetup.com/bert.jpg' }) 43 | expect(subject.info[:photo_url]).to eq('http://meetup.com/bert.jpg') 44 | allow(subject).to receive(:raw_info).and_return({}) 45 | expect(subject.info[:photo_url]).to eq(nil) 46 | end 47 | 48 | it 'returns the image from raw_info if available' do 49 | allow(subject).to receive(:raw_info).and_return('photo' => { 'photo_link' => 'http://meetup.com/bert.jpg' }) 50 | expect(subject.info[:image]).to eq('http://meetup.com/bert.jpg') 51 | allow(subject).to receive(:raw_info).and_return({}) 52 | expect(subject.info[:image]).to eq(nil) 53 | end 54 | 55 | it 'returns the public_profile url' do 56 | allow(subject).to receive(:raw_info).and_return('link' => 'http://meetup.com/bert') 57 | expect(subject.info[:urls][:public_profile]).to eq('http://meetup.com/bert') 58 | end 59 | 60 | it 'returns the description from raw_info' do 61 | allow(subject).to receive(:raw_info).and_return('bio' => 'My name is Bert.') 62 | expect(subject.info[:description]).to eq('My name is Bert.') 63 | end 64 | 65 | it 'returns the location from raw_info' do 66 | allow(subject).to receive(:raw_info).and_return('city' => 'Los Angeles', 'state' => 'CA', 'country' => 'USA') 67 | expect(subject.info[:location]).to eq('Los Angeles, CA, USA') 68 | allow(subject).to receive(:raw_info).and_return('city' => 'Tokyo', 'country' => 'Japan') 69 | expect(subject.info[:location]).to eq('Tokyo, Japan') 70 | allow(subject).to receive(:raw_info).and_return({}) 71 | expect(subject.info[:location]).to eq('') 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | Dir[File.expand_path('../support/**/*', __FILE__)].each { |f| require f } 2 | require 'bundler/setup' 3 | require 'rspec' 4 | require 'rack/test' 5 | require 'webmock/rspec' 6 | require 'omniauth' 7 | require 'omniauth-meetup' 8 | 9 | RSpec.configure do |config| 10 | config.include WebMock::API 11 | config.include Rack::Test::Methods 12 | config.extend OmniAuth::Test::StrategyMacros, type: :strategy 13 | end 14 | --------------------------------------------------------------------------------