diff --git a/app/controllers/concerns/submission_controller.rb b/app/controllers/concerns/submission_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0d1ade4070ad3e502be875793d06976e62c113c6
--- /dev/null
+++ b/app/controllers/concerns/submission_controller.rb
@@ -0,0 +1,63 @@
+
+# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
+# Departamento de Informatica - Universidade Federal do Parana
+#
+# This file is part of portalmec.
+#
+# portalmec is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# portalmec is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
+module SubmissionController
+    extend ActiveSupport::Concern
+    include ::Paginator
+
+    included do
+        before_action :set_new_submission, only: :submit
+        before_action :set_submission, only: :show_submission
+        before_action :authorize!
+    end
+
+    def submissions
+        learning_objects = paginate LearningObject.where(state: LearningObject.states[:submitted])
+        render json: learning_objects
+    end
+
+    def submit
+        return render status: :ok if @learning_object.submitted?
+
+        if @learning_object.update(state: LearningObject.states[:submitted])
+            render json: @learning_object, status: :ok
+        else
+            render json: @learning_object.errors, status: :unprocessable_entity
+        end
+    end
+
+    def show_submission
+      return render status: :ok if @learning_object.draft? || @learning_object.published?
+      render json: @learning_object
+    end
+
+    private
+
+    def submitted
+        return @learning_object.submitted?
+    end
+
+    def set_new_submission
+        @learning_object = LearningObject.find(params[:id])
+    end
+
+    def set_submission
+      @learning_object ||= LearningObject.find(params[:id])
+    end
+
+end
diff --git a/app/controllers/v1/learning_objects/publishes_controller.rb b/app/controllers/v1/learning_objects/publishes_controller.rb
index 75efb858ae099a5f4700e17bda5fab52e24d8538..a76ba612e35d082bb32aa3e6b8bbfb9f8b3a43d7 100644
--- a/app/controllers/v1/learning_objects/publishes_controller.rb
+++ b/app/controllers/v1/learning_objects/publishes_controller.rb
@@ -39,7 +39,7 @@ class V1::LearningObjects::PublishesController < ApplicationController
   end
 
   def authorize!
-    authorize(@learning_object || LearningObject.new, :update?)
+    authorize(@learning_object, :publish?)
   end
 
   # Never trust parameters from the scary internet, only allow the white list through.
diff --git a/app/controllers/v1/learning_objects_controller.rb b/app/controllers/v1/learning_objects_controller.rb
index eda09d0a99e32ceaa5232edfa44f1186fe5298d6..1a055f4190af4dddb66cde263cae3d06e8fe76f6 100644
--- a/app/controllers/v1/learning_objects_controller.rb
+++ b/app/controllers/v1/learning_objects_controller.rb
@@ -28,10 +28,13 @@ class V1::LearningObjectsController < ApplicationController
   include ::HighlightsController
   include ::SubjectableController
   include ::StageableController
+  include ::SubmissionController
 
-  before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging]
+  before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging, :submit, :submission, :show_submission]
   before_action :set_learning_object, only: [:show, :update, :destroy, :subjecting, :unsubjecting, :add_stages, :remove_stages]
-  before_action :set_new_learning_object, only: :index
+  before_action :set_new_learning_object, only: [:index, :submissions]
+  before_action :set_new_submission, only: :submit
+  before_action :set_submission, only: :show_submission
   before_action :authorize!, except: [:create, :tagging, :untagging, :download, :magnetlink]
   before_action :set_paper_trail_whodunnit, except: [:index, :show]
 
diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb
index ca63b2aec4ce58f8394d64f8ccf07947d7de33cb..0207691aacbf8f25d6a9b0ccc4006dad7d70181b 100644
--- a/app/controllers/v1/users_controller.rb
+++ b/app/controllers/v1/users_controller.rb
@@ -24,9 +24,11 @@ class V1::UsersController < ApplicationController
   include ::PublisherController
 	include ::SubjectableController
 
