Skip to content

Commit

Permalink
Support new watchlist format in persons endpoint and add new endpoints
Browse files Browse the repository at this point in the history
Persons get info and put info has been updated to support new watchlist
format. New endpoints to get and update watchlist are also added

Signed-off-by: Rubhan Azeem <rubhanazeem@gmail.com>
  • Loading branch information
rubhanazeem committed Apr 28, 2022
1 parent 778823d commit ebcd12f
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 30 deletions.
77 changes: 68 additions & 9 deletions src/api/app/controllers/person_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class PersonController < ApplicationController
skip_before_action :extract_user, only: [:command, :register]
skip_before_action :require_login, only: [:command, :register]

before_action :set_user, only: [:post_userinfo, :change_my_password]
before_action :set_user, only: [:post_userinfo, :change_my_password, :get_watchlist, :put_watchlist]
before_action :check_user_belongs_feature_flag, only: [:get_watchlist, :put_watchlist]

def show
@list = if params[:prefix]
Expand Down Expand Up @@ -134,6 +135,34 @@ def put_userinfo
render_ok
end

def get_watchlist
if @user
authorize @user, :check_watchlist?

render xml: @user.render_axml(render_watchlist_only: true)
else
@errorcode = 404
@summary = 'Requested non-existing user'
render_error(status: @errorcode)
end
end

def put_watchlist
if @user
authorize @user, :check_watchlist?
else
@errorcode = 404
@summary = 'Requested non-existing user'
render_error(status: @errorcode) && return
end

xml = Xmlhash.parse(request.raw_post)
ActiveRecord::Base.transaction do
update_new_watchlist(@user, xml)
end
render_ok
end

class NoPermissionToGroupList < APIError
setup 401, 'No user logged in, permission to grouplist denied'
end
Expand Down Expand Up @@ -193,16 +222,21 @@ def internal_register
end

def update_watchlist(user, xml)
new_watchlist = []
xml.get('watchlist').elements('project') do |e|
new_watchlist << e['name']
end
# Keeping the backwards compatibility
if Flipper.enabled?(:new_watchlist, User.session)
update_new_watchlist(user, xml)
else
new_watchlist = []
xml.get('watchlist').elements('project') do |e|
new_watchlist << e['name']
end

new_watchlist.map! do |name|
WatchedProject.find_or_create_by(project: Project.find_by_name!(name), user: user)
new_watchlist.map! do |name|
WatchedProject.find_or_create_by(project: Project.find_by_name!(name), user: user)
end
user.watched_projects.replace(new_watchlist)
Rails.cache.delete(['watched_project_names', user])
end
user.watched_projects.replace(new_watchlist)
Rails.cache.delete(['watched_project_names', user])
end
private :update_watchlist

Expand Down Expand Up @@ -262,7 +296,32 @@ def change_password(login, password)

private

def update_new_watchlist(user, xml)
if xml.get('watchlist').empty?
projects = [xml.get('project')].flatten
packages = [xml.get('package')].flatten
requests = [xml.get('request')].flatten
else
projects = xml.get('watchlist').elements('project')
packages = xml.get('watchlist').elements('package')
requests = xml.get('watchlist').elements('request')
end

watchables = []
watchables << projects.map { |proj| Project.find_by(name: proj['name']) }
watchables << packages.map { |pkg| Package.find_by_project_and_name(pkg['project'], pkg['name']) }
watchables << requests.map { |req| BsRequest.find_by(number: req['number']) }
user.watched_items.clear
watchables.flatten.compact.each do |item|
user.watched_items.create!(watchable: item)
end
end

def set_user
@user = User.find_by(login: params[:login])
end

def check_user_belongs_feature_flag
raise NotFoundError unless Flipper.enabled?(:new_watchlist, User.session)
end
end
4 changes: 2 additions & 2 deletions src/api/app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,9 @@ def to_axml(_opts = {})
render_axml
end

def render_axml(watchlist = false)
def render_axml(watchlist = false, render_watchlist_only: false)
# CanRenderModel
render_xml(watchlist: watchlist)
render_xml(watchlist: watchlist, render_watchlist_only: render_watchlist_only)
end

def home_project_name
Expand Down
4 changes: 4 additions & 0 deletions src/api/app/policies/user_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ def update?
def show?
user.can_modify_user?(record)
end

def check_watchlist?
record.login == User.session!.login || User.admin_session?
end
end
17 changes: 17 additions & 0 deletions src/api/app/queries/watchlist_finder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class WatchlistFinder
def initialize(relation = WatchedItem.all)
@relation = relation
end

def watchlist_projects(user)
@relation.includes(:watchable).where(user: user, watchable_type: 'Project').collect(&:watchable)
end

def watchlist_packages(user)
@relation.includes(:watchable).where(user: user, watchable_type: 'Package').collect(&:watchable)
end

def watchlist_requests(user)
@relation.includes(:watchable).where(user: user, watchable_type: 'BsRequest').collect(&:watchable)
end
end
44 changes: 25 additions & 19 deletions src/api/app/views/models/_user.xml.builder
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
xml.person do
xml.login(my_model.login)
xml.email(my_model.email)
realname = my_model.realname
unless realname.nil?
realname.toutf8
xml.realname(realname)
end
xml.owner(userid: my_model.owner.login) if my_model.owner
xml.state(my_model.state)
if render_watchlist_only
render partial: 'person/watchlist', locals: { builder: xml, my_model: my_model }
else
xml.person do
xml.login(my_model.login)
xml.email(my_model.email)
realname = my_model.realname
unless realname.nil?
realname.toutf8
xml.realname(realname)
end
xml.owner(userid: my_model.owner.login) if my_model.owner
xml.state(my_model.state)

my_model.roles.global.each do |role|
xml.globalrole(role.title)
end
my_model.roles.global.each do |role|
xml.globalrole(role.title)
end

xml.ignore_auth_services(my_model.ignore_auth_services) if my_model.is_admin?
xml.ignore_auth_services(my_model.ignore_auth_services) if my_model.is_admin?

# Show the watchlist only to the user for privacy reasons
if watchlist
xml.watchlist do
my_model.watched_projects.each do |wp|
xml.project(name: wp.project.name)
# Show the watchlist only to the user for privacy reasons
if Flipper.enabled?(:new_watchlist, User.session) && watchlist
render partial: 'person/watchlist', locals: { builder: xml, my_model: my_model }
elsif watchlist
xml.watchlist do
my_model.watched_projects.each do |wp|
xml.project(name: wp.project.name)
end
end
end
end
Expand Down
11 changes: 11 additions & 0 deletions src/api/app/views/person/_watchlist.xml.builder
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
builder.watchlist do
WatchlistFinder.new.watchlist_projects(my_model).each do |project|
builder.project(name: project.name)
end
WatchlistFinder.new.watchlist_packages(my_model).each do |package|
builder.package(name: package.name, project: package.project.name)
end
WatchlistFinder.new.watchlist_requests(my_model).each do |request|
builder.request(number: request.number)
end
end
2 changes: 2 additions & 0 deletions src/api/config/routes/api_routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
get 'person/:login' => 'person#get_userinfo', constraints: cons
put 'person/:login' => 'person#put_userinfo', constraints: cons
post 'person/:login' => 'person#post_userinfo', constraints: cons
get 'person/:login/watchlist' => 'person#get_watchlist', constraints: cons
put 'person/:login/watchlist' => 'person#put_watchlist', constraints: cons

### /group
controller :group do
Expand Down

0 comments on commit ebcd12f

Please sign in to comment.