python-COMP1531 /

2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 1/18 Forked from an inaccessible project Merge changes from starter code into ‘master’ COMP1531 Bot authored 1 day ago ed0faa53 Name Last commit Last update Iteration 2 2 weeks ago Fixed auth_login error 1 week ago Fixed auth_login error 1 week ago Iteration 2 2 weeks ago Deferred data persistence issues till completion of iteration two features – … 1 week ago Iteration 2 2 weeks ago Iteration 2 2 weeks ago Update README.md 1 day ago Cleared coverage requirements and added uuid to get unique message_id 1 week ago Release 1 month ago add teamwork file 2 weeks ago Tracing pylint errors again; edited test.py because fixture implementation … 1 week ago Teamwork makes the [UNSW] Dream[s] work 1. Aims 2. Overview 3. Iteration 1: Basic functionality and tests 4. Iteration 2: Building a web server 5. Iteration 3: Completing the lifecycle 6. Interface specifications 7. Style and documentation 8. Due Dates and Weightings 9. Other Expectations 10. Plagiarism 12/03: Extended Iteration due date by 1 day, fixed up marking criteria to add to 100% 14/03: See commit for more info, non-trivial clarifications include: Correct error.py file pushed to repository P project-backend Project ID: 105428 Leave project 1 0 pipeline passed README.md COMP1531 Major Project Contents 0. Change Log http_tests src tests .coveragerc .gitignore .gitlab-ci.yml .pylintrc README.md assumptions.md pytest.ini teamwork.md test.py 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 2/18 Clarity on handle_str length when updating str Adding some missing locations that show when behaviour on channels is the same as behaviour on DMs Clarity on behaviour on how contents of messages are changed when an admin removes a user Valid email format re-added to spec (accidentally removed) Clarified the data type of notifications dm/create/v1 behaviour clarified message/share/v1 behaviour clarified in cases where no message is given Behaviour of handle generation on auth/register clarified. The handle is truncated to 20 characters during concatenation, but the process of adding the number at the end can extend the 20 characters. For groups that have implemented this behaviour differently (as per some forum posts), you are allowed to keep that implementation and you will not lose marks. 16/03: Clarified that messages from users in a channel should remain after they leave the channel Clarified the parameters of dm/create Specified that the creator of a DM is also the owner 20/03: Fixed parameters of dm/create 26/03: Removed “React” from the notification data type, as that isn’t until iteration 3 To provide students with hands on experience testing, developing, and maintaining a backend server in python. To develop students’ problem solving skills in relation to the software development lifecycle. Learn
to work effectively as part of a team by managing your project,
planning, and allocation of responsibilities among the members of your team. Gain experience in collaborating through the use of a source control and other associated modern team-based tools. Apply appropriate design practices and methodologies in the development of their solution Develop an appreciation for product design and an intuition of how a typical customer will use a product. To
manage the transition from trimesters to hexamesters in 2020, UNSW has
established a new focus on building an in-house digital collaboration and communication tool for groups and teams to support the high intensity learning environment. Rather
than re-invent the wheel, UNSW has decided that it finds the
functionality of Microsoft Teams to be nearly exactly what it needs. For
this reason, UNSW has contracted out Penguin Pty Ltd (a small
software business run by Hayden) to build the new product. In UNSW’s
attempt to try and add a lighter not to the generally fatigued and
cynical student body, they have named their UNSW-based product UNSW
Dreams (or just Dreams for short). UNSW Dreams is the communication
tool that allows you to share, communication, and collaborate to
(attempt to) make dreams a reality. Penguin Pty Ltd has sub-contracted two software firms: BlueBottle Pty Ltd (two software developers, Andrea and Andrew, who will build the initial web-based GUI) YourTeam
Pty Ltd (a team of talented misfits completing COMP1531 in 21T1), who
will build the backend python server and possibly assist in the GUI later in the project In summary, UNSW contracts Penguin Pty Ltd, who sub contracts: BlueBottle (Andrea and Andrew) for front end work YourTeam (you and others) for backend work Penguin
Pty Ltd met with Andrea and Andrew (the front end development team) 2
weeks ago to brief them on this project. While you are still trying
to get up to speed on the requirements of this project, Andrea and
Andrew understand the requirements of the project very well. Because
of this they have already specified a common interface for the frontend
and backend to operate on. This allows both parties to go off and
do their own development and testing under the assumption that both
parties will comply with the common interface. This is the interface you are required to use Besides
the information available in the interface that Andrea and Andrew
provided, you have been told (so far) that the features of Dreams that UNSW would like to see implemented include: 1. Ability to login, register if not registered, and log out 2. Ability to reset password if forgotten 3. Ability to see a list of channels 4. Ability to create a channel, join a channel, invite someone else to a channel, and leave a channel 5. Within a channel, ability to view all messages, view the members of the channel, and the details of the channel 6. Within a channel, ability to send a message now, or to send a message at a specified time in the future 7. Within a channel, ability to edit, share between channels, remove, pin, unpin, react, or unreact to a message 8. Ability to view anyone’s user profile, and modify a user’s own profile (name, email, handle, and profile photo) 9. Ability to search for messages based on a search string 10. Ability to modify a user’s admin permissions: (MEMBER, OWNER) 11.
Ability to begin a “standup”, which is an X minute period where users
can send messages that at the end of the period will automatically be collated and summarised to all users 1. Aims: 2. Overview 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 3/18 12. Ability to send message directly to a user (or group of users) via direct messaging (DM). The
specific capabilities that need to be built for this project are
described in the interface at the bottom. This is clearly a lot of
features, but not all of them are to be implemented at once (see below) This iteration is now complete. Please see commit history to view information pertaining to iteration 1. NOTE:
In merging the instructions for this iteration into your repo, you may
get a failed pipeline. This is most likely because your code is not pylint
compliant. If this is the case, that is the first thing you should
address for this iteration. It is important you have a stable master
branch before proceeding to add additional features. In this
iteration, more features were added to the specification, and the focus
has been changed to HTTP endpoints. Many of the theory surrounding
iteration 2 will be covered in week 4-6 lectures. Note that there will
still be 1 or 2 features of the frontend that will not work because the routes will not appear until iteration 3. In this iteration, you are expected to: 1. Implement and test the HTTP Flask server according to the entire interface provided in the specification. Part of this section may be automarked. Pylint
has been added to your continuous integration file, meaning that code
that isn’t pylint compliant will now fail the pipeline. The provided .pylintrc file is very lenient, so there is no reason you should have to disable any additional checks. Additionally,
CI pipelines will measure branch coverage for all .py files that
aren’t tests. The coverage percentage for master is visible in a
badge at the top of this repo and changes in coverage will appear in
Merge Requests. Do note that coverage of server.py is not measured,
nor will what is executed by your HTTP tests. This is because, when
running HTTP tests, the server is run in a separate process. Your
implementation should build upon your work in iteration 1, and ideally
your HTTP layer is just a wrapper for underlying functions you’ve
written that handle the logic. Your implementation will rely on topics
taught in week 4 (HTTP servers and testing) as well as week 5 (authentication and authorisation). Your implementation will need to implement persistence of data (see section 4.4). You
can structure your tests however you choose, as long as they are
appended with _test.py . It’s important you consider how to separate
(or combine) your unit/integration tests from iteration 1 with the
extra system tests (HTTP with requests library) in iteration 2. You
will be marked on both tests being present/used in this iteration. An
example of a HTTP test has been provided for you in http_tests/echo_http_test.py . You
do not have to rewrite all of your pytests as HTTP tests – the latter
can test the system at a higher level. For example, to test a success case for message/send via HTTP routes you will need to call auth/register and channels/create ; this means you do not need
the success case for those two functions seperately. Your HTTP tests
will need to cover all success/error conditions for each endpoint, however. Ensure
that you correctly manage sessions and tokens in terms of
authentication and authorisation, as per requirements laid out in section 6.9 2. Continue demonstrating effective project management and effective git usage Part of this section may be automarked. You
will be heavily marked for your use of thoughtful project management
and use of git effectively. The degree to which your team works effectively will also be assessed. As for iteration 1 all task tracking and management will need to be done via the GitLab Taskboard. You
are required to regularly and thoughtfully make merge requests for the
smallest reasonable units, and merge them into master . To run the server you should always use the command python3 src/server.py This
will start the server on the next available port. If you get any errors
relating to flask_cors , ensure you have installed all the necessary Python libraries for this course (the list of libraries was updated for this iteration). You can do this with: pip3 install $(curl https://www.cse.unsw.edu.au/~cs1531/21T1/requirements.txt) 3. Iteration 1: Basic functionality and tests 4. Iteration 2: Building a web server 4.1. Task 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 4/18 A
frontend has been built by Andrea and Andrew that you can use in this
iteration, and use your backend to power it (note: an incomplete backend
will mean the frontend cannot work). You can, if you wish, make changes
to the frontend code, but it is not required for this iteration. The source code for the frontend is only provided for your own fun or curiosity. You
should first approach this project by considering its distinct
“features”. Each feature should add some meaningful functionality to the
project, but still be as small as possible. You should aim to size
features as the smallest amount of functionality that adds value without
making the project more unstable. For each feature you should: 1. Create a new branch. 2. Write tests for that feature and commit them to the branch. 3. Implement that feature. 4.
Make any changes to the tests such that they pass with the given
implementation. You should not have to do a lot here. If you find that
you are, you’re not spending enough time on step 2. 5. Create a merge request for the branch. 6.
Get someone in your team who did not work on the feature to review the
merge request. When reviewing, not only should you ensure the new feature has tests that pass, but you should also check that the coverage percentage has not been significantly reduced. 7. Fix any issues identified in the review. 8. Merge the merge request into master. For
this project, a feature is typically sized somewhere between a single
function, and a whole file of functions (e.g. auth.py ). It is up to you
and your team to decide what each feature is. There is no
requirement that each feature be implemented by only one person. In
fact, we encourage you to work together closely on features, especially to help those who may still be coming to grips with python. Please pay careful attention to the following: Your tests, keep in mind the following: We
want to see evidence that you wrote your tests before writing the
implementation. As noted above, the commits containing your initial
tests should appear before your implementation for every feature branch.
If we don’t see this evidence, we will assume you did not write your tests first and your mark will be reduced. You
should have black-box tests for all tests required (i.e. testing each
function/endpoint). However, you are also welcome to write whitebox unit tests in this iteration if you see that as important. Merging
in merge requests with failing pipelines is very bad practice. Not only
does this interfere with your teams ability to work on different features at the same time, and thus slow down development, it is something you will be penalised for in marking. Similarly,
merging in branches with untested features is also very bad practice.
We will assume, and you should too, that any code without tests does not work. Pushing
directly to master is not possible for this repo. The only way to get
code into master is via a merge request. If you discover you have a bug in master that got through testing, create a bugfix branch and merge that in via a merge request. Our recommendation with this iteration is that you: 1.
Start out trying to implement the new functions the same way you did in
iteration 1 (a series of implemented functions, categorised in files, with black-box pytests testing them). 2.
Write another layer of HTTP tests that test the inputs/outputs on
routes according to the specific, and while writing tests for each component/feature, write the Flask route/endpoint for that feature too. This
approach means that you can essentially finish the project/testing
logic without worrying about HTTP, and then simply wrap the HTTP/Flask layer on top of it at the end. You are required to store data persistently in this iteration. Modify
your backend such that it is able to persist and reload its data store
if the process is stopped and started again. The persistence should happen
at regular intervals so that in the event of unexpected program
termination (e.g. sudden power outage) a minimal amount of data is lost. You may implement this using whatever method of serialisation you prefer (e.g. pickle, JSON). This
iteration due date and demonstrate week is described in section 7. You
will demonstrate this submission inline with the information provided in section 7. You
might notice that some routes are suffixed with v1 and v2 , and that
all the new routes are v1 yet all the old routes are v2 . Why is this When
you make changes to specifications, it’s usually good practice to give
the new function/capability/route a different unique name. This way, if
people are using older versions of the specification they can’t
accidentally call the updated function/route with the wrong data input. 4.2. Implementing and testing features 4.3. Recommended approach 4.4. Storing data 4.5. Submission 4.6. Versioning 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 5/18 Hint:
Yes, your v2 routes can use the X_Y_v1 functions you had in iteration
1, regardless of whether you rename the functions or not. The layer of
abstraction in iteration 2 has changed from the function interface to
the HTTP interface, and therefore your ‘functions’ from iteration 1 are essentailly now just implementation details, and therefore are completely modifiable by you. Section Weighting Criteria Automarking (Testing) 15% Correctly written tests based on the specification requirements Code coverage (99% coverage gives 30% of the marks for this section) Automarking (Implementation) 35% Correct implementation of specified functions Correctly linted code (worth 10% of this section) Code Quality 30% Demonstrated an understanding of good test coverage Demonstrated an understanding of the importance of clarity on the communication test and code purposes Demonstrated an understanding of thoughtful test design Appropriate use of python data structures (lists, dictionaries, etc.) Appropriate style as described in section 8.4 Appropriate application of good software design and pythonic patterns Implementation of persistent state Git & Project Management 20% Meaningful and informative git commit names being used At least 12 merge requests into master made A generally equal contribution between team members Clear evidence of reflection on group’s performance and state of the team, with initiative to improve in future iterations Effective use of course-provided MS Teams for communicating, demonstrating an ability to communicate and manage effectivelly digitally Use of task board on Gitlab to track and manage tasks Effective use of agile methods such as standups Minutes/notes taken from group meetings (and stored in a logical place in the repo) For this and for all future milestones, you should consider the other expectations as outlined in section 8 below. Coming Soon These interface specifications come from Andrea and Andrew, who are building the frontend to the requirements set out below. Variable name Type named exactly email string has suffix id integer named exactly length integer contains substring password string named exactly token string 4.7. Marking Criteria 5. Iteration 3: Completing the lifecycle 6. Interface specifications 6.1. Data types 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 6/18 named exactly message string contains substring name string has prefix is_ boolean has prefix time_ integer (unix timestamp), check this out (outputs only) named exactly messages List of dictionaries, where each dictionary contains types { message_id, u_id, message, time_created } (outputs only) named exactly channels List of dictionaries, where each dictionary contains types { channel_id, name } has suffix _str string (outputs only) named exactly dms List of dictionaries, where each dictionary contains types { dm_id, name } (outputs only) name ends in members List of dictionaries, where each dictionary contains types of user (outputs only) named exactly user Dictionary containing u_id, email, name_first, name_last, handle_str (outputs only) named exactly users List of dictionaries, where each dictionary contains types of user (outputs only) named exactly notifications List of dictionaries, where each dictionary contains types { channel_id, dm_id, notification_message } where channel_id is the id of the channel that the event happened in, and is -1 if it is being sent to a DM. dm_id is the DM that the event happened in, and is -1 if it is being sent to a channel. The list should be ordered from most to least recent. Notification_message is a string of the following format for each trigger action: tagged: “{User’s handle} tagged you in {channel/DM name}: {first 20 characters of the message}” added to a channel/DM: “{User’s handle} added you to {channel/DM name}” named exactly u_ids List of user ids Name & Description HTTP Method Data Types Exceptions auth/login/v2 Given a registered users’ email and password and returns a new `token` for that session POST Parameters: (email, password) Return Type: { token, auth_user_id } InputError when any of: Email entered is not a valid email Email entered does not belong to a user Password is not correct 6.2. Interface 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 7/18 auth/register/v2 Given a user’s first and last name, email address, and password, create a new account for them and return a new `token` for that session. A handle is generated that is the concatenation of a lowercase-only first name and last name. If the concatenation is longer than 20 characters, it is cutoff at 20 characters. The handle will not include any whitespace or the ‘@’ character. Once you’ve concatenated it, if the handle is once again taken, append the concatenated names with the smallest number (starting from 0) that forms a new handle that isn’t already taken. The addition of this final number may result in the handle exceeding the 20 character limit. POST Parameters: (email, password, name_first, name_last) Return Type: { token, auth_user_id } InputError when any of: Email entered is not a valid email using the method provided here (unless you feel you have a better method). Email address is already being used by another user Password entered is less than 6 characters long name_first is not between 1 and 50 characters inclusively in length name_last is not between 1 and 50 characters inclusively in length auth/logout/v1 Given an active token, invalidates the token to log the user out. If a valid token is given, and the user is successfully logged out, it returns true, otherwise false. POST Parameters: (token) Return Type: { is_success } N/A channel/invite/v2 Invites a user (with user id u_id) to join a channel with ID channel_id. Once invited the user is added to the channel immediately POST Parameters: (token, channel_id, u_id) Return Type: {} InputError when any of: channel_id does not refer to a valid channel. u_id does not refer to a valid user AccessError when any of: the authorised user is not already a member of the channel 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 8/18 channel/details/v2 Given a Channel with ID channel_id that the authorised user is part of, provide basic details about the channel GET Parameters: (token, channel_id) Return Type: { name, is_public, owner_members, all_members } InputError when any of: Channel ID is not a valid channel AccessError when any of: Authorised user is not a member of channel with channel_id channel/messages/v2 Given a Channel with ID channel_id that the authorised user is part of, return up to 50 messages between index “start” and “start + 50”. Message with index 0 is the most recent message in the channel. This function returns a new index “end” which is the value of “start + 50”, or, if this function has returned the least recent messages in the channel, returns -1 in “end” to indicate there are no more messages to load after this return. GET Parameters: (token, channel_id, start) Return Type: { messages, start, end } InputError when any of: Channel ID is not a valid channel start is greater than the total number of messages in the channel AccessError when any of: Authorised user is not a member of channel with channel_id channel/join/v2 Given a channel_id of a channel that the authorised user can join, adds them to that channel POST Parameters: (token, channel_id) Return Type: {} InputError when any of: Channel ID is not a valid channel AccessError when any of: channel_id refers to a channel that is private (when the authorised user is not a global owner) 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 9/18 channel/addowner/v1 Make user with user id u_id an owner of this channel POST Parameters: (token, channel_id, u_id) Return Type: {} InputError when any of: Channel ID is not a valid channel When user with user id u_id is already an owner of the channel AccessError when the authorised user is not an owner of the **Dreams**, or an owner of this channel channel/removeowner/v1 Remove user with user id u_id an owner of this channel POST Parameters: (token, channel_id, u_id) Return Type: {} InputError when any of: Channel ID is not a valid channel When user with user id u_id is not an owner of the channel The user is currently the only owner AccessError when the authorised user is not an owner of the **Dreams**, or an owner of this channel channel/leave/v1 Given a channel ID, the user removed as a member of this channel. Their messages should remain in the channel POST Parameters: (token, channel_id) Return Type: {} InputError when any of: Channel ID is not a valid channel AccessError when Authorised user is not a member of channel with channel_id channels/list/v2 Provide a list of all channels (and their associated details) that the authorised user is part of GET Parameters: (token) Return Type: { channels } N/A channels/listall/v2 Provide a list of all channels (and their associated details) GET Parameters: (token) Return Type: { channels } N/A 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 10/18 channels/create/v2 Creates a new channel with that name that is either a public or private channel POST Parameters: (token, name, is_public) Return Type: { channel_id } InputError when any of: Name is more than 20 characters long message/send/v2 Send a message from authorised_user to the channel specified by channel_id. Note: Each message should have it’s own unique ID. I.E. No messages should share an ID with another message, even if that other message is in a different channel. POST Parameters: (token, channel_id, message) Return Type: { message_id } InputError when any of: Message is more than 1000 characters AccessError when: the authorised user has not joined the channel they are trying to post to message/edit/v2 Given a message, update its text with new text. If the new message is an empty string, the message is deleted. PUT Parameters: (token, message_id, message) Return Type: {} InputError when any of: Length of message is over 1000 characters message_id refers to a deleted message AccessError when none of the following are true: Message with message_id was sent by the authorised user making this request The authorised user is an owner of this channel (if it was sent to a channel) or the **Dreams** 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 11/18 message/remove/v1 Given a message_id for a message, this message is removed from the channel/DM DELETE Parameters: (token, message_id) Return Type: {} InputError when any of: Message (based on ID) no longer exists AccessError when none of the following are true: Message with message_id was sent by the authorised user making this request The authorised user is an owner of this channel (if it was sent to a channel) or the **Dreams** message/share/v1 og_message_id is the original message. channel_id is the channel that the message is being shared to, and is -1 if it is being sent to a DM. dm_id is the DM that the message is being shared to, and is -1 if it is being sent to a channel. message is the optional message in addition to the shared message, and will be an empty string ” if no message is given POST Parameters: (token, og_message_id, message, channel_id, dm_id) Return Type: {shared_message_id} AccessError when: the authorised user has not joined the channel or DM they are trying to share the message to dm/details/v1 Users that are part of this direct message can view basic information about the DM GET Parameters: (token, dm_id) Return Type: { name, members } InputError when any of: DM ID is not a valid DM AccessError when Authorised user is not a member of this DM with dm_id dm/list/v1 Returns the list of DMs that the user is a member of GET Parameters: (token) Return Type: { dms } N/A dm/create/v1 u_ids contains the user(s) that this DM is directed to, and will not include the creator. The creator is the owner of the DM. name should be automatically generated based on the user(s) that is in this dm. The name should be an alphabetically-sorted, comma-separated list of user handles, e.g. ‘handle1, handle2, handle3’. POST Parameters: (token, u_ids) Return Type: { dm_id, dm_name } InputError when any of: u_id does not refer to a valid user 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 12/18 dm/remove/v1 Remove an existing DM. This can only be done by the original creator of the DM. DELETE Parameters: (token, dm_id) Return Type: {} InputError when: dm_id does not refer to a valid DM AccessError when: the user is not the original DM creator dm/invite/v1 Inviting a user to an existing dm POST Parameters: (token, dm_id, u_id) Return Type: {} InputError when any of: dm_id does not refer to an existing dm. u_id does not refer to a valid user. AccessError when: the authorised user is not already a member of the DM dm/leave/v1 Given a DM ID, the user is removed as a member of this DM POST Parameters: (token, dm_id) Return Type: {} InputError when any of: dm_id is not a valid DM AccessError when Authorised user is not a member of DM with dm_id dm/messages/v1 Given a DM with ID dm_id that the authorised user is part of, return up to 50 messages between index “start” and “start + 50”. Message with index 0 is the most recent message in the channel. This function returns a new index “end” which is the value of “start + 50”, or, if this function has returned the least recent messages in the channel, returns -1 in “end” to indicate there are no more messages to load after this return. GET Parameters: (token, dm_id, start) Return Type: { messages, start, end } InputError when any of: DM ID is not a valid DM start is greater than the total number of messages in the channel AccessError when any of: Authorised user is not a member of DM with dm_id 2021/3/27 COMP1531 / 21T1 / Groups / WED13C_DORITO / project-backend · GitLab https://gitlab.cse.unsw.edu.au/COMP1531/21T1/groups/WED13C_DORITO/project-backend 13/18 message/senddm/v1 Send a message from authorised_user to the DM specified by dm_id. Note: Each message should have it’s own unique ID. I.E. No messages should share an ID with another message, even if that other message is in a different channel or DM. POST Parameters: (token, dm_id, message) Return Type: { message_id } InputError when any of: Message is more than 1000 characters AccessError when: the authorised user is not a member of the DM they are trying to post to user/profile/v2 For a valid user, returns information about their user_id, email, first name, last name, and handle GET Parameters: (token, u_id) Return Type: { user } InputError when any of: User with u_id is not a valid user user/profile/setname/v2 Update the authorised user’s first and last name PUT Parameters: (token, name_first, name_last) Return Type: {} InputError when any of: name_first is not between 1 and 50 characters inclusively in length name_last is not between 1 and 50 characters inclusively in length user/profile/setemail/v2 Update the authorised user’s email address PUT Parameters: (token, email) Return Type: {} InputError when any of: Email entered is not a valid email using the method provided here (unless you feel you have a better method). Email address is already being used by another user user/profile/sethandle/v1 Update the authorised user’s handle (i.e. display name) PUT Parameters: (token, handle_str)