-  before_action :set_user, only: [:show, :update, :destroy, :following, :own_reviews, :received_reviews, :followers]
-  before_action :authenticate_user!, only: [:create, :update, :destroy, :following, :own_reviews, :received_reviews, :followers]
-  before_action :authorize_user, only: [:own_reviews, :received_reviews, :update, :destroy]
+  before_action :set_user, only: [:show, :update, :destroy, :following, :own_reviews, :received_reviews, :followers, :approve_request]
+  before_action :set_new_user, only: [:upload_requests]
+  before_action :authenticate_user!, only: [:create, :update, :destroy, :following,
+                :own_reviews, :received_reviews, :followers, :submitter_request, :upload_requests, :approve_request]
+  before_action :authorize_user, only: [:own_reviews, :received_reviews, :update, :destroy, :upload_requests, :approve_request]
 
   # GET /v1/users
   # GET /v1/users.json
@@ -77,6 +79,43 @@ class V1::UsersController < ApplicationController
     render status: :ok
   end
 
+  # POST /v1/users/submitter_request
+  # POST /v1/users/submitter_request.json
+  def submitter_request
+    if current_user.update(submitter_request: User.submitter_requests[:requested])
+      render status: :ok
+    else
+      render status: :forbidden
+    end
+  end
+
+  # GET /v1/users/upload_requests
+  # GET /v1/users/upload_requests.json
+  def upload_requests
+    users = paginate User.where(submitter_request: User.submitter_requests[:requested])
+    render json: users
+  end
+
+  # POST /v1/users/:id/approve_request
+  # POST /v1/users/:id/approve_request.json
+  def approve_request
+    if @user.requested?
+      if !approve_params.to_s.blank?
+        if approve_params
+          @user.update(submitter_request: User.submitter_requests[:accepted], roles: Role.where(name: "submitter"))
+          render status: :ok
+        else
+          @user.update(submitter_request: User.submitter_requests[:rejected])
+          render status: :ok
+        end
+      else
+        render status: :forbidden
+      end
+    else
+      render status: :forbidden
+    end
+  end
+
   def following
     type = params[:object_type]
     is_current = (@user.id == current_user.id) unless current_user.nil?
@@ -115,6 +154,10 @@ class V1::UsersController < ApplicationController
     @user = User.find(params[:id])
   end
 
+  def set_new_user
+    @user ||= User.new
+  end
+
   # Never trust parameters from the scary internet, only allow the white list through.
   def user_params
     params.require(:user).permit(
@@ -131,6 +174,10 @@ class V1::UsersController < ApplicationController
     )
   end
 
+  def approve_params
+    params.require(:approves)
+  end
+
   def association_params
     return {} if params[:user].nil?
     params[:user].permit(subjects: [])
diff --git a/app/models/concerns/stateful.rb b/app/models/concerns/stateful.rb
index ef79f6b2e4da6f8e12c0ccbc286998dff3f9421e..224a221ae97e9970a02c2056e08846f2efc988a2 100644
--- a/app/models/concerns/stateful.rb
+++ b/app/models/concerns/stateful.rb
@@ -21,6 +21,6 @@ module Stateful
   extend ActiveSupport::Concern
 
   included do
-    enum state: { draft: 0, published: 1, suspended: 2 }
+    enum state: { draft: 0, published: 1, suspended: 2, submitted: 3 }
   end
 end
diff --git a/app/models/role.rb b/app/models/role.rb
index 0ae8eebe379bb281f1e75ccc905111072d356694..4d4af8793c300b988ab2d788bff92062d3d7813c 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -52,4 +52,21 @@ class Role < ApplicationRecord
   def self.moderator
     find_by(name: 'moderator') || create!(name: 'moderator')
   end
+
+  def self.editor
+    find_by(name: 'editor') || create!(name: 'editor')
+  end
+
+  def self.supervisor
+    find_by(name: 'supervisor') || create!(name: 'supervisor')
+  end
+
+  def self.submitter
+    find_by(name: 'submitter') || create!(name: 'submitter')
+  end
+
+  def self.partner
+    find_by(name: 'partner') || create!(name: 'partner')
+  end
+
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index f913694f750906207967a56009d6920dea087282..d603fdd3f8e11a30ef392c71e3e1372bce5443bf 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -97,6 +97,8 @@ class User < ApplicationRecord
 
   validates :terms_of_service, acceptance: true
 
+  enum submitter_request: { default: 0, requested: 1, accepted: 2, rejected: 3 }
+
   searchkick language: 'brazilian', match: :word_start, searchable: [:name], callbacks: :async
 
   acts_as_paranoid
@@ -125,8 +127,43 @@ class User < ApplicationRecord
     false
   end
 
