note description: "Provide an interface to project data." author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class PROJECT_INTERFACE inherit BASE_INTERFACE A_CONFIG_CONSTANTS A_CONSTANTS create make feature -- Commands project_create (a_msg: A_MESSAGE) -- Create a new project according to a_msg. require a_msg_ok: a_msg /= Void local l_pc_msg: O_PROJECT_CREATE_MESSAGE l_project: PROJECT l_projectname: STRING l_time: DATE_TIME l_reply: A_MESSAGE do l_pc_msg ?= a_msg check project_create_message: l_pc_msg /= Void end -- Validation of type & rcs_type & visibility if not (project_access.is_valid_project_type_id (l_pc_msg.project_type)) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_project_type) elseif not (project_access.is_valid_rcs_type_id (l_pc_msg.rcs_type)) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_rcs_type) elseif not (project_access.is_valid_visibility_type_id (l_pc_msg.project_visibility)) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_visibility_type) else l_projectname := l_pc_msg.name.out l_projectname.to_lower project_access.retrieve_project_by_name (l_projectname) if project_access.is_found then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_project_name_already_used) else create l_project.make l_project.set_name (l_projectname) l_project.set_logo ("no") l_project.set_project_type (l_pc_msg.project_type) l_project.set_rcs_type (l_pc_msg.rcs_type) l_project.set_project_visibility (l_pc_msg.project_visibility) create l_time.make_now_utc l_project.set_creation_time (l_time.definite_duration (create {DATE_TIME}.make (1970, 1, 1, 0, 0, 0)).seconds_count.as_integer_32) user_access.retrieve_user_by_session (l_pc_msg.session.value) if user_access.is_found then l_project.set_creator_id (user_access.last_user.user_id) end -- insert project project_access.insert_project (l_project) -- description is set here project_access.insert_project_information (project_access.last_insert_id, l_pc_msg.description.value) create {O_PROJECT_CREATE_REPLY_MESSAGE}l_reply.make (project_access.last_insert_id) end end node.send_message_reply (l_reply, a_msg) end project_remove (a_msg: A_MESSAGE) -- Removes a project require a_msg_ok: a_msg /= Void local l_get_msg: O_PROJECT_REMOVE_MESSAGE l_reply: O_PROJECT_REPLY_MESSAGE l_project_id: INTEGER l_project: PROJECT do l_get_msg ?= a_msg check valid_message: l_get_msg /= Void end -- Retrieve the project for the core node needs to know the project name l_project_id := l_get_msg.project_id project_access.retrieve_project_by_id (l_project_id) l_project := project_access.last_project project_access.delete_project (l_project_id) project_access.delete_project_request (l_project.name) create l_reply.make ( l_project_id, l_project.name, l_project.logo, l_project.project_type, l_project.rcs_type) node.send_message_reply (l_reply, a_msg) end project_retrieve_id (a_msg: A_MESSAGE) -- Retrieve project id of project specified in a_msg or return an error. require a_msg_ok: a_msg /= Void local l_get_msg: O_PROJECT_RETRIEVE_ID_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_reply: O_PROJECT_RETRIEVE_ID_REPLY_MESSAGE l_projectname: STRING do l_get_msg ?= a_msg check project_retrieve_id_message: l_get_msg /= Void end l_projectname := l_get_msg.project_name.value l_projectname.to_lower project_access.retrieve_project_by_name (l_projectname) if not project_access.is_found then create l_status.make (False, err_project_not_found) node.send_message_reply (l_status, a_msg) else create l_reply.make (project_access.last_project.project_id) node.send_message_reply (l_reply, a_msg) end end project (a_msg: A_MESSAGE) -- Get project information. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_ID_MESSAGE l_reply: O_PROJECT_REPLY_MESSAGE l_project: PROJECT l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check workitem_message: l_msg /= Void end project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then -- retrieve project l_project := project_access.last_project create l_reply.make ( l_project.project_id, l_project.name, l_project.logo, l_project.project_type, l_project.rcs_type) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end end project_change_group (a_msg: A_MESSAGE) -- Change access_group of a user for a project. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_CHANGE_GROUP_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_grp: INTEGER l_user: STRING l_user_ret: USER l_project: INTEGER l_members : LIST [USER] l_was_already_member : BOOLEAN do l_msg ?= a_msg check valid_msg: l_msg /= Void end l_project := l_msg.project l_user := l_msg.user.value l_grp := l_msg.group -- is the access group valid? if l_grp = 0 or policy_cache.project_access_groups.has (l_grp) then -- is session valid? user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then -- is user valid? user_access.retrieve_user_by_name (l_user, False) if user_access.is_found then l_user_ret := user_access.last_user -- is project valid? project_access.retrieve_project_by_id (l_project) if project_access.is_found then -- update the workitem subscriptions if l_grp = 0 then -- remove all workitem subscriptions if user hasn't already bookmarked project if not user_access.has_bookmarked_project (l_project, l_user_ret.user_id) then user_access.delete_project_workitem_subscriptions (l_user_ret.user_id, l_project) end else -- don't modify subscriptions if user has a bookmark on this project -- or if the user was previously a member/owner -- else subscribe to all workitems if l_grp = 4 then project_access.retrieve_members (l_project, 3) elseif l_grp = 3 then project_access.retrieve_members (l_project, 4) end l_members := project_access.last_member_list l_was_already_member := False if l_members /= Void then from l_members.start until l_members.after or l_was_already_member loop l_was_already_member := l_members.item.user_id = l_user_ret.user_id l_members.forth end end if not user_access.has_bookmarked_project (l_project, l_user_ret.user_id) and not l_was_already_member then user_access.insert_all_project_workitem_subscriptions (l_user_ret.user_id, l_project) end end -- update the user role user_access.update_user_project_association (l_project, l_user_ret.user_id, l_grp) -- retrieve the user and team associations and add them to the cache in case the user was logged in policy_cache.retrieve_associations (l_user_ret.user_id) create l_status.make (True, Void) else create l_status.make (False, err_invalid_project) end else create l_status.make (False, err_invalid_user) end else create l_status.make (False, err_invalid_session) end else create l_status.make (False, err_invalid_group) end -- send status node.send_message_reply (l_status, a_msg) end project_list_of_user (a_msg: A_MESSAGE) -- List all projects of which a user is developer or owner require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_LIST_OF_USER_MESSAGE l_reply: O_PROJECT_LIST_OF_USER_REPLY_MESSAGE l_user_projects: DS_HASH_TABLE [O_PROJECT_PROJECT_NAME_AND_GID_MESSAGE, A_STRING_VALUE] l_query_result: ARRAYED_LIST[TUPLE[project_id: INTEGER; project_name: STRING; group: INTEGER]] l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check project_list_of_user_message: l_msg /= Void end user_access.retrieve_user_by_name (l_msg.user.value, False) if user_access.is_found then -- retrieve projects and map them into a HASH_TABLE l_query_result := project_access.retrieve_projects_of_user(l_msg.user.value) from create l_user_projects.make (l_query_result.count) l_query_result.start until l_query_result.after loop l_user_projects.force ( create {O_PROJECT_PROJECT_NAME_AND_GID_MESSAGE}.make ( l_query_result.item.project_name, l_query_result.item.group), l_query_result.item.project_id.out) l_query_result.forth end create l_reply.make (create {A_MAP_VALUE[O_PROJECT_PROJECT_NAME_AND_GID_MESSAGE]}.make (l_user_projects)) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_user) node.send_message_reply (l_status, a_msg) end end project_members (a_msg: A_MESSAGE) -- List project members. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_MEMBERS_MESSAGE l_reply: O_USER_LIST_MESSAGE l_lst: LIST [USER] l_members: DS_HASH_TABLE [A_STRING_VALUE, A_STRING_VALUE] l_usr: USER do l_msg ?= a_msg check project_members_message: l_msg /= Void end -- retrieve users and map them into a HASH_TABLE project_access.retrieve_members (l_msg.project, l_msg.group) from l_lst := project_access.last_member_list create l_members.make (l_lst.count) l_lst.start until l_lst.after loop l_usr := l_lst.item l_members.force (create {A_STRING_VALUE}.make (l_usr.name), create {A_STRING_VALUE}.make (l_usr.user_id.out)) l_lst.forth end create l_reply.make (create {A_MAP_VALUE[A_STRING_VALUE]}.make (l_members)) node.send_message_reply (l_reply, a_msg) end project_bookmarkers (a_msg: A_MESSAGE) -- List project bookmarkers. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_LIST_BOOKMARKERS_MESSAGE l_reply: O_USER_LIST_MESSAGE l_user_list: LIST [USER] l_bookmarker_map: DS_HASH_TABLE [A_STRING_VALUE, A_STRING_VALUE] l_user: USER do l_msg ?= a_msg check valid_message: l_msg /= Void end -- retrieve users and map them into a HASH_TABLE project_access.retrieve_bookmarkers (l_msg.project_id) from l_user_list := project_access.last_bookmarker_list create l_bookmarker_map.make (l_user_list.count) l_user_list.start until l_user_list.after loop l_user := l_user_list.item_for_iteration l_bookmarker_map.force (create {A_STRING_VALUE}.make (l_user.name), create {A_STRING_VALUE}.make (l_user.user_id.out)) l_user_list.forth end create l_reply.make (create {A_MAP_VALUE [A_STRING_VALUE]}.make (l_bookmarker_map)) node.send_message_reply (l_reply, a_msg) end project_list_communities (a_msg: A_MESSAGE) -- List communities of a project. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_LIST_COMMUNITIES_MESSAGE l_reply: O_COMMUNITY_LIST_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_list: LIST [COMMUNITY] l_communities: DS_ARRAYED_LIST [A_STRING_VALUE] l_community: COMMUNITY do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then -- retrieve communities and map them into a LIST community_access.retrieve_communities_of_project (l_msg.project_id) from l_list := community_access.last_community_list create l_communities.make (l_list.count) l_list.start until l_list.after loop l_community := l_list.item l_communities.force_last (create {A_STRING_VALUE}.make (l_community.name)) l_list.forth end create l_reply.make (create {A_SEQUENCE_VALUE [A_STRING_VALUE]}.make (l_communities)) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_invalid_session) node.send_message_reply (l_status, a_msg) end end project_change_description (a_msg: A_MESSAGE) -- Change description of a project require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_CHANGE_DESCRIPTION_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_msg: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then project_access.update_project_description (l_msg.project_id, l_msg.description.value) create l_status.make (True, Void) else create l_status.make (False, err_invalid_project) end else create l_status.make (False, err_invalid_session) end -- send status node.send_message_reply (l_status, a_msg) end project_change_logo (a_msg: A_MESSAGE) -- Change logo of a project require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_CHANGE_LOGO_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_msg: l_msg /= Void end project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then project_access.update_project_logo (l_msg.project_id, l_msg.logo.value) create l_status.make (True, Void) else create l_status.make (False, err_invalid_project) end -- send status node.send_message_reply (l_status, a_msg) end project_internal (a_msg: A_MESSAGE) -- Get project information. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_INTERNAL_MESSAGE l_reply: O_PROJECT_REPLY_MESSAGE l_project: PROJECT l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check workitem_message: l_msg /= Void end project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then -- retrieve project l_project := project_access.last_project create l_reply.make ( l_project.project_id, l_project.name, l_project.logo, l_project.project_type, l_project.rcs_type) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end end project_request_add (a_msg: A_MESSAGE) -- Create a new project request according to a_msg. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_REQUEST_ADD_MESSAGE l_project_request: PROJECT_REQUEST l_status: A_GENERAL_STATUS_MESSAGE l_projectname: STRING l_user_id: INTEGER do l_msg ?= a_msg check project_request_add_message: l_msg /= Void end -- Validation of type & rcs_type & visibility if not (project_access.is_valid_project_type_id (l_msg.project_type)) then create l_status.make (False, err_invalid_project_type) elseif not (project_access.is_valid_rcs_type_id (l_msg.rcs_type)) then create l_status.make (False, err_invalid_rcs_type) elseif not (project_access.is_valid_visibility_type_id (l_msg.project_visibility)) then create l_status.make (False, err_invalid_visibility_type) else user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then l_user_id := user_access.last_user.user_id --check if name is used in active project l_projectname := l_msg.name.out l_projectname.to_lower project_access.retrieve_project_by_name (l_projectname) if project_access.is_found then create l_status.make (False, err_project_name_already_used) else --check if name is used in project request project_access.retrieve_project_request_by_name (l_projectname) if project_access.is_found then create l_status.make (False, err_project_name_already_used) else create l_project_request.make l_project_request.set_user_id (user_access.last_user.user_id) l_project_request.set_name (l_projectname) l_project_request.set_description (l_msg.description.value) l_project_request.set_project_type (l_msg.project_type) l_project_request.set_rcs_type (l_msg.rcs_type) l_project_request.set_project_visibility (l_msg.project_visibility) l_project_request.set_message (l_msg.message.value) project_access.insert_project_request (l_project_request) create l_status.make (True, Void) end end else create l_status.make (False, err_invalid_user) end end node.send_message_reply (l_status, a_msg) end project_request_retrieve (a_msg: A_MESSAGE) -- Get project request. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_REQUEST_RETRIEVE_MESSAGE l_reply: O_PROJECT_REQUEST_RETRIEVE_REPLY_MESSAGE l_project_request: PROJECT_REQUEST l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end project_access.retrieve_project_request_by_name (l_msg.request_project_name.value) if project_access.is_found then -- retrieve project request l_project_request := project_access.last_project_request user_access.retrieve_user_by_id (l_project_request.user_id) if user_access.is_found then create l_reply.make ( l_project_request.request_id, user_access.last_user.name, user_access.last_user.email, l_project_request.name, l_project_request.description, l_project_request.project_type, l_project_request.rcs_type, l_project_request.project_visibility, l_project_request.message) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_user) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_invalid_project_request) node.send_message_reply (l_status, a_msg) end end project_retrieve_statistics (a_msg: A_MESSAGE) -- retrieve project statistics (used for both the internal and external api call - code sharing) require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_RETRIEVE_STATISTICS_MESSAGE l_msg_internal: O_PROJECT_RETRIEVE_STATISTICS_INTERNAL_MESSAGE l_reply: O_PROJECT_RETRIEVE_STATISTICS_REPLY_MESSAGE l_statistics: DS_HASH_TABLE[STRING, STRING] do l_msg ?= a_msg if l_msg = Void then l_msg_internal ?= a_msg check valid_message: l_msg_internal /= Void end end -- retrieve statistics l_statistics := project_access.retrieve_statistics create l_reply.make ( l_statistics.item ("project_count").to_integer, l_statistics.item ("open_source_count").to_integer, l_statistics.item ("project_count_hidden").to_integer, l_statistics.item ("open_source_count_hidden").to_integer, l_statistics.item ("user_count").to_integer, l_statistics.item ("recent_projects")) node.send_message_reply (l_reply, a_msg) end project_change_settings (a_msg: A_MESSAGE) -- Change project settings require a_msg_ok: a_msg /= Void local l_pc_msg: O_PROJECT_CHANGE_SETTINGS_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER cursor: DS_ARRAYED_LIST_CURSOR [O_PROJECT_SETTING_MESSAGE] do l_pc_msg ?= a_msg check valid_message: l_pc_msg /= Void end user_access.retrieve_user_by_session (l_pc_msg.session.value) if user_access.is_found then project_access.retrieve_project_by_id (l_pc_msg.project_id) if project_access.is_found then l_user_ret := user_access.last_user from -- Use own cursor, to avoid iterator - side effects in `project_access.update_project_settings' cursor := l_pc_msg.settings.sequence.new_cursor cursor.start until cursor.after loop project_access.update_project_settings ( l_pc_msg.project_id, cursor.item.setting_type.value, cursor.item.setting_value.value) -- Increment cursor.forth end create l_status.make (True, Void) else create l_status.make (False, err_invalid_project) end else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end project_retrieve_settings (a_msg: A_MESSAGE) -- Retrieve settings for project require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_RETRIEVE_SETTINGS_MESSAGE l_reply: O_PROJECT_RETRIEVE_SETTINGS_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then project_access.retrieve_project_settings_by_id (l_msg.project_id) if project_access.is_found then -- we have a user and a project, generate reply create l_reply.make ( project_access.last_project.project_id, project_access.last_project.name, project_access.last_project.logo, project_access.last_project.project_type, project_access.last_project.rcs_type, project_access.last_project.project_visibility, project_access.last_project.svn_path_doc, project_access.last_project.project_pretty_name, project_access.last_project.creation_time) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_invalid_session) node.send_message_reply (l_status, a_msg) end end project_change_information (a_msg: A_MESSAGE) -- Change project information require a_msg_ok: a_msg /= Void local l_pc_msg: O_PROJECT_CHANGE_INFORMATION_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER cursor: DS_ARRAYED_LIST_CURSOR [O_PROJECT_INFORMATION_MESSAGE] do l_pc_msg ?= a_msg check valid_message: l_pc_msg /= Void end user_access.retrieve_user_by_session (l_pc_msg.session.value) if user_access.is_found then project_access.retrieve_project_by_id (l_pc_msg.project_id) if project_access.is_found then l_user_ret := user_access.last_user from -- Use own cursor, to avoid iterator - side effects in `project_access.update_project_information' cursor := l_pc_msg.informations.sequence.new_cursor cursor.start until cursor.after loop project_access.update_project_information ( l_pc_msg.project_id, cursor.item.information_type.value, cursor.item.information_value.value) -- Increment cursor.forth end create l_status.make (True, Void) else create l_status.make (False, err_invalid_project) end else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end project_retrieve_information (a_msg: A_MESSAGE) -- Retrieve information for project require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_RETRIEVE_INFORMATION_MESSAGE l_reply: O_PROJECT_RETRIEVE_INFORMATION_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then project_access.retrieve_project_information_by_id (l_msg.project_id) if project_access.is_found then -- we have a user and a project, generate reply create l_reply.make ( project_access.last_project_information.project_id, project_access.last_project_information.short_description, project_access.last_project_information.description, project_access.last_project_information.programming_language, project_access.last_project_information.operating_system, project_access.last_project_information.license, project_access.last_project_information.category) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_invalid_session) node.send_message_reply (l_status, a_msg) end end project_change_type (a_msg: A_MESSAGE) -- Change the project's type require a_msg_ok: a_msg /= Void local l_pc_msg: O_PROJECT_CHANGE_TYPE_MESSAGE l_reply: A_MESSAGE l_old_project_type: INTEGER l_old_rcs_type: INTEGER l_old_visibility_type: INTEGER do l_pc_msg ?= a_msg check valid_message: l_pc_msg /= Void end -- Validation of type & rcs_type & visibility if not (project_access.is_valid_project_type_id (l_pc_msg.project_type)) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_project_type) elseif not (project_access.is_valid_rcs_type_id (l_pc_msg.rcs_type)) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_rcs_type) elseif not (project_access.is_valid_visibility_type_id (l_pc_msg.visibility)) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_visibility_type) else user_access.retrieve_user_by_session (l_pc_msg.session.value) if user_access.is_found then project_access.retrieve_project_by_id (l_pc_msg.project_id) if project_access.is_found then l_old_project_type := project_access.last_project.project_type l_old_rcs_type := project_access.last_project.rcs_type l_old_visibility_type := project_access.last_project.project_visibility project_access.update_project_type (l_pc_msg.project_id, l_pc_msg.project_type, l_pc_msg.rcs_type, l_pc_msg.visibility) create {O_PROJECT_CHANGE_TYPE_STORAGE_REPLY_MESSAGE}l_reply.make (project_access.last_project.name, l_old_project_type, l_old_rcs_type, l_old_visibility_type) else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_project) end else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_user) end end node.send_message_reply (l_reply, a_msg) end project_list_repositories (a_msg: A_MESSAGE) -- List all source repositories of a project. require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_LIST_REPOSITORIES_MESSAGE l_reply: A_MESSAGE l_is_authenticated: BOOLEAN l_session: SESSION l_project_groups: LINKED_SET [INTEGER] l_project: PROJECT l_repo_list: DS_ARRAYED_LIST [A_STRING_VALUE] do l_msg ?= a_msg check valid_message: l_msg /= Void end project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then -- retrieve project l_project := project_access.last_project create l_repo_list.make (1) if l_project.rcs_type = 1 then -- It's a subversion project -- As there is only a single repository with a easy guessable name (= the -- project name), skipt the whole access-permission check. l_is_authenticated := True l_repo_list.force_last (l_project.name) else -- It's another repo type l_is_authenticated := False if l_project.project_type /= 2 then -- The project is not open source - check the user's permission -- check if the session is still valid and retrieve the user user_access.retrieve_session_by_id (l_msg.session) if not user_access.is_found and not (l_msg.session.value.is_empty or l_msg.session.value.is_equal(anonymous_user_session)) then -- session timeout/invalid create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_session_timeout) l_is_authenticated := False elseif not user_access.is_found then -- anonymous user create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_user) l_is_authenticated := False else l_session := user_access.last_session if policy_cache.is_origo_admin (l_session.user_id) then l_is_authenticated := True else l_project_groups := policy_cache.user_project_associations.item (l_session.user_id).item (l_msg.project_id) if l_project_groups /= Void then from l_project_groups.start until l_project_groups.after or l_is_authenticated loop l_is_authenticated := (l_project_groups.item_for_iteration = 3) or -- owner (l_project_groups.item_for_iteration = 4) -- member -- inc l_project_groups.forth end else -- not a project member/owner create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_access_denied) end end end else -- Open source projects don't need to check for the user's permissions l_is_authenticated := True end if l_is_authenticated then project_access.retrieve_repositories (l_project.project_id) l_repo_list.resize (project_access.last_repositories.count) from project_access.last_repositories.start until project_access.last_repositories.after loop l_repo_list.force_last (project_access.last_repositories.item_for_iteration) -- inc project_access.last_repositories.forth end else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_access_denied) end end -- Here, the user is either not authenticated, or the data about the repos was gathered. if l_is_authenticated then -- send the reply with the repos gathered above create {O_PROJECT_LIST_REPOSITORIES_REPLY_MESSAGE}l_reply.make ( create {A_SEQUENCE_VALUE [A_STRING_VALUE]}.make_from_linear (l_repo_list), default_repository_limit ) else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_access_denied) end else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_project) end node.send_message_reply (l_reply, a_msg) end project_add_repository (a_msg: A_MESSAGE) require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_ADD_REPOSITORY_MESSAGE l_reply: A_MESSAGE l_project: PROJECT do l_msg ?= a_msg check valid_message: l_msg /= Void end project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then -- retrieve project l_project := project_access.last_project if l_project.rcs_type /= 2 then -- ATM, we only can add Git repositories create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_rcs_type) else -- Retrieve the existing repos project_access.retrieve_repositories (l_project.project_id) project_access.last_repositories.set_equality_tester (create {KL_STRING_EQUALITY_TESTER}) if project_access.last_repositories.has (l_msg.repository_name) then create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_repository_name) else -- All ok - add it project_access.insert_repository (l_msg.project_id, l_msg.repository_name) create {O_PROJECT_ADD_REPOSITORY_REPLY_MESSAGE}l_reply.make (l_project.name, l_project.project_type = 2) end end else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_project) end node.send_message_reply (l_reply, a_msg) end project_remove_repository (a_msg: A_MESSAGE) require a_msg_ok: a_msg /= Void local l_msg: O_PROJECT_REMOVE_REPOSITORY_MESSAGE l_reply: A_MESSAGE l_project: PROJECT l_repository_id: INTEGER do l_msg ?= a_msg check valid_message: l_msg /= Void end project_access.retrieve_project_by_id (l_msg.project_id) if project_access.is_found then -- retrieve project l_project := project_access.last_project if l_project.rcs_type /= 2 then -- ATM, we only can remove Git repositories create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_rcs_type) else -- remove it l_repository_id := project_access.retrieve_repository_id (l_msg.repository_name, l_msg.project_id) if l_repository_id > 0 then project_access.delete_repository (l_repository_id) create {O_PROJECT_REMOVE_REPOSITORY_REPLY_MESSAGE}l_reply.make(l_project.name) else -- we didn't find the repository create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_repository) end end else create {A_GENERAL_STATUS_MESSAGE}l_reply.make (False, err_invalid_project) end node.send_message_reply (l_reply, a_msg) end feature {NONE} -- Implementation default_repository_limit: INTEGER = 5 -- The default limit on the number of repositories allowed for per project. end