Tunify Platform is a music streaming service that allows users to create and manage playlists, listen to songs, and follow their favorite artists. The platform supports different subscription plans, including free and premium tiers.
The Tunify Platform consists of several entities that are related to each other in various ways. Below is an overview of these relationships:
-
User
- A user can have one subscription.
- A user can create multiple playlists.
-
Subscription
- A subscription can be associated with multiple users.
-
Playlist
- A playlist belongs to one user.
- A playlist can contain multiple songs through the
PlaylistSongs
join table.
-
PlaylistSongs
- This is a join table that establishes a many-to-many relationship between playlists and songs.
- Each entry in
PlaylistSongs
references one playlist and one song.
-
Song
- A song belongs to one album.
- A song is performed by one artist.
- A song can be part of multiple playlists through the
PlaylistSongs
join table.
-
Album
- An album is created by one artist.
- An album can contain multiple songs.
-
Artist
- An artist can create multiple albums.
- An artist can perform multiple songs.
The Tunify Platform includes new navigation and routing functionalities to enhance user experience. These functionalities allow users to easily navigate through different sections of the platform, such as viewing playlists, songs, and artists. The routing system ensures that users can access specific resources directly via URLs, making the platform more intuitive and user-friendly.
- Playlists:
/api/Playlists/{playlistId}/Songs/{songId}
- Add a song to a playlist. - Artists:
/api/Artists/{artistId}/songs/{songId}
- Add a song to an artist.
The Tunify Platform utilizes the Repository Design Pattern to manage data access. This pattern provides a way to encapsulate the logic required to access data sources, making the code more modular and easier to maintain.
- Separation of Concerns: The data access logic is separated from the business logic, making the codebase cleaner and more organized.
- Testability: Repositories can be easily mocked, which simplifies unit testing.
- Flexibility: Changes to the data access logic (e.g., switching from one database to another) can be made with minimal impact on the rest of the application.
- Reusability: Common data access logic can be reused across different parts of the application.
The platform seeds initial data for all entities to ensure that the database is populated with some default entries. This includes users, subscriptions, artists, albums, songs, playlists, and the relationships between them.
In the Program.cs
file, configure JWT authentication:
builder.Services.AddAuthentication(
options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; })
.AddJwtBearer(
options => { options.TokenValidationParameters = JwtTokenService.ValidateToken(builder.Configuration);
});
Use the JwtTokenService
to generate a JWT token for authenticated users:
public async Task GenerateToken(ApplicationUser user, TimeSpan expiryDate, IList roles)
{
var userPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
if (userPrincipal == null){ return null; }
var claims = new List {
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) };
foreach (var role in roles) { claims.Add(new Claim(ClaimTypes.Role, role)); }
claims.AddRange(userPrincipal.Claims);
var signInKey = GetSecurityKey(_config);
var token = new JwtSecurityToken(
expires: DateTime.Now.Add(expiryDate),
signingCredentials: new SigningCredentials(signInKey, SecurityAlgorithms.HmacSha256),
claims: claims );
return new JwtSecurityTokenHandler().WriteToken(token);
}
Use the [Authorize]
attribute to secure specific API endpoints in your controllers. Apply role-based and policy-based authorization as needed.
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUser _user;
public UsersController(IUser user)
{
_user = user;
}
// GET: api/Users
[HttpGet]
[Authorize(Policy = "AdminPolicy")]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
var users = await _user.GetAllUsersAsync();
return Ok(users);
}
// POST: api/Users
[HttpPost]
[Authorize(Policy = "AdminPolicy")]
public async Task<ActionResult<User>> PostUser(User user)
{
await _user.CreateUserAsync(user);
return Ok(user);
}}
Define roles and claims in your application, ensuring they are correctly assigned to users. Seed initial roles and a default admin user with appropriate claims in the OnModelCreating
method of your TunifyDbContext
.
The Tunify Platform includes Swagger UI for API documentation and testing. Swagger UI provides a visual interface to interact with the API endpoints, making it easier for developers to understand and test the API.
- Run the application using the following command:
dotnet run
- Open a web browser and navigate to
http://localhost:5000/api/v1/swagger.json
to view the Swagger JSON document. - To access the Swagger UI, navigate to
http://localhost:5000/swagger
in your web browser.
- Explore Endpoints: The Swagger UI lists all available API endpoints. You can expand each endpoint to see details such as request parameters and response formats.
- Try it Out: You can test API endpoints directly from the Swagger UI by clicking the "Try it out" button, filling in the required parameters, and executing the request.
- View Responses: After executing a request, the Swagger UI displays the response, including status codes and response bodies.
The Tunify Platform uses ASP.NET Core Identity for user authentication and authorization. This setup allows users to register, log in, and log out securely.
To register a new user, send a POST request to the /api/Account/register
endpoint with the following JSON payload:
{
"username": "your_username",
"password": "your_password",
"email": "[email protected]"
}
To log in, send a POST request to the /api/Account/login
endpoint with the following JSON payload:
{
"username": "your_username",
"password": "your_password"
}
To log out, send a POST request to the /api/Account/logout
endpoint. No payload is required for this request.
To get started with the Tunify Platform, follow these steps:
- Clone the repository.
- Set up the database connection string in the
appsettings.json
file. - Run the migrations to create and seed the database:
dotnet ef migrations add InitialCreate
dotnet ef database update
- Build and run the application:
dotnet run
- .NET 7
- Entity Framework Core
- SQL Server
This project is licensed under the MIT License.