-  def can_moderate?
-    self.is_admin? || self.is_moderator?
+  def is_curator?
+    roles.each do |role|
+      return true if role.name == 'curator'
+    end
+    false
+  end
+
+  def is_supervisor?
+    roles.each do |role|
+      return true if role.name == 'supervisor'
+    end
+    false
+  end
+
+  def is_editor?
+    roles.each do |role|
+      return true if role.name == 'editor'
+    end
+    false
+  end
+
+  def is_submitter?
+    roles.each do |role|
+      return true if role.name == 'submitter'
+    end
+    false
+  end
+
+  def is_partner?
+    roles.each do |role|
+      return true if role.name == 'partner'
+    end
+    false
+  end
+
+  def can_edit?
+    self.is_admin? || self.is_editor?
   end
 
   def associated_collections
diff --git a/app/policies/activity_policy.rb b/app/policies/activity_policy.rb
index 1592b3f39ffa4c09f7e33ac9e8ed49a0bb5711f3..8d98a493fbc40a7072d9bf09132ee9f7b35d18f7 100644
--- a/app/policies/activity_policy.rb
+++ b/app/policies/activity_policy.rb
@@ -28,7 +28,7 @@ class ActivityPolicy < ApplicationPolicy
     end
 
     def resolve
-      if user_can_moderate?
+      if user_can_edit?
         scope.includes(:owner,:recipient).order('created_at DESC').all
       else
         scope.includes(:owner,:recipient).where("privacy = 'public'").where(key: activities_filter).order('created_at DESC').all
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
index 84a418d6fcc60b4b842ae72efefde22081ef49ae..640d6e3966daa2f9e12fea5fb509586de3bc78cf 100644
--- a/app/policies/application_policy.rb
+++ b/app/policies/application_policy.rb
@@ -59,7 +59,7 @@ class ApplicationPolicy
 
   def owns?
     return false if user.nil?
-    return true if user_can_moderate?
+    return true if user_can_edit?
 
     return owner.users.include?(user) if owner.is_a?(Institution)
 
@@ -74,8 +74,12 @@ class ApplicationPolicy
     raise 'You must implement this method!'
   end
 
-  def user_can_moderate?
-    user.is_admin? || user.is_moderator?
+  def user_can_edit?
+    user.is_admin? || user.is_editor?
+  end
+
+  def user_can_curate?
+    user.is_curator?
   end
 
   class Scope < ApplicationPolicy
diff --git a/app/policies/bookmark_policy.rb b/app/policies/bookmark_policy.rb
index fca92306eb0435a48345b2bfc196a11573e5399e..f256e6a0d95f2b994a9ee60352f492817a4ed0eb 100644
--- a/app/policies/bookmark_policy.rb
+++ b/app/policies/bookmark_policy.rb
@@ -36,7 +36,7 @@ class BookmarkPolicy < ApplicationPolicy
   end
 
   def user_own?
-    record.user == user || user_can_moderate?
+    record.user == user || user_can_edit?
   end
 
 end
diff --git a/app/policies/collection_policy.rb b/app/policies/collection_policy.rb
index de0e62bc7a8e749ace0f7de5162482a2ee0c7865..d2f8403b4f1d097dfc634defff6e26fc94e7ea12 100644
--- a/app/policies/collection_policy.rb
+++ b/app/policies/collection_policy.rb
@@ -27,7 +27,7 @@ class CollectionPolicy < ApplicationPolicy
   class Scope < Scope
     def resolve
       if user_exists?
-        if user_can_moderate?
+        if user_can_edit?
           scope.all
         else
           scope.includes(:collection_items).where.not(:collection_items => {:collection_id => nil}).where("privacy = ? OR owner_id = ?", 'public', user.id)
diff --git a/app/policies/institution_policy.rb b/app/policies/institution_policy.rb
index 7728b76a50ff1a9ae92fd33c916fbf3c2a9273c5..97b3b11a4a9eaa46e26f079d5414c36e6ee1112f 100644
--- a/app/policies/institution_policy.rb
+++ b/app/policies/institution_policy.rb
@@ -19,22 +19,22 @@
 
 class InstitutionPolicy < ApplicationPolicy
   def create?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def update?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def index?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def destroy?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def users?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 end
