Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

217 new admin endpoints: search user #233

Merged
merged 5 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,38 @@ public async Task UpdateUserGroup(UserGroup userGroup, int userId)
await _context.SaveChangesAsync();
}

public async Task<List<User>> SearchUsers(String search, int pageNum, int pageLength)
{
List<User> users = new List<User>();

int skip = pageNum * pageLength;

if (int.TryParse(search, out int id))
{
var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == id);
if (user != null)
{
users.Add(user);
return users;
}
}

users = await _context.Users
.Where(u => u.Email.ToLower().StartsWith(search.ToLower()) || u.Name.ToLower().StartsWith(search.ToLower()))
.OrderBy(u => u.Id)
.Skip(skip).Take(pageLength)
.ToListAsync();
jonasanker marked this conversation as resolved.
Show resolved Hide resolved


if (users.Count == 0)
jonasanker marked this conversation as resolved.
Show resolved Hide resolved
{
throw new EntityNotFoundException("No users match the search");
}

return users;
}


private async Task<User> GetUserByIdAsync(int id)
{
var user = await _context.Users
Expand Down
10 changes: 10 additions & 0 deletions coffeecard/CoffeeCard.Library/Services/v2/IAccountService.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
Expand Down Expand Up @@ -63,5 +64,14 @@ public interface IAccountService
/// <param name="userGroup"> The user group that will be updated </param>
/// <param name="id"> id of the user </param>
Task UpdateUserGroup(UserGroup userGroup, int id);

/// <summary>
/// Search a user from the database
/// </summary>
/// <param name="search"> The search string from a search bar </param>
/// <param name="pageNum"> The page number </param>
/// <param name="pageLength"> The length of a page </param>
/// <exception cref="EntityNotFoundException"> No user found </exception>
Task<List<User>> SearchUsers(String search, int pageNum, int pageLength);
jonasanker marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.ComponentModel.DataAnnotations;

namespace CoffeeCard.Models.DataTransferObjects.v2.User
{
/// <summary>
/// User information that is returned when searching
/// </summary>
/// <example>
/// {
/// "id": 123,
/// "name": "John Doe",
/// "email": "john@doe.com",
/// "role": "Barista"
/// }
/// </example>
public class UserSearchResponse
{
/// <summary>
/// User Id
/// </summary>
/// <value>User Id</value>
/// <example>123</example>
[Required]
public int Id { get; set; }

/// <summary>
/// Full Name of user
/// </summary>
/// <value>Full Name</value>
/// <example>John Doe</example>
[Required]
public string Name { get; set; }

/// <summary>
/// Email of user
/// </summary>
/// <value>Email</value>
/// <example>john@doe.com</example>
[Required]
public string Email { get; set; }

/// <summary>
/// User's role
/// </summary>
/// <value>Role</value>
/// <example>Barista</example>
[Required]
public UserRole Role { get; set; } = UserRole.Customer;
jonasanker marked this conversation as resolved.
Show resolved Hide resolved
}
}
37 changes: 37 additions & 0 deletions coffeecard/CoffeeCard.WebApi/Controllers/v2/AccountController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoffeeCard.Common.Errors;
using CoffeeCard.Library.Utils;
Expand Down Expand Up @@ -201,5 +204,39 @@ private async Task<UserResponse> UserWithRanking(User user)
PrivacyActivated = user.PrivacyActivated,
};
}

/// <summary>
/// Searches a user in the database
/// </summary>
/// <param name="search"> The search string from a search bar </param>
/// <param name="pageNum"> The page number </param>
/// <param name="pageLength"> The length of a page </param>
/// <returns> A collection of User objects that match the search criteria </returns>
/// <response code="200"> The user(s) were found </response>
/// <response code="401"> Invalid credentials </response>
/// <response code="404"> User(s) not found </response>
[HttpGet]
[AuthorizeRoles(UserGroup.Board)]
[AllowAnonymous]
jonasanker marked this conversation as resolved.
Show resolved Hide resolved
[ProducesResponseType(typeof(ApiError), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(ApiError), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ApiError), StatusCodes.Status200OK)]
jonasanker marked this conversation as resolved.
Show resolved Hide resolved
[Route("search")]
public async Task<ActionResult<IEnumerable<User>>> SearchUsers([FromQuery] String search, [FromQuery] int pageNum, [FromQuery] int pageLength)
jonasanker marked this conversation as resolved.
Show resolved Hide resolved
{
List<User> users = await _accountService.SearchUsers(search, pageNum, pageLength);
return Ok(users.Select(MapSearchedUserToDto).ToList());
}

private static UserSearchResponse MapSearchedUserToDto(User user)
{
return new UserSearchResponse
{
Id = user.Id,
Email = user.Email,
Name = user.Name,
Role = user.UserGroup.toUserRole(),
};
}
}
}
Loading