noosfero | 4 new commits pushed to repository
Bráulio Bhavamitra
gitlab at gitlab.com
Sun Feb 22 20:21:04 BRT 2015
Bráulio Bhavamitra pushed to refs/heads/master at <a href="https://gitlab.com/noosfero/noosfero">Noosfero / noosfero</a>
Commits:
<a href="https://gitlab.com/noosfero/noosfero/commit/82325df3267f6ea4caf4895fe7453e4a405ac8eb">82325df3</a> by Victor Costa
Add oauth client plugin
- - - - -
<a href="https://gitlab.com/noosfero/noosfero/commit/8f0d8761001c65c52959e215424fc0059e1c7dd4">8f0d8761</a> by Victor Costa
Add oauth provider plugin
- - - - -
<a href="https://gitlab.com/noosfero/noosfero/commit/8408ffac6f660a06510c7d1f1814db71c7f8163a">8408ffac</a> by Victor Costa
Prevent session reset because of cache in signup form
Also a GET is more appropriate for this case.
- - - - -
<a href="https://gitlab.com/noosfero/noosfero/commit/1213fdf1e3ceed079b54779296dcd26cf60e65e4">1213fdf1</a> by Bráulio Bhavamitra
Merge branch 'oauth_rails3' into 'master'
Two oauth plugins: oauth_client and oauth_provider
See merge request !415
- - - - -
Changes:
=====================================
app/views/account/_signup_form.html.erb
=====================================
--- a/app/views/account/_signup_form.html.erb
+++ b/app/views/account/_signup_form.html.erb
@@ -16,7 +16,7 @@
<input type="hidden" id="signup_time_key" name="signup_time_key" />
<script type="text/javascript">
jQuery.ajax({
- type: "POST",
+ type: "GET",
url: "<%= url_for :controller=>'account', :action=>'signup_time' %>",
dataType: 'json',
success: function(data) {
=====================================
plugins/oauth_client/Gemfile
=====================================
--- /dev/null
+++ b/plugins/oauth_client/Gemfile
@@ -0,0 +1,3 @@
+gem 'omniauth', '~> 1.2.2'
+gem 'omniauth-facebook', '~> 2.0.0'
+gem "omniauth-google-oauth2", '~> 0.2.6'
=====================================
plugins/oauth_client/README.md
=====================================
--- /dev/null
+++ b/plugins/oauth_client/README.md
@@ -0,0 +1,72 @@
+README - Oauth Client Plugin
+================================
+
+OauthClient is a plugin which allow users to login/signup to noosfero with some oauth providers (for now, google, facebook and noosfero itself).
+
+Install
+=======
+
+Enable Plugin
+-------------
+
+cd <your_noosfero_dir>
+./script/noosfero-plugins enable oauth_client
+
+Active Plugin
+-------------
+
+As a Noosfero administrator user, go to administrator panel:
+
+- Click on "Enable/disable plugins" option
+- Click on "Oauth Client Plugin" check-box
+
+Provider Settings
+=================
+
+Goggle
+------
+
+[Create Google+ application](https://developers.google.com/+/web/signin/javascript-flow)
+
+Facebook
+--------
+
+[Create Facebook application](https://developers.facebook.com/docs/facebook-login/v2.1)
+
+Varnish Settings
+================
+If varnish has been used in your stack, you've to bypass the cache for signup page and prevent cookies to be removed when calling the oauth_client plugin callback. E.g.:
+
+```
+if (req.url !~ "^/account/*" && req.url !~ "^/plugin/oauth_provider/*" && req.url !~ "^/plugin/oauth_client/*" && req.http.cookie !~ "_noosfero_.*") {
+ unset req.http.cookie;
+ return(lookup);
+}
+```
+
+Using Oauth Provider Plugin
+===========================
+The oauth_provider plugin may be used as a provider in the same noosfero installation that hosts your oauth_client plugin (this is usefull in a multi environment setup).
+
+However, you've to use a distinct set of thin processes to handle the authorization requests (to avoid deadlock).
+
+Apache settings example:
+```
+RewriteRule ^/oauth_provider/oauth/(authorize|token).*$ balancer://noosfero-oauth-provider%{REQUEST_URI} [P,QSA,L]
+```
+
+
+Development
+===========
+
+Running OauthClient tests
+--------------------
+
+$ rake test:noosfero_plugins:oauth_client
+
+License
+=======
+
+Copyright (c) The Author developers.
+
+See Noosfero license.
=====================================
plugins/oauth_client/controllers/oauth_client_plugin_admin_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/controllers/oauth_client_plugin_admin_controller.rb
@@ -0,0 +1,27 @@
+class OauthClientPluginAdminController < AdminController
+
+ def index
+ end
+
+ def new
+ @provider = environment.oauth_providers.new
+ render :file => 'oauth_client_plugin_admin/edit'
+ end
+
+ def remove
+ environment.oauth_providers.find(params[:id]).destroy
+ redirect_to :action => 'index'
+ end
+
+ def edit
+ @provider = params[:id] ? environment.oauth_providers.find(params[:id]) : environment.oauth_providers.new
+ if request.post?
+ if @provider.update_attributes(params['oauth_client_plugin_provider'])
+ session[:notice] = _('Saved!')
+ else
+ session[:notice] = _('Error!')
+ end
+ end
+ end
+
+end
=====================================
plugins/oauth_client/controllers/public/oauth_client_plugin_public_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/controllers/public/oauth_client_plugin_public_controller.rb
@@ -0,0 +1,46 @@
+class OauthClientPluginPublicController < PublicController
+
+ skip_before_filter :login_required
+
+ def callback
+ auth = request.env["omniauth.auth"]
+ user = environment.users.find_by_email(auth.info.email)
+ user ? login(user) : signup(auth)
+ end
+
+ def failure
+ session[:notice] = _('Failed to login')
+ redirect_to root_url
+ end
+
+ def destroy
+ session[:user] = nil
+ redirect_to root_url
+ end
+
+ protected
+
+ def login(user)
+ provider = OauthClientPlugin::Provider.find(session[:provider_id])
+ user_provider = user.oauth_user_providers.find_by_provider_id(provider.id)
+ unless user_provider
+ user_provider = user.oauth_user_providers.create(:user => user, :provider => provider, :enabled => true)
+ end
+ if user_provider.enabled? && provider.enabled?
+ session[:user] = user.id
+ else
+ session[:notice] = _("Can't login with #{provider.name}")
+ end
+
+ redirect_to :controller => :account, :action => :login
+ end
+
+ def signup(auth)
+ login = auth.info.email.split('@').first
+ session[:oauth_data] = auth
+ name = auth.info.name
+ name ||= auth.extra && auth.extra.raw_info ? auth.extra.raw_info.name : ''
+ redirect_to :controller => :account, :action => :signup, :user => {:login => login, :email => auth.info.email}, :profile_data => {:name => name}
+ end
+
+end
=====================================
plugins/oauth_client/db/migrate/20141010135314_create_oauth_client_plugin_provider.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/db/migrate/20141010135314_create_oauth_client_plugin_provider.rb
@@ -0,0 +1,19 @@
+class CreateOauthClientPluginProvider < ActiveRecord::Migration
+
+ def self.up
+ create_table :oauth_client_plugin_providers do |t|
+ t.integer :environment_id
+ t.string :strategy
+ t.string :name
+ t.text :options
+ t.boolean :enabled
+ t.integer :image_id
+
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :oauth_client_plugin_providers
+ end
+end
=====================================
plugins/oauth_client/db/migrate/20141014162710_create_oauth_client_user_providers.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/db/migrate/20141014162710_create_oauth_client_user_providers.rb
@@ -0,0 +1,14 @@
+class CreateOauthClientUserProviders < ActiveRecord::Migration
+ def self.up
+ create_table :oauth_client_plugin_user_providers do |t|
+ t.references :user
+ t.references :provider
+ t.boolean :enabled
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :oauth_client_plugin_user_providers
+ end
+end
=====================================
plugins/oauth_client/lib/ext/environment.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/lib/ext/environment.rb
@@ -0,0 +1,7 @@
+require_dependency 'environment'
+
+class Environment
+
+ has_many :oauth_providers, :class_name => 'OauthClientPlugin::Provider'
+
+end
=====================================
plugins/oauth_client/lib/ext/user.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/lib/ext/user.rb
@@ -0,0 +1,31 @@
+require_dependency 'user'
+
+class User
+
+ has_many :oauth_user_providers, :class_name => 'OauthClientPlugin::UserProvider'
+ has_many :oauth_providers, :through => :oauth_user_providers, :source => :provider
+
+ def password_required_with_oauth?
+ password_required_without_oauth? && oauth_providers.empty?
+ end
+
+ alias_method_chain :password_required?, :oauth
+
+ after_create :activate_oauth_user
+
+ def activate_oauth_user
+ unless oauth_providers.empty?
+ activate
+ oauth_providers.each do |provider|
+ OauthClientPlugin::UserProvider.create!(:user => self, :provider => provider, :enabled => true)
+ end
+ end
+ end
+
+ def make_activation_code_with_oauth
+ oauth_providers.blank? ? make_activation_code_without_oauth : nil
+ end
+
+ alias_method_chain :make_activation_code, :oauth
+
+end
=====================================
plugins/oauth_client/lib/oauth_client_plugin.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/lib/oauth_client_plugin.rb
@@ -0,0 +1,95 @@
+require 'omniauth/strategies/noosfero_oauth2'
+
+class OauthClientPlugin < Noosfero::Plugin
+
+ def self.plugin_name
+ "Oauth Client Plugin"
+ end
+
+ def self.plugin_description
+ _("Login with Oauth.")
+ end
+
+ def login_extra_contents
+ plugin = self
+ proc do
+ render :partial => 'auth/oauth_login', :locals => {:providers => environment.oauth_providers.enabled}
+ end
+ end
+
+ def signup_extra_contents
+ plugin = self
+
+ proc do
+ if plugin.context.session[:oauth_data].present?
+ render :partial => 'account/oauth_signup'
+ else
+ ''
+ end
+ end
+ end
+
+ PROVIDERS = {
+ :facebook => {
+ :name => 'Facebook'
+ },
+ :google_oauth2 => {
+ :name => 'Google'
+ },
+ :noosfero_oauth2 => {
+ :name => 'Noosfero'
+ }
+ }
+
+ def stylesheet?
+ true
+ end
+
+ OmniAuth.config.on_failure = OauthClientPluginPublicController.action(:failure)
+
+ Rails.application.config.middleware.use OmniAuth::Builder do
+ PROVIDERS.each do |provider, options|
+ setup = lambda { |env|
+ request = Rack::Request.new(env)
+ strategy = env['omniauth.strategy']
+
+ Noosfero::MultiTenancy.setup!(request.host)
+ domain = Domain.find_by_name(request.host)
+ environment = domain.environment rescue Environment.default
+
+ provider_id = request.params['id']
+ provider_id ||= request.session['omniauth.params']['id'] if request.session['omniauth.params']
+ provider = environment.oauth_providers.find(provider_id)
+ strategy.options.merge!(provider.options.symbolize_keys)
+
+ request.session[:provider_id] = provider_id
+ }
+
+ provider provider, :setup => setup,
+ :path_prefix => '/plugin/oauth_client',
+ :callback_path => "/plugin/oauth_client/public/callback/#{provider}",
+ :client_options => { :connection_opts => { :proxy => ENV["OAUTH_HTTP_PROXY"] } }
+ end
+
+ unless Rails.env.production?
+ provider :developer, :path_prefix => "/plugin/oauth_client", :callback_path => "/plugin/oauth_client/public/callback/developer"
+ end
+ end
+
+ def account_controller_filters
+ {
+ :type => 'before_filter', :method_name => 'signup',
+ :block => proc {
+ auth = session[:oauth_data]
+
+ if auth.present? && params[:user].present?
+ params[:user][:oauth_providers] = [OauthClientPlugin::Provider.find(session[:provider_id])]
+ if request.post? && auth.info.email != params[:user][:email]
+ raise "Wrong email for oauth signup"
+ end
+ end
+ }
+ }
+ end
+
+end
=====================================
plugins/oauth_client/lib/oauth_client_plugin/provider.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/lib/oauth_client_plugin/provider.rb
@@ -0,0 +1,20 @@
+class OauthClientPlugin::Provider < Noosfero::Plugin::ActiveRecord
+
+ belongs_to :environment
+
+ validates_presence_of :name, :strategy
+
+ acts_as_having_image
+ acts_as_having_settings :field => :options
+
+ settings_items :client_id, :type => :string
+ settings_items :client_secret, :type => :string
+ settings_items :client_options, :type => Hash
+
+ attr_accessible :name, :environment, :strategy, :client_id, :client_secret, :enabled, :client_options, :image_builder
+
+ scope :enabled, :conditions => {:enabled => true}
+
+ acts_as_having_image
+
+end
=====================================
plugins/oauth_client/lib/oauth_client_plugin/user_provider.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/lib/oauth_client_plugin/user_provider.rb
@@ -0,0 +1,10 @@
+class OauthClientPlugin::UserProvider < Noosfero::Plugin::ActiveRecord
+
+ belongs_to :user, :class_name => 'User'
+ belongs_to :provider, :class_name => 'OauthClientPlugin::Provider'
+
+ set_table_name :oauth_client_plugin_user_providers
+
+ attr_accessible :user, :provider, :enabled
+
+end
=====================================
plugins/oauth_client/lib/omniauth/strategies/noosfero_oauth2.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/lib/omniauth/strategies/noosfero_oauth2.rb
@@ -0,0 +1,26 @@
+require 'omniauth/strategies/oauth2'
+
+module OmniAuth
+ module Strategies
+ class NoosferoOauth2 < OmniAuth::Strategies::OAuth2
+ option :name, :noosfero_oauth2
+ option :client_options, {
+ :authorize_url => '/oauth_provider/oauth/authorize',
+ :token_url => '/oauth_provider/oauth/token'
+ }
+
+ uid { raw_info["id"] }
+
+ info do
+ {
+ :email => raw_info["email"]
+ }
+ end
+
+ def raw_info
+ #FIXME access the noosfero api (coming soon)
+ @raw_info ||= access_token.get('/plugin/oauth_provider/public/me').parsed
+ end
+ end
+ end
+end
=====================================
plugins/oauth_client/public/style.css
=====================================
--- /dev/null
+++ b/plugins/oauth_client/public/style.css
@@ -0,0 +1,18 @@
+.oauth-login .provider a {
+ min-width: 20px;
+ min-height: 20px;
+ background-size: 20px;
+ display: inline-block;
+ text-decoration: none;
+ background-repeat: no-repeat;
+ line-height: 20px;
+}
+.oauth-login .provider a img {
+ max-width: 40px;
+}
+.oauth-login .provider a:hover {
+ opacity: 0.7;
+}
+.oauth-login .provider .developer {
+ display: none;
+}
=====================================
plugins/oauth_client/test/functional/oauth_client_plugin_public_controller_test.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/test/functional/oauth_client_plugin_public_controller_test.rb
@@ -0,0 +1,80 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class OauthClientPluginPublicControllerTest < ActionController::TestCase
+
+ def setup
+ @auth = mock
+ @auth.stubs(:info).returns(mock)
+ request.env["omniauth.auth"] = @auth
+ @environment = Environment.default
+ @provider = OauthClientPlugin::Provider.create!(:name => 'provider', :strategy => 'provider', :enabled => true)
+ end
+ attr_reader :auth, :environment, :provider
+
+ should 'redirect to signup when user is not found' do
+ auth.info.stubs(:email).returns("xyz123 at noosfero.org")
+ auth.info.stubs(:name).returns('xyz123')
+ session[:provider_id] = provider.id
+
+ get :callback
+ assert_match /.*\/account\/signup/, @response.redirect_url
+ end
+
+ should 'redirect to login when user is found' do
+ user = fast_create(User, :environment_id => environment.id)
+ auth.info.stubs(:email).returns(user.email)
+ auth.info.stubs(:name).returns(user.name)
+ session[:provider_id] = provider.id
+
+ get :callback
+ assert_redirected_to :controller => :account, :action => :login
+ assert_equal user.id, session[:user]
+ end
+
+ should 'do not login when the provider is disabled' do
+ user = fast_create(User, :environment_id => environment.id)
+ auth.info.stubs(:email).returns(user.email)
+ auth.info.stubs(:name).returns(user.name)
+ session[:provider_id] = provider.id
+ provider.update_attribute(:enabled, false)
+
+ get :callback
+ assert_redirected_to :controller => :account, :action => :login
+ assert_equal nil, session[:user]
+ end
+
+ should 'do not login when the provider is disabled for a user' do
+ user = fast_create(User, :environment_id => environment.id)
+ auth.info.stubs(:email).returns(user.email)
+ auth.info.stubs(:name).returns(user.name)
+ session[:provider_id] = provider.id
+ user.oauth_user_providers.create(:user => user, :provider => provider, :enabled => false)
+
+ get :callback
+ assert_redirected_to :controller => :account, :action => :login
+ assert_equal nil, session[:user]
+ end
+
+ should 'save provider when an user login with it' do
+ user = fast_create(User, :environment_id => environment.id)
+ auth.info.stubs(:email).returns(user.email)
+ auth.info.stubs(:name).returns(user.name)
+ session[:provider_id] = provider.id
+
+ get :callback
+ assert_equal [provider], user.oauth_providers
+ end
+
+ should 'do not duplicate relations between an user and a provider when the same provider was used again in a login' do
+ user = fast_create(User, :environment_id => environment.id)
+ auth.info.stubs(:email).returns(user.email)
+ auth.info.stubs(:name).returns(user.name)
+ session[:provider_id] = provider.id
+
+ get :callback
+ assert_no_difference 'user.oauth_user_providers.count' do
+ 3.times { get :callback }
+ end
+ end
+
+end
=====================================
plugins/oauth_client/test/test_helper.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/test/test_helper.rb
@@ -0,0 +1 @@
+require File.dirname(__FILE__) + '/../../../test/test_helper'
=====================================
plugins/oauth_client/test/unit/environment_test.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/test/unit/environment_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class UserTest < ActiveSupport::TestCase
+
+ should 'be able to add oauth providers in a environment' do
+ env = fast_create(Environment)
+ env.oauth_providers << OauthClientPlugin::Provider.new(:name => 'test', :strategy => 'test')
+ end
+
+end
=====================================
plugins/oauth_client/test/unit/oauth_client_plugin_test.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/test/unit/oauth_client_plugin_test.rb
@@ -0,0 +1,86 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class OauthClientPluginTest < ActiveSupport::TestCase
+
+ def setup
+ @plugin = OauthClientPlugin.new(self)
+ @params = {}
+ @plugin.stubs(:context).returns(self)
+ @environment = Environment.default
+ @session = {}
+ @request = mock
+ @provider = OauthClientPlugin::Provider.create!(:name => 'name', :strategy => 'strategy')
+ end
+
+ attr_reader :params, :plugin, :environment, :session, :request, :provider
+
+ should 'has extra contents for login' do
+ assert plugin.login_extra_contents
+ end
+
+ should 'has no signup extra contents if no provider was enabled' do
+ assert_equal '', instance_eval(&plugin.signup_extra_contents)
+ end
+
+ should 'has signup extra contents if oauth_data exists in session' do
+ session[:oauth_data] = {:oauth => 'test'}
+ expects(:render).with(:partial => 'account/oauth_signup').once
+ instance_eval(&plugin.signup_extra_contents)
+ end
+
+ should 'define before filter for account controller' do
+ assert plugin.account_controller_filters
+ end
+
+ should 'raise error if oauth email was changed' do
+ request.expects(:post?).returns(true)
+
+ oauth_data = mock
+ info = mock
+ oauth_data.stubs(:info).returns(info)
+ oauth_data.stubs(:uid).returns('uid')
+ oauth_data.stubs(:provider).returns('provider')
+ info.stubs(:email).returns('test at example.com')
+ session[:oauth_data] = oauth_data
+ session[:provider_id] = provider.id
+
+ params[:user] = {:email => 'test2 at example.com'}
+ assert_raises RuntimeError do
+ instance_eval(&plugin.account_controller_filters[:block])
+ end
+ end
+
+ should 'do not raise error if oauth email was not changed' do
+ request.expects(:post?).returns(true)
+
+ oauth_data = mock
+ info = mock
+ oauth_data.stubs(:info).returns(info)
+ oauth_data.stubs(:uid).returns('uid')
+ oauth_data.stubs(:provider).returns('provider')
+ info.stubs(:email).returns('test at example.com')
+ session[:oauth_data] = oauth_data
+ session[:provider_id] = provider.id
+
+ params[:user] = {:email => 'test at example.com'}
+ instance_eval(&plugin.account_controller_filters[:block])
+ end
+
+ should 'do not raise error if oauth session is not set' do
+ instance_eval(&plugin.account_controller_filters[:block])
+ end
+
+ should 'do not raise error if it is not a post' do
+ request.expects(:post?).returns(false)
+ params[:user] = {:email => 'test2 at example.com'}
+
+ oauth_data = mock
+ oauth_data.stubs(:uid).returns('uid')
+ oauth_data.stubs(:provider).returns('provider')
+ session[:provider_id] = provider.id
+
+ session[:oauth_data] = oauth_data
+ instance_eval(&plugin.account_controller_filters[:block])
+ end
+
+end
=====================================
plugins/oauth_client/test/unit/user_test.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/test/unit/user_test.rb
@@ -0,0 +1,40 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class UserTest < ActiveSupport::TestCase
+
+ def setup
+ @provider = OauthClientPlugin::Provider.create!(:name => 'name', :strategy => 'strategy')
+ end
+ attr_reader :provider
+
+ should 'password is not required if there is a oauth provider' do
+ User.create!(:email => 'testoauth at example.com', :login => 'testoauth', :oauth_providers => [provider])
+ end
+
+ should 'password is required if there is a oauth provider' do
+ user = User.new(:email => 'testoauth at example.com', :login => 'testoauth')
+ user.save
+ assert user.errors[:password].present?
+ end
+
+ should 'activate user when created with oauth' do
+ user = User.create!(:email => 'testoauth at example.com', :login => 'testoauth', :oauth_providers => [provider])
+ assert user.activated?
+ end
+
+ should 'not activate user when created without oauth' do
+ user = fast_create(User)
+ assert !user.activated?
+ end
+
+ should 'not make activation code when created with oauth' do
+ user = User.create!(:email => 'testoauth at example.com', :login => 'testoauth', :oauth_providers => [provider])
+ assert !user.activation_code
+ end
+
+ should 'make activation code when created without oauth' do
+ user = User.create!(:email => 'testoauth at example.com', :login => 'testoauth', :password => 'test', :password_confirmation => 'test')
+ assert user.activation_code
+ end
+
+end
=====================================
plugins/oauth_client/views/account/_oauth_signup.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/views/account/_oauth_signup.html.erb
@@ -0,0 +1,11 @@
+<%= hidden_field_tag 'return_to', '/' %>
+
+<style>
+ #signup-password, #signup-password-confirmation, #signup-email {
+ display: none;
+ }
+</style>
+
+<div id='signup-email-readonly'>
+ <%= labelled_form_field(_('Email'), text_field(:user, :email, :class => "disabled", :readonly => true)) %>
+</div>
=====================================
plugins/oauth_client/views/auth/_oauth_login.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/views/auth/_oauth_login.html.erb
@@ -0,0 +1,16 @@
+<div class="oauth-login">
+ <% unless providers.empty? %>
+ <%= _('Login with:') %>
+ <% end %>
+ <% providers.each do |provider| %>
+ <span class="provider">
+ <%= link_to provider.image ? image_tag(provider.image.public_filename) : provider.name, "/plugin/oauth_client/#{provider.strategy}?id=#{provider.id}", :class => provider.strategy, :title => provider.name %>
+ </span>
+ <% end %>
+
+ <span class="provider">
+ <% unless Rails.env.production? %>
+ <%= link_to _('Developer Login'), "/plugin/oauth_client/developer", :class => 'developer' %>
+ <% end %>
+ </span>
+</div>
=====================================
plugins/oauth_client/views/oauth_client_plugin_admin/_noosfero_oauth2.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/views/oauth_client_plugin_admin/_noosfero_oauth2.html.erb
@@ -0,0 +1,5 @@
+<%= f.fields_for :client_options, OpenStruct.new(provider.options[:client_options]) do |c| %>
+ <div class="client-url">
+ <%= labelled_form_field _('Client Url'), c.text_field(:site) %>
+ </div>
+<% end %>
=====================================
plugins/oauth_client/views/oauth_client_plugin_admin/edit.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/views/oauth_client_plugin_admin/edit.html.erb
@@ -0,0 +1,39 @@
+<h1><%= _('Oauth Client Settings') %></h1>
+<h3><%= _('Edit Provider') %></h3>
+
+<%= form_for @provider, :url => {:action => 'edit'}, :method => 'post' do |f| %>
+
+ <div class="enabled">
+ <%= labelled_form_field f.check_box(:enabled) + _('Enabled'), '' %>
+ </div>
+
+ <div class="name">
+ <%= labelled_form_field _('Name'), f.text_field(:name) %>
+ </div>
+
+ <div class="strategy">
+ <%= labelled_form_field _('Strategy'), f.select(:strategy, OauthClientPlugin::PROVIDERS) %>
+ </div>
+
+ <div class="client-id">
+ <%= labelled_form_field _('Client Id'), f.text_field(:client_id) %>
+ </div>
+
+ <div class="client-secret">
+ <%= labelled_form_field _('Client Secret'), f.text_field(:client_secret) %>
+ </div>
+
+ <% if File.exists?(File.join(File.dirname(__FILE__), "_#{@provider.strategy}.html.erb")) %>
+ <%= render :partial => "#{@provider.strategy}", :locals => {:f => f, :provider => @provider} %>
+ <% end %>
+
+ <div class="image-icon">
+ <%= f.fields_for :image_builder, @provider.image do |i| %>
+ <%= file_field_or_thumbnail(_('Image:'), @provider.image, i) %><%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %>
+ <% end %>
+ </div>
+
+ <% button_bar do %>
+ <%= submit_button(:save, _('Save'), :cancel => {:action => 'index'}) %>
+ <% end %>
+<% end %>
=====================================
plugins/oauth_client/views/oauth_client_plugin_admin/index.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_client/views/oauth_client_plugin_admin/index.html.erb
@@ -0,0 +1,24 @@
+<h1><%= _('Oauth Client Settings') %></h1>
+<h3><%= _('Providers') %></h3>
+<%= button :add, _('New'), {:action => 'new'} %>
+<table>
+ <tr>
+ <th><%= _('Name') %></th>
+ <th><%= _('Strategy') %></th>
+ <th><%= _('Actions') %></th>
+ </tr>
+
+ <% environment.oauth_providers.each do |provider| %>
+ <tr>
+ <td><%= provider.name %></td>
+ <td><%= provider.strategy %></td>
+ <td>
+ <%= link_to _('Edit'), {:action => 'edit', :id => provider.id} %>
+ <%= link_to _('Remove'), {:action => 'remove', :id => provider.id} %>
+ </td>
+ </tr>
+ <% end %>
+</table>
+<div class="actions">
+ <%= button(:back, _('Go back'), {:controller => 'plugins', :action => 'index'}) %>
+</div>
=====================================
plugins/oauth_provider/Gemfile
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/Gemfile
@@ -0,0 +1 @@
+gem 'doorkeeper', '~> 1.4.0'
=====================================
plugins/oauth_provider/README.md
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/README.md
@@ -0,0 +1,47 @@
+README - Oauth Provider Plugin
+================================
+
+OauthProvider is a plugin which allow noosfero to be used as an oauth provider
+
+Install
+=======
+
+Enable Plugin
+-------------
+
+cd <your_noosfero_dir>
+./script/noosfero-plugins enable oauth_provider
+
+Active Plugin
+-------------
+
+As a Noosfero administrator user, go to administrator panel:
+
+- Click on "Enable/disable plugins" option
+- Click on "Oauth Provider Plugin" check-box
+
+Varnish Settings
+================
+If varnish has been used in your stack, you've to prevent cookies to be removed when calling authorization actions for oauth_provider. E.g.:
+
+```
+if (req.url !~ "^/plugin/oauth_provider/*" && req.http.cookie !~ "_noosfero_.*") {
+ unset req.http.cookie;
+ return(lookup);
+}
+```
+
+Development
+===========
+
+Running OauthProvider tests
+--------------------
+
+$ rake test:noosfero_plugins:oauth_provider
+
+License
+=======
+
+Copyright (c) The Author developers.
+
+See Noosfero license.
=====================================
plugins/oauth_provider/controllers/doorkeeper/application_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/controllers/doorkeeper/application_controller.rb
@@ -0,0 +1,8 @@
+module Doorkeeper
+ class ApplicationController < ApplicationController
+
+ include Helpers::Controller
+ helper 'doorkeeper/form_errors'
+
+ end
+end
=====================================
plugins/oauth_provider/controllers/oauth_provider_applications_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/controllers/oauth_provider_applications_controller.rb
@@ -0,0 +1,9 @@
+class OauthProviderApplicationsController < Doorkeeper::ApplicationsController
+
+ no_design_blocks
+ layout :get_layout
+
+ def show
+ end
+
+end
=====================================
plugins/oauth_provider/controllers/oauth_provider_authorizations_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/controllers/oauth_provider_authorizations_controller.rb
@@ -0,0 +1,9 @@
+class OauthProviderAuthorizationsController < Doorkeeper::AuthorizationsController
+
+ no_design_blocks
+ layout :get_layout
+
+ def index
+ end
+
+end
=====================================
plugins/oauth_provider/controllers/oauth_provider_authorized_applications_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/controllers/oauth_provider_authorized_applications_controller.rb
@@ -0,0 +1,6 @@
+class OauthProviderAuthorizedApplicationsController < Doorkeeper::AuthorizedApplicationsController
+
+ no_design_blocks
+ layout :get_layout
+
+end
=====================================
plugins/oauth_provider/controllers/oauth_provider_plugin_admin_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/controllers/oauth_provider_plugin_admin_controller.rb
@@ -0,0 +1,6 @@
+class OauthProviderPluginAdminController < AdminController
+
+ def index
+ end
+
+end
=====================================
plugins/oauth_provider/controllers/public/oauth_provider_plugin_public_controller.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/controllers/public/oauth_provider_plugin_public_controller.rb
@@ -0,0 +1,10 @@
+class OauthProviderPluginPublicController < PublicController
+
+ doorkeeper_for :me
+
+ def me
+ user = environment.users.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
+ render :json => {:id =>user.login, :email => user.email}.to_json
+ end
+
+end
=====================================
plugins/oauth_provider/db/migrate/20140829153047_create_doorkeeper_tables.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/db/migrate/20140829153047_create_doorkeeper_tables.rb
@@ -0,0 +1,41 @@
+class CreateDoorkeeperTables < ActiveRecord::Migration
+ def change
+ create_table :oauth_applications do |t|
+ t.string :name, null: false
+ t.string :uid, null: false
+ t.string :secret, null: false
+ t.text :redirect_uri, null: false
+ t.timestamps
+ end
+
+ add_index :oauth_applications, :uid, unique: true
+
+ create_table :oauth_access_grants do |t|
+ t.integer :resource_owner_id, null: false
+ t.integer :application_id, null: false
+ t.string :token, null: false
+ t.integer :expires_in, null: false
+ t.text :redirect_uri, null: false
+ t.datetime :created_at, null: false
+ t.datetime :revoked_at
+ t.string :scopes
+ end
+
+ add_index :oauth_access_grants, :token, unique: true
+
+ create_table :oauth_access_tokens do |t|
+ t.integer :resource_owner_id
+ t.integer :application_id
+ t.string :token, null: false
+ t.string :refresh_token
+ t.integer :expires_in
+ t.datetime :revoked_at
+ t.datetime :created_at, null: false
+ t.string :scopes
+ end
+
+ add_index :oauth_access_tokens, :token, unique: true
+ add_index :oauth_access_tokens, :resource_owner_id
+ add_index :oauth_access_tokens, :refresh_token, unique: true
+ end
+end
=====================================
plugins/oauth_provider/lib/oauth_provider_plugin.rb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/lib/oauth_provider_plugin.rb
@@ -0,0 +1,55 @@
+class OauthProviderPlugin < Noosfero::Plugin
+
+ def self.plugin_name
+ "Oauth Provider Plugin"
+ end
+
+ def self.plugin_description
+ _("Oauth Provider.")
+ end
+
+ def stylesheet?
+ true
+ end
+
+ Doorkeeper.configure do
+ orm :active_record
+
+ resource_owner_authenticator do
+ domain = Domain.find_by_name(request.host)
+ environment = domain ? domain.environment : Environment.default
+ environment.users.find_by_id(session[:user]) || redirect_to('/account/login')
+ end
+
+ admin_authenticator do
+ domain = Domain.find_by_name(request.host)
+ environment = domain ? domain.environment : Environment.default
+ user = environment.users.find_by_id(session[:user])
+ unless user && user.person.is_admin?(environment)
+ redirect_to('/account/login')
+ end
+ user
+ end
+
+ default_scopes :public
+ end
+
+ Rails.configuration.to_prepare do
+ Rails.application.routes.prepend do
+ scope 'oauth_provider' do
+ use_doorkeeper do
+ controllers ({
+ :applications => 'oauth_provider_applications',
+ :authorized_applications => 'oauth_provider_authorized_applications',
+ :authorizations => 'oauth_provider_authorizations'
+ })
+ end
+ end
+ end
+ end
+
+ SCOPE_TRANSLATION = {
+ 'public' => _('Access your public data')
+ }
+
+end
=====================================
plugins/oauth_provider/public/style.css
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/public/style.css
@@ -0,0 +1,13 @@
+.oauth-provider-authorize .actions form {
+ display: inline-block;
+}
+.oauth-provider-authorize .h4 {
+ font-size: 14px;
+ color: rgb(36, 36, 36)
+}
+.oauth-provider-authorize #oauth-permissions {
+ color: rgb(92, 92, 92);
+}
+.oauth-provider .actions {
+ margin-top: 10px;
+}
=====================================
plugins/oauth_provider/views/doorkeeper/applications/_delete_form.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/applications/_delete_form.html.erb
@@ -0,0 +1,5 @@
+<%- submit_btn_css ||= 'btn btn-link' %>
+<%= form_tag [:oauth, application] do %>
+ <input type="hidden" name="_method" value="delete">
+ <%= submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css %>
+<% end %>
=====================================
plugins/oauth_provider/views/doorkeeper/applications/_form.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/applications/_form.html.erb
@@ -0,0 +1,39 @@
+<%= form_for [:oauth, application], html: {class: 'form-horizontal', role: 'form'} do |f| %>
+ <% if application.errors.any? %>
+ <div class="alert alert-danger" data-alert>
+ <p><%= _('Whoops! Check your form for possible errors') %></p>
+ </div>
+ <% end %>
+
+ <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do %>
+ <%= f.label :name, class: 'col-sm-2 control-label', for: 'application_name' %>
+ <div class="col-sm-10">
+ <%= f.text_field :name, class: 'form-control' %>
+ <%= doorkeeper_errors_for application, :name %>
+ </div>
+ <% end %>
+
+ <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do %>
+ <%= f.label :redirect_uri, class: 'col-sm-2 control-label', for: 'application_redirect_uri' %>
+ <div class="col-sm-10">
+ <%= f.text_area :redirect_uri, class: 'form-control' %>
+ <%= doorkeeper_errors_for application, :redirect_uri %>
+ <span class="help-block">
+ <%= _('Use one line per URI') %>
+ </span>
+ <% if Doorkeeper.configuration.native_redirect_uri %>
+ <span class="help-block">
+ Use <code><%= Doorkeeper.configuration.native_redirect_uri %></code> for local tests
+ </span>
+ <% end %>
+ </div>
+ <% end %>
+
+ <div class="form-group">
+ <div class="col-sm-offset-2 col-sm-10">
+ <%= f.submit _('Submit'), class: "btn btn-primary" %>
+ <%= link_to _("Cancel"), oauth_applications_path, :class => "btn btn-default" %>
+ </div>
+ </div>
+<% end %>
+
=====================================
plugins/oauth_provider/views/doorkeeper/applications/edit.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/applications/edit.html.erb
@@ -0,0 +1,5 @@
+<div class="page-header">
+ <h1><%= _('Edit application') %></h1>
+</div>
+
+<%= render 'form', application: @application %>
=====================================
plugins/oauth_provider/views/doorkeeper/applications/index.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/applications/index.html.erb
@@ -0,0 +1,31 @@
+<div class="oauth-provider">
+<div class="page-header">
+ <h3><%= link_to _('Oauh Provider'), '/admin/plugin/oauth_provider' %></h3>
+</div>
+
+<p><%= link_to _('New Application'), new_oauth_application_path, class: 'btn btn-success' %></p>
+
+<table class="table table-striped">
+ <thead>
+ <tr>
+ <th><%= _('Name') %></th>
+ <th><%= _('Callback URL') %></th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @applications.each do |application| %>
+ <tr id="application_<%= application.id %>">
+ <td><%= link_to application.name, [:oauth, application] %></td>
+ <td><%= application.redirect_uri %></td>
+ <td><%= link_to _('Edit'), edit_oauth_application_path(application), class: 'btn btn-link' %></td>
+ <td><%= render 'delete_form', application: application %></td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
+<div class="actions">
+ <%= button(:back, _('Go back'), {:controller => 'oauth_provider_plugin_admin', :action => 'index'}) %>
+</div>
+</div>
=====================================
plugins/oauth_provider/views/doorkeeper/applications/new.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/applications/new.html.erb
@@ -0,0 +1,5 @@
+<div class="page-header">
+ <h1>New application</h1>
+</div>
+
+<%= render 'form', application: @application %>
=====================================
plugins/oauth_provider/views/doorkeeper/applications/show.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/applications/show.html.erb
@@ -0,0 +1,40 @@
+<div class="page-header">
+ <h1><%= _('Application: %s' % @application.name) %></h1>
+</div>
+
+<div class="row">
+ <div class="col-md-8">
+ <h4><%= _('Application Id:') %></h4>
+
+ <p><code id="application_id"><%= @application.uid %></code></p>
+
+ <h4><%= _('Secret:') %></h4>
+
+ <p><code id="secret"><%= @application.secret %></code></p>
+
+ <h4><%= _('Callback urls:') %></h4>
+
+ <table>
+ <% @application.redirect_uri.split.each do |uri| %>
+ <tr>
+ <td>
+ <code><%= uri %></code>
+ </td>
+ <td>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ </div>
+
+ <div class="col-md-4">
+ <h3><%= _('Actions') %></h3>
+
+ <p>
+ <%= link_to _('Edit'), edit_oauth_application_path(@application), class: 'btn btn-primary' %>
+ <%= link_to _("Cancel"), oauth_applications_path, :class => "btn btn-default" %>
+ </p>
+
+ <p><%= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger' %></p>
+ </div>
+</div>
=====================================
plugins/oauth_provider/views/doorkeeper/authorizations/error.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/authorizations/error.html.erb
@@ -0,0 +1,7 @@
+<div class="page-header">
+ <h1>An error has occurred</h1>
+</div>
+
+<main role="main">
+ <pre><%= @pre_auth.error_response.body[:error_description] %></pre>
+</main>
=====================================
plugins/oauth_provider/views/doorkeeper/authorizations/new.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/authorizations/new.html.erb
@@ -0,0 +1,43 @@
+<div class="oauth-provider-authorize">
+
+<header class="page-header" role="banner">
+ <h1><%= _('Authorize required') %></h1>
+</header>
+
+<main role="main">
+ <p class="h4">
+ <%= _('Authorize %s to use your account?' % "<strong class=\"text-info\">#{@pre_auth.client.name}</strong>") %>
+ </p>
+
+ <% if @pre_auth.scopes %>
+ <div id="oauth-permissions">
+ <p><%= _('This application will be able to:') %></p>
+
+ <ul class="text-info">
+ <% @pre_auth.scopes.each do |scope| %>
+ <li><%= OauthProviderPlugin::SCOPE_TRANSLATION[scope] %></li>
+ <% end %>
+ </ul>
+ </div>
+ <% end %>
+
+ <div class="actions">
+ <%= form_tag oauth_authorization_path, method: :post do %>
+ <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
+ <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
+ <%= hidden_field_tag :state, @pre_auth.state %>
+ <%= hidden_field_tag :response_type, @pre_auth.response_type %>
+ <%= hidden_field_tag :scope, @pre_auth.scope %>
+ <%= submit_button :ok, _("Authorize") %>
+ <% end %>
+ <%= form_tag oauth_authorization_path, method: :delete do %>
+ <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
+ <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
+ <%= hidden_field_tag :state, @pre_auth.state %>
+ <%= hidden_field_tag :response_type, @pre_auth.response_type %>
+ <%= hidden_field_tag :scope, @pre_auth.scope %>
+ <%= submit_button :cancel, _("Deny") %>
+ <% end %>
+ </div>
+</main>
+</div>
=====================================
plugins/oauth_provider/views/doorkeeper/authorizations/show.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/authorizations/show.html.erb
@@ -0,0 +1,7 @@
+<header class="page-header">
+ <h1>Authorization code:</h1>
+</header>
+
+<main role="main">
+ <code id="authorization_code"><%= params[:code] %></code>
+</main>
=====================================
plugins/oauth_provider/views/doorkeeper/authorized_applications/_delete_form.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/authorized_applications/_delete_form.html.erb
@@ -0,0 +1,5 @@
+<%- submit_btn_css ||= 'btn btn-link' %>
+<%= form_tag oauth_authorized_application_path(application) do %>
+ <input type="hidden" name="_method" value="delete">
+ <%= submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: submit_btn_css %>
+<% end %>
=====================================
plugins/oauth_provider/views/doorkeeper/authorized_applications/index.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/doorkeeper/authorized_applications/index.html.erb
@@ -0,0 +1,31 @@
+<div class="oauth-provider">
+<header class="page-header">
+ <h1>Your authorized applications</h1>
+</header>
+
+<main role="main">
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th>Application</th>
+ <th>Created At</th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @applications.each do |application| %>
+ <tr>
+ <td><%= application.name %></td>
+ <td><%= application.created_at.strftime('%Y-%m-%d %H:%M:%S') %></td>
+ <td><%= render 'delete_form', application: application %></td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+</main>
+
+<div class="actions">
+ <%= button(:back, _('Go back'), :back) %>
+</div>
+</div>
=====================================
plugins/oauth_provider/views/oauth_provider_plugin_admin/index.html.erb
=====================================
--- /dev/null
+++ b/plugins/oauth_provider/views/oauth_provider_plugin_admin/index.html.erb
@@ -0,0 +1,14 @@
+<div class="oauth-provider">
+<h3><%= _('Oauh Provider') %></h3>
+
+ <div class="applications">
+ <%= link_to _('Applications'), oauth_applications_path %>
+ </div>
+ <div class="authorized-applications">
+ <%= link_to _('Authorized Applications'), oauth_authorized_applications_path %>
+ </div>
+
+ <div class="actions">
+ <%= button(:back, _('Go back'), {:controller => 'plugins', :action => 'index'}) %>
+ </div>
+</div>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20150222/97ba69fd/attachment-0001.html>
More information about the Noosfero-dev
mailing list