diff --git a/app/policies/language_policy.rb b/app/policies/language_policy.rb
index 503655751a4aff7291954bb7f2ea86be57eace60..ead10f34ecf0cd59230cc8ea8fd6c77f7a6e456f 100644
--- a/app/policies/language_policy.rb
+++ b/app/policies/language_policy.rb
@@ -27,14 +27,14 @@ class LanguagePolicy < ApplicationPolicy
   end
 
   def create?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def update?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def destroy?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 end
diff --git a/app/policies/learning_object_policy.rb b/app/policies/learning_object_policy.rb
index 8450227a347fa07b8a68c3f47343b05fac836dde..ff55dfcec746a90f337062a1fd627bb5c1c15103 100644
--- a/app/policies/learning_object_policy.rb
+++ b/app/policies/learning_object_policy.rb
@@ -23,12 +23,13 @@ class LearningObjectPolicy < ApplicationPolicy
   include TaggablePolicy
   include SubjectablePolicy
   include StageablePolicy
+  include SubmissionPolicy
 
   class Scope < Scope
     def resolve
       if user.nil?
         scope.where(state: 'published')
-      elsif user_can_moderate?
+      elsif user_can_edit?
         scope.all
       else
         scope.where(state: 'published')
@@ -37,11 +38,15 @@ class LearningObjectPolicy < ApplicationPolicy
   end
 
   def create?
-    record if user_exists?
+    record if (user_exists? && user.is_submitter?) || (user_exists? && user.is_partner?)
   end
 
   def update?
-    record if owns?
+    record if (owns? && user.is_submitter?) || (owns? && user.is_partner?)
+  end
+
+  def publish?
+    record if (user_can_curate? && record.submitted?) || user.is_partner?
   end
 
   def destroy?
@@ -57,7 +62,7 @@ class LearningObjectPolicy < ApplicationPolicy
   end
 
   def show?
-    return record if record.published? || ( !user.nil? && user_can_moderate? )
+    return record if record.published? || ( !user.nil? && user_can_edit? )
     return record if user == record.publisher
     ## TODO: falta verificar se o +record.publisher+ é uma instituição e +user+ faz parte
     # => return owner.users.include?(user) if owner.is_a?(Institution)  (???)
diff --git a/app/policies/license_policy.rb b/app/policies/license_policy.rb
index 53bb36df7fd7963188bf091f73aac76180f07809..2306f9d74f1a2667de4c18061c3791bc9ddfbeb9 100644
--- a/app/policies/license_policy.rb
+++ b/app/policies/license_policy.rb
@@ -27,14 +27,14 @@ class LicensePolicy < ApplicationPolicy
   end
 
   def create?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def update?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def destroy?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 end
diff --git a/app/policies/mime_type_policy.rb b/app/policies/mime_type_policy.rb
index 5501f59681a35b9094ee64a6823ebafcb61e51f0..7ed57f5b8f4a2410415ab83ac4e0e9478333aad0 100644
--- a/app/policies/mime_type_policy.rb
+++ b/app/policies/mime_type_policy.rb
@@ -27,14 +27,14 @@ class MimeTypePolicy < ApplicationPolicy
   end
 
   def create?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def update?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def destroy?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 end
diff --git a/app/policies/object_type_policy.rb b/app/policies/object_type_policy.rb
index d8eb36562a256fee407066234d4023a91ba8b74e..23350084ac7280ddbc2df55ea4c48a3e23af133c 100644
--- a/app/policies/object_type_policy.rb
+++ b/app/policies/object_type_policy.rb
@@ -27,14 +27,14 @@ class ObjectTypePolicy < ApplicationPolicy
   end
 
   def create?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def update?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def destroy?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 end
diff --git a/app/policies/publisher_policy.rb b/app/policies/publisher_policy.rb
index 41e3bafd74ac92aa23f978ed0d85407d49f0dc11..631b5eccfb79d362773e6d120033a53d7932f1bd 100644
--- a/app/policies/publisher_policy.rb
+++ b/app/policies/publisher_policy.rb
@@ -31,7 +31,7 @@ module PublisherPolicy
     def resolve
       if user.nil?
         scope.where(privacy: 'public')
-      elsif user_can_moderate? || record == user
+      elsif user_can_edit? || record == user
         scope.all
       else
         scope.where(privacy: 'public')
@@ -40,15 +40,15 @@ module PublisherPolicy
   end
 
   def show_all_drafts?
