note description: "Provide an interface to user data." author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class USER_INTERFACE inherit BASE_INTERFACE redefine make end A_CONFIG_CONSTANTS O_USER_CONSTANTS A_CONSTANTS export {NONE} all end create make feature {NONE} -- Initialization make (a_node: like node; a_db_handler: like db_handler; a_policy_cache: like policy_cache) -- Initialize. do Precursor(a_node, a_db_handler, a_policy_cache) -- purge all sessions as they are not valid anymore user_access.purge_sessions end feature -- Commands user_create (a_msg: A_MESSAGE) -- Create a new user according to a_msg. require a_msg_ok: a_msg /= Void local l_uc_msg: O_USER_CREATE_MESSAGE l_user: USER l_assoc: USER_ASSOCIATION l_status: A_GENERAL_STATUS_MESSAGE do l_uc_msg ?= a_msg check user_create_message: l_uc_msg /= Void end create l_user.make l_user.set_name (l_uc_msg.name.value) l_user.set_pass (l_uc_msg.password.value) l_user.set_email (l_uc_msg.email.value) -- check if the user already exists (this includes the disabled users as well) user_access.retrieve_user_by_name (l_user.name, True) if user_access.is_found then create l_status.make (False, err_user_name_already_used) else user_access.insert_user (l_user) -- we need the user to get the id, to add an according user_association user_access.retrieve_user_by_name (l_user.name, False) check found: user_access.is_found end create l_assoc.make l_assoc.set_group_id (2) l_assoc.set_user_id (user_access.last_user.user_id) user_access.insert_user_association (l_assoc) -- insert user_id and registration_date in user_information table user_access.insert_user_information (user_access.last_user.user_id) create l_status.make (True, Void) end node.send_message_reply (l_status, a_msg) end user_login (a_msg: A_MESSAGE) -- Try to login a user according to a_msg. require a_msg_ok: a_msg /= Void local l_ul_msg: O_USER_LOGIN_MESSAGE l_ses_msg: O_USER_SESSION_MESSAGE l_user: USER l_session: SESSION l_status: A_GENERAL_STATUS_MESSAGE do l_ul_msg ?= a_msg check user_login_message: l_ul_msg /= Void end user_access.retrieve_user_by_name (l_ul_msg.name.value, False) -- did we find the user? if not user_access.is_found then create l_status.make (False, err_user_password_invalid) node.send_message_reply (l_status, a_msg) else l_user := user_access.last_user -- password correct? if not l_user.pass.is_equal (l_ul_msg.password.value) then create l_status.make (False, err_user_password_invalid) node.send_message_reply (l_status, a_msg) else -- also retrieve the user and team associations and add them to the cache policy_cache.retrieve_associations (l_user.user_id) create l_session.make l_session.set_user_id (l_user.user_id) user_access.insert_session (l_session) user_access.update_user_last_login (l_user.user_id) create l_ses_msg.make (l_session.session_id) node.send_message_reply (l_ses_msg, a_msg) end end end user_login_authenticated (a_msg: A_MESSAGE) -- Try to login a user according to a_msg. require a_msg_ok: a_msg /= Void local l_ul_msg: O_USER_LOGIN_AUTHENTICATED_MESSAGE l_ses_msg: O_USER_SESSION_MESSAGE l_user: USER l_session: SESSION l_status: A_GENERAL_STATUS_MESSAGE do l_ul_msg ?= a_msg check user_login_message: l_ul_msg /= Void end user_access.retrieve_user_by_name (l_ul_msg.name.value, False) -- did we find the user? if not user_access.is_found then create l_status.make (False, err_user_password_invalid) node.send_message_reply (l_status, a_msg) else l_user := user_access.last_user -- also retrieve the user and team associations and add them to the cache policy_cache.retrieve_associations (l_user.user_id) create l_session.make l_session.set_user_id (l_user.user_id) user_access.insert_session (l_session) user_access.update_user_last_login (l_user.user_id) create l_ses_msg.make (l_session.session_id) node.send_message_reply (l_ses_msg, a_msg) end end user_login_key (a_msg: A_MESSAGE) -- Try to login a user with a key according to a_msg. require a_msg_ok: a_msg /= Void local l_ul_msg: O_USER_LOGIN_KEY_MESSAGE l_ses_msg: O_USER_SESSION_MESSAGE l_user: USER l_session: SESSION l_status: A_GENERAL_STATUS_MESSAGE do l_ul_msg ?= a_msg check user_login_key_message: l_ul_msg /= Void end user_access.retrieve_user_by_key (l_ul_msg.user_key.value) -- did we find the user? if not user_access.is_found then create l_status.make (False, err_invalid_user_key) node.send_message_reply (l_status, a_msg) else l_user := user_access.last_user -- did we find the application? if user_access.retrieve_application_by_key (l_ul_msg.app_key.value) = Void then create l_status.make (False, err_application_invalid) node.send_message_reply (l_status, a_msg) else -- also retrieve the user and team associations and add them to the cache policy_cache.retrieve_associations (l_user.user_id) create l_session.make l_session.set_user_id (l_user.user_id) user_access.insert_session (l_session) user_access.update_user_last_login (l_user.user_id) user_access.increase_application_login_count(l_ul_msg.app_key.value) create l_ses_msg.make (l_session.session_id) node.send_message_reply (l_ses_msg, a_msg) end end end user_authorized_for_project (a_msg: A_MESSAGE) -- Check authorization of a session against an instruction for a project. require a_msg_ok: a_msg /= Void local l_auth_msg: O_USER_AUTHORIZED_FOR_PROJECT_MESSAGE l_session: SESSION l_policy: LINKED_SET [INTEGER] l_group, l_project_group: LINKED_SET [INTEGER] l_allowed, l_reply_sent: BOOLEAN l_status: A_GENERAL_STATUS_MESSAGE l_user_id: INTEGER do l_auth_msg ?= a_msg check authorized_message: l_auth_msg /= Void end -- check if the session is still valid and retrieve the user user_access.retrieve_session_by_id (l_auth_msg.session.value) if not user_access.is_found and not (l_auth_msg.session.is_empty or l_auth_msg.session.value.is_equal(anonymous_user_session)) then -- session timeout/invalid create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) l_reply_sent := True elseif not user_access.is_found then -- anonymous user l_user_id := 0 create l_group.make l_group.put (8) else l_session := user_access.last_session user_access.update_session (l_session) l_user_id := l_session.user_id end if not l_reply_sent then l_allowed := False -- check if the user is authorized for the instruction l_policy := policy_cache.policies.item (l_auth_msg.instruction.value) -- only if we have a policy we can be allowed if l_policy /= Void then if user_access.is_found then l_group := policy_cache.user_associations.item (l_user_id) end -- are we in one group that is allowed from the policy? from l_group.start until l_allowed or l_group.after loop l_allowed := l_policy.has (l_group.item) l_group.forth end -- if we have a project and aren't yet allowed, check those if l_auth_msg.project.value > 0 and l_session /= Void then l_project_group := policy_cache.user_project_associations.item (l_session.user_id).item (l_auth_msg.project.value.to_integer) if l_project_group /= Void then from l_project_group.start until l_allowed or l_project_group.after loop l_allowed := l_policy.has (l_project_group.item) l_project_group.forth end end end end -- return allowed/denied if l_allowed then create l_status.make (True, Void) else create l_status.make (False, err_access_denied) end node.send_message_reply (l_status, a_msg) end end user_authorized_for_community (a_msg: A_MESSAGE) -- Check authorization of a session against an instruction for a community. require a_msg_ok: a_msg /= Void local l_auth_msg: O_USER_AUTHORIZED_FOR_COMMUNITY_MESSAGE l_session: SESSION l_policy: LINKED_SET [INTEGER] l_group, l_community_group: LINKED_SET [INTEGER] l_allowed, l_reply_sent: BOOLEAN l_status: A_GENERAL_STATUS_MESSAGE l_community_id, l_user_id: INTEGER do l_auth_msg ?= a_msg check authorized_message: l_auth_msg /= Void end -- check if the session is still valid and retrieve the user user_access.retrieve_session_by_id (l_auth_msg.session.value) if not user_access.is_found and not (l_auth_msg.session.is_empty or l_auth_msg.session.value.is_equal(anonymous_user_session)) then -- session timeout/invalid create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) l_reply_sent := True elseif not user_access.is_found then -- anonymous user l_user_id := 0 create l_group.make l_group.put (8) else l_session := user_access.last_session user_access.update_session (l_session) l_user_id := l_session.user_id end if not l_reply_sent then l_allowed := False -- check if the user is authorized for the instruction l_policy := policy_cache.policies.item (l_auth_msg.instruction.value) -- only if we have a policy we can be allowed if l_policy /= Void then if user_access.is_found then l_group := policy_cache.user_associations.item (l_user_id) end -- are we in one group that is allowed from the policy? check l_group_set: l_group /= Void end from l_group.start until l_allowed or l_group.after loop l_allowed := l_policy.has (l_group.item) l_group.forth end -- if we have a community and aren't yet allowed, check those if not l_auth_msg.community_name.is_empty and l_session /= Void then community_access.retrieve_community_by_name (l_auth_msg.community_name.value) if community_access.is_found then l_community_id := community_access.last_community.community_id l_community_group := policy_cache.user_community_associations.item (l_session.user_id).item (l_community_id) if l_community_group /= Void then from l_community_group.start until l_allowed or l_community_group.after loop l_allowed := l_policy.has (l_community_group.item) l_community_group.forth end end else create l_status.make (False, err_invalid_community) node.send_message_reply (l_status, a_msg) end end end -- return allowed/denied if l_allowed then create l_status.make (True, Void) else create l_status.make (False, err_access_denied) end node.send_message_reply (l_status, a_msg) end end user_change_email (a_msg: A_MESSAGE) -- Change email address of a user require a_msg_ok: a_msg /= Void local l_msg: O_USER_CHANGE_EMAIL_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_email: STRING l_session: SESSION l_user: USER do l_msg ?= a_msg check valid_msg: l_msg /= Void end l_email := l_msg.email_address.value -- session valid? user_access.retrieve_session_by_id (l_msg.session.value) if user_access.is_found then l_session := user_access.last_session user_access.retrieve_user_by_id (l_session.user_id) if user_access.is_found then l_user := user_access.last_user user_access.update_user_email (l_user.user_id, l_email) create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end else create l_status.make (False, err_session_timeout) end -- send status node.send_message_reply (l_status, a_msg) end user_change_account_enabled (a_msg: A_MESSAGE) -- if `enabled' is set to false, will call disable account. -- otherwise we just set the enabled flag to true. require a_msg_ok: a_msg /= Void local l_msg: O_USER_CHANGE_ACCOUNT_ENABLED_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user: USER do l_msg ?= a_msg check valid_msg: l_msg /= Void end user_access.retrieve_user_by_name (l_msg.name.value, True) if user_access.is_found then l_user := user_access.last_user if l_msg.enabled.value = True then -- enable account user_access.enable_account (l_user.user_id) else -- disable account disable_account (l_user.user_id) end create l_status.make (True, Void) node.send_message_reply (l_status, a_msg) else create l_status.make (False, err_invalid_user) node.send_message_reply (l_status, a_msg) end end user_change_password (a_msg: A_MESSAGE) -- Change password of a user require a_msg_ok: a_msg /= Void local l_msg: O_USER_CHANGE_PASSWORD_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_password: STRING l_user: USER do l_msg ?= a_msg check valid_msg: l_msg /= Void end l_password := l_msg.password.value -- session valid? user_access.retrieve_user_by_name (l_msg.name.value, False) if user_access.is_found then l_user := user_access.last_user user_access.update_user_password (l_user.user_id, l_password) create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end -- send status node.send_message_reply (l_status, a_msg) end user_reset_password (a_msg: A_MESSAGE) -- Reset password of a user require a_msg_ok: a_msg /= Void local l_msg: O_USER_RESET_PASSWORD_MESSAGE l_reply: O_USER_RESET_PASSWORD_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_password: STRING l_user: USER do l_msg ?= a_msg check valid_msg: l_msg /= Void end l_password := token_generator.generate_id.substring (1, 15) user_access.retrieve_user_by_name (l_msg.name.value, False) if user_access.is_found then l_user := user_access.last_user user_access.update_user_password (l_user.user_id, l_password) create l_reply.make (l_password, l_user.email) 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 user_my_name (a_msg: A_MESSAGE) -- Returns username of user require a_msg_ok: a_msg /= Void local l_msg: O_USER_MY_NAME_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check user_my_name_message: l_msg /= Void end -- check session user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then create l_reply.make (user_access.retrieve_my_name(l_msg.session.value)) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end user_my_password (a_msg: A_MESSAGE) -- Returns password of user require a_msg_ok: a_msg /= Void local l_msg: O_USER_MY_PASSWORD_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check user_my_name_message: l_msg /= Void end -- check session user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then create l_reply.make (user_access.retrieve_my_password(l_msg.session.value)) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end user_my_email (a_msg: A_MESSAGE) -- Returns email address of user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_MY_EMAIL_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end -- check session user_access.retrieve_user_by_session (l_msg.session.value) if user_access.is_found then create l_reply.make (user_access.retrieve_my_email (l_msg.session.value)) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end user_retrieve_password (a_msg: A_MESSAGE) -- Returns password of user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_RETRIEVE_PASSWORD_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end -- check session user_access.retrieve_user_by_name (l_msg.name.value, True) if user_access.is_found then create l_reply.make (user_access.last_user.pass) 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 user_retrieve_email (a_msg: A_MESSAGE) -- Returns email address of user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_RETRIEVE_EMAIL_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end -- check session user_access.retrieve_user_by_name (l_msg.name.value, True) if user_access.is_found then create l_reply.make (user_access.last_user.email) 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 user_retrieve_user_from_email (a_msg: A_MESSAGE) -- Returns user from email address of user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_RETRIEVE_USER_FROM_EMAIL_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check valid_message: l_msg /= Void end -- check session user_access.retrieve_user_by_email (l_msg.email.value, False) if user_access.is_found then create l_reply.make (user_access.last_user.name) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_email) node.send_message_reply (l_status, a_msg) end end user_profile_visible (a_msg: A_MESSAGE) -- Returns the profile visibility. require a_msg_ok: a_msg /= Void local l_msg: O_USER_PROFILE_VISIBLE_MESSAGE l_reply: A_GENERAL_STRING_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user: USER do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_name (l_msg.name.value, False) if user_access.is_found then -- user found l_user := user_access.last_user create l_reply.make (user_access.retrieve_profile_visible (l_user.user_id).out) node.send_message_reply (l_reply, a_msg) else -- user not found or disabled create l_status.make (False, err_invalid_user) node.send_message_reply (l_status, a_msg) end end user_change_profile_visible (a_msg: A_MESSAGE) -- Set profile visibility require a_msg_ok: a_msg /= Void local l_message: O_USER_CHANGE_PROFILE_VISIBLE_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER do l_message ?= a_msg check valid_message: l_message /= Void valid_value: l_message.value.value.to_integer >= 0 end -- check session user_access.retrieve_user_by_session (l_message.session.value) if user_access.is_found then l_user_ret := user_access.last_user user_access.update_profile_visible (l_user_ret.user_id, l_message.value.value.to_integer) create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end user_retrieve_information (a_msg: A_MESSAGE) -- Retrieve information about a user require a_msg_ok: a_msg /= Void local l_msg: O_USER_RETRIEVE_INFORMATION_MESSAGE l_reply: O_USER_RETRIEVE_INFORMATION_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_birthday_date: DATE_TIME l_birthday_formatted: STRING l_strings: DS_HASH_TABLE [STRING, STRING] l_string_map: DS_HASH_TABLE [A_STRING_VALUE, A_STRING_VALUE] l_integers: DS_HASH_TABLE [INTEGER, STRING] l_integer_map: DS_HASH_TABLE [A_INTEGER_VALUE, A_STRING_VALUE] l_doubles: DS_HASH_TABLE [DOUBLE, STRING] l_double_map: DS_HASH_TABLE [A_DOUBLE_VALUE, A_STRING_VALUE] do l_msg ?= a_msg check valid_message: l_msg /= Void end --check user to retrieve information for user_access.retrieve_user_by_name (l_msg.user_name.value, False) if user_access.is_found then -- get its user ID and gather information user_access.retrieve_user_information_by_id (user_access.last_user.user_id) if user_access.is_found then -- Prepare the date-string for `birthday': -- In older versions, the DATE was used, but transformed into a string in -- the API node (format: '12/11/1982 12:00:00.000 AM'), transported like -- that to the frontend, which cut of the time-part. -- -- Now, we just transmit the date-part, but for backward-compability reasons is the -- non-ISO format M/D/Y l_birthday_date := user_access.last_user_information.birthday l_birthday_formatted := l_birthday_date.month.out + "/" + l_birthday_date.day.out + "/" + l_birthday_date.year.out -- process strings l_strings := user_access.last_user_settings.strings -- fix birthday value, see above l_strings.put (l_birthday_formatted, "birthday") create l_string_map.make (l_strings.count) l_strings.do_all_with_key (agent convert_string_map (?, ?, l_string_map)) -- process integers l_integers := user_access.last_user_settings.integers create l_integer_map.make (l_integers.count) l_integers.do_all_with_key (agent convert_integer_map (?, ?, l_integer_map)) -- process integers l_doubles := user_access.last_user_settings.doubles create l_double_map.make (l_doubles.count) l_doubles.do_all_with_key (agent convert_double_map (?, ?, l_double_map)) create l_reply.make (l_integer_map, l_double_map, l_string_map) -- create l_reply.make ( -- l_msg.user_name.value, -- user_access.last_user_information.first_name, -- user_access.last_user_information.last_name, -- user_access.last_user_information.gender, -- user_access.last_user_information.icon, -- user_access.last_user_information.languages, -- user_access.last_user_information.registration_date, -- l_birthday_formatted, -- user_access.last_user_information.timezone, -- user_access.last_user_information.signature, -- user_access.last_user_information.message, -- user_access.last_user_information.homepage, -- user_access.last_user_information.blog, -- user_access.last_user_information.ohloh_profile, -- user_access.last_user_information.icq, -- user_access.last_user_information.aim, -- user_access.last_user_information.jabber, -- user_access.last_user_information.yahoo, -- user_access.last_user_information.msn, -- user_access.last_user_information.skype, -- user_access.last_user_information.sip, -- user_access.last_user_information.irc, -- user_access.last_user_information.workitems_per_page, -- user_access.last_user_information.issues_per_page, -- user_access.last_user_information.feed_show_unread -- ) 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_user) node.send_message_reply (l_status, a_msg) end end user_set_information (a_msg: A_MESSAGE) -- Set user information require a_msg_ok: a_msg /= Void local l_pc_msg: O_USER_SET_INFORMATION_MESSAGE l_informations: DS_ARRAYED_LIST [O_USER_INFORMATION_MESSAGE] l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER l_information_type: STRING l_information_value: STRING 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 l_user_ret := user_access.last_user l_informations := l_pc_msg.informations.sequence from l_informations.start until l_informations.after loop l_information_type := l_informations.item_for_iteration.information_type.value l_information_value := l_informations.item_for_iteration.information_value.value user_access.update_user_information (l_user_ret.user_id, l_information_type, l_information_value) l_informations.forth end create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end user_set_icon (a_msg: A_MESSAGE) -- Set user icon require a_msg_ok: a_msg /= Void local l_pc_message: O_USER_SET_ICON_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER do l_pc_message ?= a_msg check valid_message: l_pc_message /= Void valid_icon: l_pc_message.icon /= Void and then not l_pc_message.icon.is_empty end -- check session user_access.retrieve_user_by_session (l_pc_message.session.value) if user_access.is_found then l_user_ret := user_access.last_user user_access.update_user_icon (l_user_ret.user_id, l_pc_message.icon.value) create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end user_reset_icon (a_msg: A_MESSAGE) -- Reset user icon require a_msg_ok: a_msg /= Void local l_pc_message: O_USER_RESET_ICON_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER do l_pc_message ?= a_msg check valid_message: l_pc_message /= Void end -- check session user_access.retrieve_user_by_session (l_pc_message.session.value) if user_access.is_found then l_user_ret := user_access.last_user user_access.update_user_icon (l_user_ret.user_id, "") create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end user_reported_issues_count (a_msg: A_MESSAGE) -- Retrieves the total number of issues reported by the calling user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_REPORTED_ISSUES_COUNT_MESSAGE l_reply: O_USER_REPORTED_ISSUES_COUNT_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 -- retrieve issue count issue_access.retrieve_user_issue_count(user_access.last_user.user_id) create l_reply.make (issue_access.last_issue_count) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end user_list_reported_issues (a_msg: A_MESSAGE) -- List reported issues for a specific user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_LIST_REPORTED_ISSUES_MESSAGE l_reply: O_USER_LIST_REPORTED_ISSUES_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_issues: DS_ARRAYED_LIST [TUPLE [project_issue_id: INTEGER; title: STRING; deadline: INTEGER; work_amount: INTEGER; project_name: STRING; last_updated: INTEGER; tags: STRING; status: STRING; assigned: STRING]] l_issue_item: TUPLE [project_issue_id: INTEGER; title: STRING; deadline: INTEGER; work_amount: INTEGER; project_name: STRING; last_updated: INTEGER; tags: STRING; status: STRING; assigned: STRING] l_issue_list: DS_ARRAYED_LIST [O_USER_ISSUE_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 -- retrieve issues l_issues := issue_access.retrieve_user_issues ( user_access.last_user.user_id, l_msg.start, l_msg.limit, l_msg.sort_column, l_msg.sort_order) create l_issue_list.make (l_issues.count) from l_issues.start until l_issues.after loop l_issue_item := l_issues.item_for_iteration l_issue_list.force_last ( create {O_USER_ISSUE_MESSAGE}.make ( l_issue_item.project_issue_id, l_issue_item.title, l_issue_item.deadline, l_issue_item.work_amount, l_issue_item.project_name, l_issue_item.last_updated, l_issue_item.tags, l_issue_item.status, l_issue_item.assigned )) -- Increment l_issues.forth end create l_reply.make(create {A_SEQUENCE_VALUE [O_USER_ISSUE_MESSAGE]}.make (l_issue_list)) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end user_request_friendship (a_msg: A_MESSAGE) -- Add friendship request in USER_FRIENDSHIP_REQUEST and return information of requester. require a_msg_ok: a_msg /= Void local l_msg: O_USER_REQUEST_FRIENDSHIP_MESSAGE l_reply: O_USER_REQUEST_FRIENDSHIP_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_requester: USER l_requestee: USER l_requester_information: USER_INFORMATION l_requester_fullname: STRING found_friendship_request: BOOLEAN found_reversed_friendship_request: BOOLEAN found_friendship: BOOLEAN 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 l_requester := user_access.last_user user_access.retrieve_user_by_name (l_msg.requestee.value, False) if user_access.is_found then l_requestee := user_access.last_user -- only add request if request does not already exists -- and request where requester and requestee are reversed does not exist -- and requester /= requestee -- and friendship not already exists user_access.retrieve_friendship_request (l_requester.user_id, l_requestee.user_id) found_friendship_request := user_access.is_found user_access.retrieve_friendship_request (l_requestee.user_id, l_requester.user_id) found_reversed_friendship_request := user_access.is_found user_access.retrieve_friendship (l_requester.user_id, l_requestee.user_id) found_friendship := user_access.is_found if not found_friendship and not found_friendship_request and not found_reversed_friendship_request and l_requester.user_id /= l_requestee.user_id then user_access.insert_friendship_request (l_requester.user_id, l_requestee.user_id) -- generate and send reply l_requester_fullname := "" user_access.retrieve_user_information_by_id (l_requester.user_id) if user_access.is_found then l_requester_information := user_access.last_user_information if not l_requester_information.first_name.is_empty and not l_requester_information.last_name.is_empty then l_requester_fullname := l_requester_information.first_name + " " + l_requester_information.last_name elseif not l_requester_information.first_name.is_empty then l_requester_fullname := l_requester_information.first_name elseif not l_requester_information.last_name.is_empty then l_requester_fullname := l_requester_information.last_name end end create l_reply.make ( l_requestee.email, l_requester.name, l_requester_fullname) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_request) node.send_message_reply (l_status, a_msg) end 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_session_timeout) node.send_message_reply (l_status, a_msg) end end user_process_friendship_request (a_msg: A_MESSAGE) -- Process friendship request: if accepted, add friendship in USER_FRIENDSHIP -- Delete request from USER_FRIENDSHIP_REQUEST and return information of requestee. require a_msg_ok: a_msg /= Void local l_msg: O_USER_PROCESS_FRIENDSHIP_REQUEST_MESSAGE l_reply: O_USER_PROCESS_FRIENDSHIP_REQUEST_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_requester: USER l_requestee: USER l_requestee_information: USER_INFORMATION l_requestee_fullname: STRING 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 l_requestee := user_access.last_user user_access.retrieve_user_by_name (l_msg.requester.value, False) if user_access.is_found then l_requester := user_access.last_user -- only process if request exists user_access.retrieve_friendship_request (l_requester.user_id, l_requestee.user_id) if user_access.is_found then -- check accept status if l_msg.accept.value then user_access.insert_friendship (l_requester.user_id, l_requestee.user_id) end user_access.delete_friendship_request (l_requester.user_id, l_requestee.user_id) -- generate and send reply l_requestee_fullname := "" user_access.retrieve_user_information_by_id (l_requestee.user_id) if user_access.is_found then l_requestee_information := user_access.last_user_information if not l_requestee_information.first_name.is_empty and not l_requestee_information.last_name.is_empty then l_requestee_fullname := l_requestee_information.first_name + " " + l_requestee_information.last_name elseif not l_requestee_information.first_name.is_empty then l_requestee_fullname := l_requestee_information.first_name elseif not l_requestee_information.last_name.is_empty then l_requestee_fullname := l_requestee_information.last_name end end create l_reply.make ( l_requester.email, l_requestee.name, l_requestee_fullname) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_request) node.send_message_reply (l_status, a_msg) end 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_session_timeout) node.send_message_reply (l_status, a_msg) end end user_remove_friendship (a_msg: A_MESSAGE) -- Remove friendship between users. require a_msg_ok: a_msg /= Void local l_msg: O_USER_REMOVE_FRIENDSHIP_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_id: INTEGER l_friend_id: INTEGER 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 l_user_id := user_access.last_user.user_id user_access.retrieve_user_by_name (l_msg.friend.value, False) if user_access.is_found then l_friend_id := user_access.last_user.user_id user_access.retrieve_friendship (l_user_id, l_friend_id) if user_access.is_found then -- now remove friendship from DB user_access.delete_friendship (l_user_id, l_friend_id) -- send True back create l_status.make (True, Void) node.send_message_reply (l_status, a_msg) else create l_status.make (False, err_invalid_friendship) node.send_message_reply (l_status, a_msg) end 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_user) node.send_message_reply (l_status, a_msg) end end user_list_friends (a_msg: A_MESSAGE) -- List friends of a user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_LIST_FRIENDS_MESSAGE l_reply: O_USER_LIST_FRIENDS_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_friend: USER l_friends: LIST [USER] l_friend_details: TUPLE[name:STRING; icon: STRING; real_name: STRING] l_friend_list: DS_HASH_TABLE [O_USER_FRIEND_MESSAGE, A_STRING_VALUE] l_user: USER i: INTEGER do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_name (l_msg.username.value, False) if user_access.is_found then l_user := user_access.last_user -- retrieve friends and map them into a HASH_TABLE user_access.retrieve_friends_of_user (l_user.user_id) if user_access.is_found then l_friends := user_access.last_friends create l_friend_list.make (l_friends.count) from l_friends.start i := 0 until l_friends.after loop l_friend := l_friends.item create l_friend_details l_friend_details.name := l_friends.item.name l_friend_details.icon := "" l_friend_details.real_name := "" user_access.retrieve_user_information_by_id (l_friends.item.user_id) if user_access.is_found then l_friend_details.icon := user_access.last_user_information.icon if not user_access.last_user_information.first_name.is_empty and not user_access.last_user_information.last_name.is_empty then l_friend_details.real_name := user_access.last_user_information.first_name + " " + user_access.last_user_information.last_name elseif not user_access.last_user_information.first_name.is_empty then l_friend_details.real_name := user_access.last_user_information.first_name elseif not user_access.last_user_information.last_name.is_empty then l_friend_details.real_name := user_access.last_user_information.last_name end end l_friend_list.force ( create {O_USER_FRIEND_MESSAGE}.make ( l_friend_details.name, l_friend_details.icon, l_friend_details.real_name), i.out) -- Increment l_friends.forth i := i + 1 end else create l_friend_list.make (0) end create l_reply.make (create {A_MAP_VALUE[O_USER_FRIEND_MESSAGE]}.make (l_friend_list)) 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 user_send_message (a_msg: A_MESSAGE) -- Send message call -> reply with email address and names. require a_msg_ok: a_msg /= Void local l_msg: O_USER_SEND_MESSAGE_MESSAGE l_reply: O_USER_SEND_MESSAGE_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_sender: USER l_sender_pretty_name: STRING l_sender_information: USER_INFORMATION l_recipient: USER l_recipient_name: STRING l_recipient_information: USER_INFORMATION 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 l_sender := user_access.last_user user_access.retrieve_user_by_name (l_msg.username.value, False) if user_access.is_found then l_recipient := user_access.last_user l_sender_pretty_name := l_sender.name user_access.retrieve_user_information_by_id (l_sender.user_id) if user_access.is_found then l_sender_information := user_access.last_user_information if not l_sender_information.first_name.is_empty and not l_sender_information.last_name.is_empty then l_sender_pretty_name := l_sender_information.first_name + " " + l_sender_information.last_name + " (" + l_sender.name + ")" elseif not l_sender_information.first_name.is_empty then l_sender_pretty_name := l_sender_information.first_name + " (" + l_sender.name + ")" elseif not l_sender_information.last_name.is_empty then l_sender_pretty_name := l_sender_information.last_name + " (" + l_sender.name + ")" end end l_recipient_name := l_recipient.name user_access.retrieve_user_information_by_id (l_recipient.user_id) if user_access.is_found then l_recipient_information := user_access.last_user_information if not l_recipient_information.first_name.is_empty and not l_recipient_information.last_name.is_empty then l_recipient_name := l_recipient_information.first_name + " " + l_recipient_information.last_name + " (" + l_recipient.name + ")" elseif not l_recipient_information.first_name.is_empty then l_recipient_name := l_recipient_information.first_name + " (" + l_recipient.name + ")" elseif not l_recipient_information.last_name.is_empty then l_recipient_name := l_recipient_information.last_name + " (" + l_recipient.name + ")" end end create l_reply.make ( l_recipient.email, l_recipient_name, l_sender_pretty_name, l_sender.name) 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_session) node.send_message_reply (l_status, a_msg) end end user_disable_account (a_msg: A_MESSAGE) -- Disable account of user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_DISABLE_ACCOUNT_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user: USER l_is_origo_admin: BOOLEAN l_user_id_to_disable: INTEGER 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 l_user := user_access.last_user l_is_origo_admin := policy_cache.user_associations.item (l_user.user_id) /= Void and then policy_cache.user_associations.item (l_user.user_id).has (1) if l_is_origo_admin then -- All hail the administrator, -- He how is allowed to disable the account with `user_name'! user_access.retrieve_user_by_name (l_msg.user_name, True) if user_access.last_user /= Void then l_user_id_to_disable := user_access.last_user.user_id disable_account (l_user_id_to_disable) else -- user not found l_user_id_to_disable := 0 end else -- Non-admin user can only disable themselves: -- Take the user-id of the session, discard the passed user_name l_user_id_to_disable := l_user.user_id end if l_user_id_to_disable > 0 then disable_account (l_user_id_to_disable) create l_status.make (True, Void) else create l_status.make (False, err_invalid_name) end node.send_message_reply (l_status, a_msg) else create l_status.make (False, err_invalid_session) node.send_message_reply (l_status, a_msg) end end user_list_communities (a_msg: A_MESSAGE) -- List communities of a user. require a_msg_ok: a_msg /= Void local l_msg: O_USER_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 l_user: USER 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 user_access.retrieve_user_by_name (l_msg.username.value, False) if user_access.is_found then l_user := user_access.last_user -- retrieve communities and map them into a LIST community_access.retrieve_communities_of_user (l_user.user_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 (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_user) 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 key (a_msg: A_MESSAGE) -- Retrieve the user key. require a_msg_ok: a_msg /= Void local l_msg: O_USER_KEY_MESSAGE l_reply: O_USER_KEY_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_key: STRING do l_msg ?= a_msg check user_key_message: l_msg /= Void end l_key := user_access.retrieve_key(l_msg.session.value) if l_key /= Void and then not l_key.is_empty then create l_reply.make (l_key) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_no_user_key) node.send_message_reply (l_status, a_msg) end end key_generate (a_msg: A_MESSAGE) -- Generate a new user key for a user require a_msg_ok: a_msg /= Void local l_msg: O_USER_KEY_GENERATE_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user: USER l_key: STRING 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 l_user := user_access.last_user from l_key := token_generator.generate_id until not user_access.has_user_key (l_key) loop -- try another key l_key := token_generator.generate_id end user_access.update_user_key (l_user.user_id, l_key) create l_status.make (True, Void) else create l_status.make (False, err_invalid_user) end node.send_message_reply (l_status, a_msg) end add_bookmark (a_msg: A_MESSAGE) -- Add bookmark to a project require a_msg_ok: a_msg /= Void local l_msg: O_USER_ADD_BOOKMARK_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user: USER l_project_bookmark: PROJECT_BOOKMARK 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 l_user := user_access.last_user project_access.retrieve_project_by_id (l_msg.project.value.to_integer) if project_access.is_found then create l_project_bookmark.make l_project_bookmark.set_project_id (l_msg.project.value.to_integer) l_project_bookmark.set_user_id (l_user.user_id) user_access.insert_bookmark (l_project_bookmark) -- subscribe to all workitems if user is not already a member of this project if user_access.retrieve_user_project_association_group (l_msg.project.value.to_integer, l_user.user_id) = 0 then user_access.insert_all_project_workitem_subscriptions (l_user.user_id, l_msg.project.value.to_integer) 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 remove_bookmark (a_msg: A_MESSAGE) -- Remove bookmark to a project require a_msg_ok: a_msg /= Void local l_msg: O_USER_REMOVE_BOOKMARK_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user: USER 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 l_user := user_access.last_user project_access.retrieve_project_by_id (l_msg.project.value.to_integer) if project_access.is_found then user_access.delete_bookmark (l_msg.project.value.to_integer, l_user.user_id) -- remove all subscriptions if user is not still a member of this project if user_access.retrieve_user_project_association_group (l_msg.project.value.to_integer, l_user.user_id) = 0 then user_access.delete_project_workitem_subscriptions (l_user.user_id, l_msg.project.value.to_integer) 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 list_bookmark (a_msg: A_MESSAGE) -- List bookmarks. require a_msg_ok: a_msg /= Void local l_msg: O_USER_LIST_BOOKMARK_MESSAGE l_reply: O_USER_LIST_BOOKMARK_REPLY_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_lst: LIST [PROJECT] l_projects: DS_HASH_TABLE [A_STRING_VALUE, A_STRING_VALUE] l_proj: PROJECT l_user: USER do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_name (l_msg.username.value, False) if user_access.is_found then l_user := user_access.last_user -- retrieve projects and map them into a HASH_TABLE project_access.retrieve_bookmark_projects_of_user(l_user.user_id) from l_lst := project_access.last_project_list create l_projects.make (l_lst.count) l_lst.start until l_lst.after loop l_proj := l_lst.item l_projects.force (l_proj.name, l_proj.project_id.out) l_lst.forth end create l_reply.make (create {A_MAP_VALUE [A_STRING_VALUE]}.make (l_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 user_set_workitem_subscription (a_msg: A_MESSAGE) -- Set workitem subscription according to a_msg. require a_msg_ok: a_msg /= Void local l_pc_msg: O_USER_SET_WORKITEM_SUBSCRIPTION_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_user_ret: USER l_project_ret: PROJECT l_settings_list: DS_ARRAYED_LIST [O_USER_WORKITEM_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 l_user_ret := user_access.last_user project_access.retrieve_project_by_id (l_pc_msg.project.value.to_integer) if project_access.is_found then l_project_ret := project_access.last_project l_settings_list := l_pc_msg.settings.sequence from l_settings_list.start until l_settings_list.after loop --TODO: add checks for workitem_type and subscription_type user_access.update_user_workitem_subscription ( l_project_ret.project_id, l_user_ret.user_id, l_settings_list.item_for_iteration.workitem_type.value.to_integer, l_settings_list.item_for_iteration.subscription_type.value.to_integer, l_settings_list.item_for_iteration.is_enabled.value) l_settings_list.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 user_list_workitem_subscription (a_msg: A_MESSAGE) -- List workitem subscriptions. require a_msg_ok: a_msg /= Void local l_msg: O_USER_LIST_WORKITEM_SUBSCRIPTION_MESSAGE l_reply: O_USER_WORKITEM_SUBSCRIPTIONS_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_query_result: ARRAYED_LIST [TUPLE [workitem_type: INTEGER; subscription_type: INTEGER]] l_subscription_list: DS_ARRAYED_LIST [O_USER_SUBSCRIPTION_SETTING_MESSAGE] do l_msg ?= a_msg check workitem_list_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.value.to_integer) if project_access.is_found then l_query_result := user_access.retrieve_workitem_subscription (user_access.last_user.user_id, project_access.last_project.project_id) create l_subscription_list.make (l_query_result.count) from l_query_result.start until l_query_result.after loop l_subscription_list.force_last ( create {O_USER_SUBSCRIPTION_SETTING_MESSAGE}.make ( l_query_result.item_for_iteration.workitem_type, l_query_result.item_for_iteration.subscription_type)) -- Increment l_query_result.forth end create l_reply.make (create {A_SEQUENCE_VALUE[O_USER_SUBSCRIPTION_SETTING_MESSAGE]}.make (l_subscription_list)) 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_user) node.send_message_reply (l_status, a_msg) end end user_valid_setting_names (a_msg: A_MESSAGE) -- Retrieve a list of user-setting names that we accept require a_msg_ok: a_msg /= Void local l_msg: O_USER_RETRIEVE_VALID_SETTING_NAMES_MESSAGE l_reply: O_USER_RETRIEVE_VALID_SETTING_NAMES_REPLY_MESSAGE l_names: DS_HASH_TABLE [STRING, STRING] l_names_map: DS_HASH_TABLE [A_STRING_VALUE, A_STRING_VALUE] do l_msg ?= a_msg check l_msg /= Void end l_names := user_access.user_valid_setting_names from l_names.start create l_names_map.make (l_names.count) until l_names.after loop l_names_map.force_last (l_names.item_for_iteration, l_names.key_for_iteration) -- increment l_names.forth end create l_reply.make (l_names_map) node.send_message_reply (l_reply, a_msg) end svn_configuration (a_msg: A_MESSAGE) -- Retrieve configuration files for subversion. require a_msg_ok: a_msg /= Void local l_request_msg: O_USER_RETRIEVE_SUBVERSION_CONFIGURATION_MESSAGE l_msg: A_CONFIG_FILE_WRITE_LIST_MESSAGE l_file_list: DS_ARRAYED_LIST [A_CONFIG_CONFIG_FILE_MESSAGE] do l_request_msg ?= a_msg check l_request_msg /= Void end create l_file_list.make (2) l_file_list.force_last (create {A_CONFIG_CONFIG_FILE_MESSAGE}.make ( svn_auth_dir + "/users", user_access.retrieve_auth_users)) l_file_list.force_last (create {A_CONFIG_CONFIG_FILE_MESSAGE}.make ( svn_auth_dir + "/access", user_access.retrieve_svn_access)) l_file_list.force_last (create {A_CONFIG_CONFIG_FILE_MESSAGE}.make ( svn_auth_dir + "/access_download", user_access.retrieve_download_access)) create l_msg.make (create {A_SEQUENCE_VALUE [A_CONFIG_CONFIG_FILE_MESSAGE]}.make (l_file_list)) node.send_message_reply (l_msg, a_msg) end git_configuration (a_msg: A_MESSAGE) require a_msg_ok: a_msg /= Void local l_msg: O_USER_RETRIEVE_GIT_CONFIGURATION_MESSAGE l_reply: O_USER_RETRIEVE_GIT_CONFIGURATION_REPLY_MESSAGE l_access_mapping: DS_HASH_TABLE [TUPLE [r: DS_ARRAYED_LIST [STRING]; rw:DS_ARRAYED_LIST [STRING]], STRING] l_project_tuple: TUPLE [read: DS_ARRAYED_LIST [STRING]; rw:DS_ARRAYED_LIST [STRING]] l_read_list, l_rw_list: DS_ARRAYED_LIST [A_STRING_VALUE] l_project_access: O_USER_PROJECT_ACCESS_MESSAGE l_projects: DS_HASH_TABLE [O_USER_PROJECT_ACCESS_MESSAGE, A_STRING_VALUE] do l_msg ?= a_msg check l_msg /= Void end user_access.retrieve_source_access l_access_mapping := user_access.last_access_mapping create l_projects.make (l_access_mapping.count) from l_access_mapping.start until l_access_mapping.after loop l_project_tuple := l_access_mapping.item_for_iteration -- process read access create l_read_list.make (l_project_tuple.read.count) l_project_tuple.read.do_all (agent convert_string_list (?, l_read_list)) -- process read/write access create l_rw_list.make (l_project_tuple.rw.count) l_project_tuple.rw.do_all (agent convert_string_list (?, l_rw_list)) create l_project_access.make ( create {A_SEQUENCE_VALUE [A_STRING_VALUE]}.make(l_read_list), create {A_SEQUENCE_VALUE [A_STRING_VALUE]}.make(l_rw_list)) l_projects.force (l_project_access, l_access_mapping.key_for_iteration) -- Increment l_access_mapping.forth end create l_reply.make (create {A_MAP_VALUE [O_USER_PROJECT_ACCESS_MESSAGE]}.make(l_projects)) node.send_message_reply (l_reply, a_msg) end ftp_configuration (a_msg: A_MESSAGE) -- Retrieve configuration files for ftp. require a_msg_ok: a_msg /= Void local l_request_msg: O_USER_RETRIEVE_FTP_CONFIGURATION_MESSAGE l_msg: A_CONFIG_FILE_WRITE_LIST_MESSAGE l_file_list: DS_ARRAYED_LIST [A_CONFIG_CONFIG_FILE_MESSAGE] do l_request_msg ?= a_msg check l_request_msg /= Void end create l_file_list.make (1) l_file_list.force_last (create {A_CONFIG_CONFIG_FILE_MESSAGE}.make ( "/etc/pure-ftpd/pureftpd.passwd", user_access.retrieve_ftp_users (ftp_dir))) create l_msg.make (create {A_SEQUENCE_VALUE [A_CONFIG_CONFIG_FILE_MESSAGE]}.make (l_file_list)) node.send_message_reply (l_msg, a_msg) end mail_addresses (a_msg: A_MESSAGE) -- Retrieve all email addresses. require a_msg_ok: a_msg /= Void local l_addresses: LIST [STRING] l_address_list: DS_ARRAYED_LIST [A_STRING_VALUE] l_msg: O_SYSTEM_RETRIEVE_ALL_EMAIL_REPLY_MESSAGE do l_addresses := user_access.retrieve_mail_addresses create l_address_list.make (l_addresses.count) from l_addresses.start until l_addresses.after loop l_address_list.force_last (l_addresses.item.twin) l_addresses.forth end create l_msg.make (create {A_SEQUENCE_VALUE [A_STRING_VALUE]}.make (l_address_list)) node.send_message_reply (l_msg, a_msg) end cleanup -- Cleanup old sessions and non-verified accounts. do user_access.purge_old_sessions(session_lifetime) user_access.purge_old_friendship_requests(friendship_request_lifetime) user_access.purge_old_unverified_accounts(account_activation_lifetime) end feature {NONE} -- Implementation disable_account (a_user_id: INTEGER) -- disable the account of `a_user' require user_id_specified: a_user_id > 0 do -- modify user table and set user_association to '5' -> disabled user user_access.disable_account (a_user_id) -- remove bookmarks user_access.delete_all_bookmarks (a_user_id) -- remove read_workitems user_access.delete_all_user_read_workitems (a_user_id) -- remove user information -- disabled because we do want to keep user information for statistic usage -- user_access.delete_user_information (a_user_id) -- remove user_workitem_subscription user_access.delete_all_workitem_subscriptions (a_user_id) -- remove user from user-project-association table user_access.delete_all_user_project_associations (a_user_id) -- remove friendships user_access.delete_all_friendships (a_user_id) -- remove friendship_requests user_access.delete_all_friendship_requests (a_user_id) -- remove session user_access.delete_session (a_user_id) end session_lifetime: INTEGER -- session lifetime in seconds require config_parser_is_ok: node.config_parser /= Void local l_lifetime: STRING once l_lifetime := node.config_parser.get_default ("session_lifetime", "3600") Result := l_lifetime.to_integer if Result <= 0 then Result := 3600 end ensure result_is_valid: Result > 0 end friendship_request_lifetime: INTEGER -- friendship request lifetime in days require config_parser_is_ok: node.config_parser /= Void local l_lifetime: STRING once l_lifetime := node.config_parser.get("friendship_request_lifetime") if l_lifetime = Void then Result := 14 else Result := l_lifetime.to_integer if Result <= 0 then Result := 14 end end ensure result_is_valid: Result > 0 end account_activation_lifetime: INTEGER -- account activation lifetime in days require config_parser_is_ok: node.config_parser /= Void local l_lifetime: STRING once l_lifetime := node.config_parser.get("account_activation_lifetime") if l_lifetime = Void then Result := 7 else Result := l_lifetime.to_integer if Result <= 0 then Result := 7 end end ensure result_is_valid: Result > 0 end svn_auth_dir: STRING -- svn authentication directory require config_parser_is_ok: node.config_parser /= Void once Result := node.config_parser.get_default ("svn_auth_dir", "/etc/origo/svnauth") ensure result_is_valid: Result /= Void and then not Result.is_empty end ftp_dir: STRING -- ftp directory require config_parser_is_ok: node.config_parser /= Void once Result := node.config_parser.get_default ("ftp_dir", "/var/lib/origo-files/ftp") ensure result_is_valid: Result /= Void and then not Result.is_empty end feature {NONE} -- Utilities convert_string_list (a_value: STRING; a_list: DS_ARRAYED_LIST [A_STRING_VALUE]) do a_list.force_last (a_value) end convert_string_map (a_value: STRING; a_key: STRING; a_map: DS_HASH_TABLE [A_STRING_VALUE, A_STRING_VALUE]) do a_map.force_last (a_value, a_key) end convert_integer_map (a_value: INTEGER; a_key: STRING; a_map: DS_HASH_TABLE [A_INTEGER_VALUE, A_STRING_VALUE]) do a_map.force_last (a_value, a_key) end convert_double_map (a_value: DOUBLE; a_key: STRING; a_map: DS_HASH_TABLE [A_DOUBLE_VALUE, A_STRING_VALUE]) do a_map.force_last (a_value, a_key) end feature {NONE} -- Cache token_generator: SESSION_ID_GENERATOR -- Generate random strings. once create Result.make end end