-    record if same_user? || user_can_moderate?
+    record if same_user? || user_can_edit?
   end
 
   def show_liked_learning_objects?
-    record if same_user? || user_can_moderate?
+    record if same_user? || user_can_edit?
   end
 
   def show_liked_collections?
-    record if same_user? || user_can_moderate?
+    record if same_user? || user_can_edit?
   end
 
   def same_user?
diff --git a/app/policies/rating_policy.rb b/app/policies/rating_policy.rb
index 57faf562798ffcb193aea3799c30b08138665370..ad2ea081d3622589c86d1becaec0fdae3d49f2c8 100644
--- a/app/policies/rating_policy.rb
+++ b/app/policies/rating_policy.rb
@@ -28,14 +28,14 @@ class RatingPolicy < ApplicationPolicy
   end
 
   def create?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def update?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 
   def destroy?
-    record if user_can_moderate?
+    record if user_can_edit?
   end
 end
diff --git a/app/policies/search_policy.rb b/app/policies/search_policy.rb
index 2708e76e8ece8fb0707d3895bfa049efa9a6f8c6..77cda937f67539985b08f6233ca58d431e51b632 100644
--- a/app/policies/search_policy.rb
+++ b/app/policies/search_policy.rb
@@ -22,7 +22,7 @@ class SearchPolicy < ApplicationPolicy
     def resolve
       if user.nil?
         scope.where(state: 'published')
-      elsif user_can_moderate?
+      elsif user_can_edit?
         scope.all
       else
         scope.where(state: 'published')
diff --git a/app/policies/submission_policy.rb b/app/policies/submission_policy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8290e6fb315e97632707665f252621f50381a31d
--- /dev/null
+++ b/app/policies/submission_policy.rb
@@ -0,0 +1,35 @@
+
+# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
+# Departamento de Informatica - Universidade Federal do Parana
+#
+# This file is part of portalmec.
+#
+# portalmec is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# portalmec is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
+module SubmissionPolicy
+
+  def submit?
+    record if owns? && user.is_submitter?
+  end
+
+  def submissions?
+    return false if user.nil?
+    record if user_can_curate?
+  end
+
+  def show_submission?
+    return false if user.nil?
+    record if user_can_curate?
+  end
+
+end
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index 66dc672881e783e12ea4ec5d290a2a95360aada9..25eb87c915769e033d655c80888d7abeaab6d194 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -40,21 +40,29 @@ class UserPolicy < ApplicationPolicy
   end
 
   def own_reviews?
-    record if same_user? || user_can_moderate?
+    record if same_user? || user_can_edit?
   end
 
   def received_reviews?
-    record if same_user? || user_can_moderate?
+    record if same_user? || user_can_edit?
+  end
+
+  def upload_requests?
+    record if user.is_supervisor?
+  end
+
+  def approve_request?
+    record if user.is_supervisor?
   end
 
   def authorized_user?
     return false if ( record.is_admin? && !user.is_admin? )
-    if ( record.is_moderator? )
+    if ( record.is_editor? )
       if !( same_user? || user.is_admin? )
         return false
       end
     end
-    user_can_moderate?
+    user_can_edit?
   end
 
   def same_user?
diff --git a/app/policies/welcome_policy.rb b/app/policies/welcome_policy.rb
index aa4b93c6e785798009cede89e779a7c07b84db80..0974f3d1612d7cc0982b03e79c5deaaaa4379c1d 100644
--- a/app/policies/welcome_policy.rb
+++ b/app/policies/welcome_policy.rb
@@ -20,7 +20,7 @@
 class WelcomePolicy < ApplicationPolicy
   class Scope < Scope
     def resolve
-      if user_can_moderate?
+      if user_can_edit?
         scope.all
       else
         scope.where(state: 'published')
diff --git a/app/serializers/collection_item_serializer.rb b/app/serializers/collection_item_serializer.rb
index d7c981589b2fafbe37383b573455d36090d0b61f..ecd96630a0f049300b4ef58525a8a0c13196a2c8 100644
--- a/app/serializers/collection_item_serializer.rb
+++ b/app/serializers/collection_item_serializer.rb
@@ -23,7 +23,7 @@ class CollectionItemSerializer < ActiveModel::Serializer
   def collectionable
     if ( object.collectionable_type == "LearningObject" )
     	serializer = ::LearningObjectSerializer
-    elsif ( object.public? || (current_user && ( object.owner?(current_user) || current_user.can_moderate? )) )
+    elsif ( object.public? || (current_user && ( object.owner?(current_user) || current_user.can_edit? )) )
     	serializer = ::CollectionMinSerializer
     end
 
diff --git a/app/serializers/user_devise_serializer.rb b/app/serializers/user_devise_serializer.rb
index ba5c76afae9d726dfa8b84e3576a1196b882ffc7..fdca0ba891fb59cfedfb104385886a647d58adb0 100644
--- a/app/serializers/user_devise_serializer.rb
+++ b/app/serializers/user_devise_serializer.rb
@@ -18,17 +18,17 @@
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
 class UserDeviseSerializer < ActiveModel::Serializer
-  
+
   def avatar_file_name
     object.avatar.url
-  end 
+  end
 
   def cover_file_name
     object.cover.url
   end
 
 
-  attributes :id, :email, :provider, :avatar_file_name, :avatar_content_type, :uid, :name, :avatar_file_size, :avatar_updated_at,
+  attributes :id, :email, :provider, :avatar_file_name, :avatar_content_type, :uid, :name, :submitter_request,  :avatar_file_size, :avatar_updated_at,
              :bookmarks_count, :user_category_id, :score, :follows_count, :deleted_at, :description, :likes_count,
              :learning_objects_count, :collections_count, :cover_file_name, :cover_content_type, :cover_file_size, :cover_updated_at
 end
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index aeda4fdd91a0a512398f8239eaa3d89ffd0a01fb..aff126b4b825c946600d62577120bd6c209a6a04 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -36,6 +36,6 @@ class UserSerializer < ActiveModel::Serializer
     object.learning_objects.where('state = ?', LearningObject.states[:published]).count
   end
 
-  attributes :id, :email, :provider, :name, :description, :education, :score, :cover, :role_ids, :institution_ids, :avatar, :likes_count, :followed, :complained, :follows_count, :learning_objects_count, :collections_count, :created_at, :updated_at
+  attributes :id, :email, :provider, :name, :description, :submitter_request, :education, :score, :cover, :role_ids, :institution_ids, :avatar, :likes_count, :followed, :complained, :follows_count, :learning_objects_count, :collections_count, :created_at, :updated_at
   has_many :subjects
 end
diff --git a/config/routes.rb b/config/routes.rb
index e4af450d887d33df75c8570f23dc7e3a1652e229..cb7691a91eb9f132edb30a4cfb8277139fbd2697 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -77,6 +77,16 @@ Rails.application.routes.draw do
     end
   end
 
+  concern :submission do
+    collection do
+        get :submissions
+    end
+    member do
+        post :submit
+        get :show_submission
+    end
+  end
+
   concern :highlights do
     collection do
       get :this_week
@@ -117,13 +127,18 @@ Rails.application.routes.draw do
     resources :feed, only: [:index]
 
     resources :users, concerns: [:followable, :deletable, :publisher, :versionable] do
-    resources :bookmarks, module: 'users', only: [:index, :create, :destroy]
+      resources :bookmarks, module: 'users', only: [:index, :create, :destroy]
       member do
         get 'following/:object_type', to: 'users#following'
         get 'followers', to: 'users#followers'
         get 'activities', to: 'activities#user_activities'
         get 'reviews/own', to: 'users#own_reviews'
         get 'reviews/received', to: 'users#received_reviews'
+        post 'approve_request', to: 'users#approve_request'
+      end
+      collection do
+        get 'upload_requests'
+        post 'submitter_request'
       end
     end
 
@@ -144,7 +159,7 @@ Rails.application.routes.draw do
       end
     end
 
-    resources :learning_objects, concerns: [:sociable, :downloadable, :reviewable, :taggable, :versionable, :deletable, :highlights, :subjectable, :stageable] do
+    resources :learning_objects, concerns: [:sociable, :downloadable, :reviewable, :taggable, :versionable, :deletable, :highlights, :subjectable, :stageable, :submission] do
       member do
         resource :chunk, module: 'learning_objects', only: [:create, :show]
         resource :upload, module: 'learning_objects', only: :create
diff --git a/db/migrate/20170703175829_add_submitter_request_to_users.rb b/db/migrate/20170703175829_add_submitter_request_to_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..305eab65145b3761c83c26daafa1b5b2292fa2c1
--- /dev/null
+++ b/db/migrate/20170703175829_add_submitter_request_to_users.rb
@@ -0,0 +1,5 @@
+class AddSubmitterRequestToUsers < ActiveRecord::Migration[5.0]
+  def change
+    add_column :users, :submitter_request, :integer, default: 0
+  end
+end
diff --git a/db/seeds.rb b/db/seeds.rb
index d71285d6b0e22d84eef313b80a16526842e6b3a4..108a59c06e460185ea97f6937356391770c138b2 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -29,6 +29,10 @@ Role.create(name: 'student', description: 'This role represents a Student in Por
 Role.create(name: 'admin', description: 'This role represents an MEC Admin, that can perform any action.')
 Role.create(name: 'curator', description: 'This role represents a content Curator in Portal MEC.')
 Role.create(name: 'moderator', description: 'This role represents a content Moderator in Portal MEC, with less privileges than admin.')
+Role.create(name: 'supervisor', description: 'This role represents an user Supervisor in Portal MEC.')
+Role.create(name: 'editor', description: 'This role represents a content Supervisor in Portal MEC, with less privileges than admin.')
+Role.create(name: 'submitter', description: 'This role represents a content submitter in Portal MEC.')
+Role.create(name: 'partner', description: 'This role represents a partner Portal MEC.')
 
 # create the default admin
 User.create(
diff --git a/spec/acceptance/learning_objects_spec.rb b/spec/acceptance/learning_objects_spec.rb
index f49e95bf1233ac4620ad74ea20bfe9cfce1b81fc..dacb36a4916c9bb0fe33ebf7de34e43b8f75bf92 100644
--- a/spec/acceptance/learning_objects_spec.rb
+++ b/spec/acceptance/learning_objects_spec.rb
@@ -60,7 +60,7 @@ resource 'Learning Objects' do
   end
 
   post '/v1/learning_objects' do
-    include_context "authenticate_user"
+    include_context "authenticate_user_submitter"
 
     parameter :author, 'The author of a educational content', scope: :learning_object
     parameter :name, 'The name of the learning object', scope: :learning_object
@@ -98,7 +98,7 @@ resource 'Learning Objects' do
   end
 
   put '/v1/learning_objects/:id' do
-    include_context "authenticate_user"
+    include_context "authenticate_user_submitter"
 
     parameter :author, 'The author of a educational content'
     parameter :name, 'The name of the learning object'
@@ -178,12 +178,12 @@ resource 'Learning Objects' do
    end
 
   post '/v1/learning_objects/:id/publish' do
-    include_context "authenticate_user"
+    include_context "authenticate_user_curator"
 
     let(:id) { @learning_object.id }
 
     before do
-      @learning_object = create(:learning_object, publisher: @user, state: LearningObject.states[:draft])
+      @learning_object = create(:learning_object, publisher: @user, state: LearningObject.states[:submitted])
     end
 
     example 'Publishing a learning object' do
diff --git a/spec/shared/contexts.rb b/spec/shared/contexts.rb
index 18feed17f325a5e6febb3398ce73f5d72866713d..90ba69ca40ca86993b00c2e59a274f92e42f34e3 100644
--- a/spec/shared/contexts.rb
+++ b/spec/shared/contexts.rb
@@ -47,3 +47,81 @@ RSpec.shared_context "authenticate_user_admin", shared_context: :metadata do
   end
 
 end
+
+RSpec.shared_context "authenticate_user_submitter", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'submitter')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end
+
+RSpec.shared_context "authenticate_user_curator", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'curator')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end
+
+RSpec.shared_context "authenticate_user_moderator", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'moderator')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end
+
+RSpec.shared_context "authenticate_user_editor", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'editor')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end
+
+RSpec.shared_context "authenticate_user_supervisor", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'supervisor')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end
+
+RSpec.shared_context "authenticate_user_partner", shared_context: :metadata do
+  let(:auth_client) { @auth_headers['client'] }
+  let(:uid) { @auth_headers['uid'] }
+  let(:access_token) { @auth_headers['access-token'] }
+  let(:role) { Role.all }
+
+  before do
+    @user = create(:user, roles: [role.find_by(name: 'partner')])
+    @auth_headers = @user.create_new_auth_token
+  end
+
+end