From df6852bf7b47835a31dd0ffeb5cfddccbf70aeba Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Wed, 2 Nov 2022 22:39:46 +0100 Subject: Napravljeni modeli za File, Location, Post, PostReceive i PostSend --- Backend/Api/Api/Models/File.cs | 13 +++++++++ Backend/Api/Api/Models/Location.cs | 29 ++++++++++++++++++++ Backend/Api/Api/Models/Post.cs | 56 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 Backend/Api/Api/Models/File.cs create mode 100644 Backend/Api/Api/Models/Location.cs create mode 100644 Backend/Api/Api/Models/Post.cs (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Models/File.cs b/Backend/Api/Api/Models/File.cs new file mode 100644 index 0000000..c3a1e1b --- /dev/null +++ b/Backend/Api/Api/Models/File.cs @@ -0,0 +1,13 @@ +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson; + +namespace Api.Models +{ + public class File + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string _id { get; set; } + public String path { get; set; } + } +} diff --git a/Backend/Api/Api/Models/Location.cs b/Backend/Api/Api/Models/Location.cs new file mode 100644 index 0000000..5e723e4 --- /dev/null +++ b/Backend/Api/Api/Models/Location.cs @@ -0,0 +1,29 @@ +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson; + +namespace Api.Models +{ + public class Location + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public String _id { get; set; } + public String name { get; set; } + public String city { get; set; } + public String country { get; set; } + public String adress { get; set; } + public double latitude { get; set; } + public double longitude { get; set; } + public LocationType type { get; set; } + + } + + + public enum LocationType + { + Plaza, + Grad, + Zgrada, + Itd + } +} diff --git a/Backend/Api/Api/Models/Post.cs b/Backend/Api/Api/Models/Post.cs new file mode 100644 index 0000000..456fcea --- /dev/null +++ b/Backend/Api/Api/Models/Post.cs @@ -0,0 +1,56 @@ +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson; + +namespace Api.Models +{ + public class Post + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string _id { get; set; } + public string ownerId { get; set; } + public Location location { get; set; } + public string description { get; set; } + public List views { get; set; } + public List reports { get; set; } + public List ratings { get; set; } + public List comments { get; set; } + public List images { get; set; } + } + public class PostReceive + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string _id { get; set; } + public Location location { get; set; } + public string description { get; set; } + public List images { get; set; } + + + } + public class PostSend + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string _id { get; set; } + public string ownerId { get; set; } + public Location location { get; set; } + public string description { get; set; } + public int views { get; set; } + public float ratings { get; set; } + public List comments { get; set; } + public List images { get; set; } + } + public class Rating + { + public string userId { get; set; } + public int rating { get; set; } + } + public class Comment + { + public string userId { get; set; } + public string comment { get; set; } + public Comment parent { get; set; } + public DateTime timestamp { get; set; } + } +} -- cgit v1.2.3 From dbb8e2ed722c71916664c9a0a9bd19cc5f5ff1f1 Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Thu, 3 Nov 2022 18:03:51 +0100 Subject: Back verification pages,pass reset, code cleanup --- Backend/Api/Api/Assets/VerifyFailed.html | 13 ++++++ Backend/Api/Api/Assets/VerifySuccess.html | 14 ++++++ Backend/Api/Api/Assets/logotima.png | Bin 0 -> 377184 bytes Backend/Api/Api/Controllers/AuthController.cs | 52 +++++++++++++++++---- Backend/Api/Api/Interfaces/IJwtService.cs | 3 +- Backend/Api/Api/Interfaces/IUserService.cs | 6 ++- Backend/Api/Api/Program.cs | 5 +- Backend/Api/Api/Services/JwtService.cs | 34 ++------------ Backend/Api/Api/Services/UserService.cs | 64 ++++++++++++++++++++++---- Backend/Api/Api/appsettings.json | 14 ++++-- 10 files changed, 145 insertions(+), 60 deletions(-) create mode 100644 Backend/Api/Api/Assets/VerifyFailed.html create mode 100644 Backend/Api/Api/Assets/VerifySuccess.html create mode 100644 Backend/Api/Api/Assets/logotima.png (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Assets/VerifyFailed.html b/Backend/Api/Api/Assets/VerifyFailed.html new file mode 100644 index 0000000..f1e41e4 --- /dev/null +++ b/Backend/Api/Api/Assets/VerifyFailed.html @@ -0,0 +1,13 @@ + + + + + Verification Failed + + +
+ +

Token timed out

+
+ + \ No newline at end of file diff --git a/Backend/Api/Api/Assets/VerifySuccess.html b/Backend/Api/Api/Assets/VerifySuccess.html new file mode 100644 index 0000000..50c01d2 --- /dev/null +++ b/Backend/Api/Api/Assets/VerifySuccess.html @@ -0,0 +1,14 @@ + + + + + Verification Successful + + +
+ +

Welcome to BrzoDoLokacije

+

We are glad to have you, {{name}} as a member.

+
+ + \ No newline at end of file diff --git a/Backend/Api/Api/Assets/logotima.png b/Backend/Api/Api/Assets/logotima.png new file mode 100644 index 0000000..85137ac Binary files /dev/null and b/Backend/Api/Api/Assets/logotima.png differ diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs index d835d97..cbd5eb8 100644 --- a/Backend/Api/Api/Controllers/AuthController.cs +++ b/Backend/Api/Api/Controllers/AuthController.cs @@ -1,5 +1,6 @@ using Api.Interfaces; using Api.Models; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Api.Controllers @@ -8,12 +9,14 @@ namespace Api.Controllers public class AuthController : Controller { private readonly IUserService _userService; - public AuthController(IUserService userService) + private readonly IJwtService _jwtService; + public AuthController(IUserService userService,IJwtService jwtService) { _userService = userService; + _jwtService = jwtService; } - [HttpPost("register")] + [HttpPost("registerdeprecated")] public async Task> Register([FromBody] Register creds) { //this is beyond scuffed and will be cleaned up later, when users,login and controllers are made @@ -47,19 +50,26 @@ namespace Api.Controllers } return BadRequest("Pogresno uneti podaci"); } - [HttpPost("registeractual")] + [HttpPost("register")] public async Task> RegisterActual([FromBody] Register creds) { var msg = await _userService.Register(creds); - if (msg == "Email Exists") - return Forbid(msg); - if (msg == "Username Exists") - return Forbid(msg); - return Ok(msg); + switch (msg) + { + case "User Registered": + return Ok(msg); + default: + return BadRequest(msg); + } } [HttpPost("verify")] public async Task> VerifyEmail([FromBody] VerifyUser creds) { + var vrfchk = new Login(); + vrfchk.email = creds.email; + vrfchk.password = creds.password; + if (await _userService.CheckVerification(vrfchk)) + return Ok("User already verified"); var uspeh = await _userService.VerifyUser(creds); if (!uspeh) return BadRequest("Kod netacan ili istekao"); @@ -73,5 +83,31 @@ namespace Api.Controllers return BadRequest("Kod netacan ili istekao"); return Ok("Sifra uspesno resetovana"); } + [HttpPost("forgotpass")] + public async Task> ForgotPass([FromBody] JustMail justMail) + { + if (await _userService.ForgotPassword(justMail)) + return Ok("Email poslat"); + return BadRequest("Email nema registrovan nalog"); + } + [HttpGet("verifytoken/{token}")] + public async Task> VerifyEmailToken(string token) + { + var username =_jwtService.EmailTokenToClaim(token,"username"); + string html; + if (username == null) + { + html = await System.IO.File.ReadAllTextAsync(@"./Assets/VerifyFailed.html"); + return base.Content(html, "text/html"); + } + else + { + html = await System.IO.File.ReadAllTextAsync(@"./Assets/VerifySuccess.html"); + html = html.Replace("{{name}}", username); + + await _userService.VerifyFromToken(token); + return base.Content(html, "text/html"); + } + } } } diff --git a/Backend/Api/Api/Interfaces/IJwtService.cs b/Backend/Api/Api/Interfaces/IJwtService.cs index 6274bf9..8d0038f 100644 --- a/Backend/Api/Api/Interfaces/IJwtService.cs +++ b/Backend/Api/Api/Interfaces/IJwtService.cs @@ -7,7 +7,6 @@ namespace Api.Interfaces string GenToken(User user); string TokenToId(string token); public string GenEmailToken(User user); - public string EmailTokenToId(string token); - public string EmailTokenToKod(string token); + public string EmailTokenToClaim(string token,string claim); } } \ No newline at end of file diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 5205028..218c67a 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -17,10 +17,12 @@ namespace Api.Interfaces Task Register(Register register); Task VerifyUser(VerifyUser login); Task UserIdFromJwt(); - Task ResendVerifyKod(Login login); - Boolean SendEmailKod(User user); + Task ResendVerifyEmail(Login login); + Boolean SendEmailKod(User user,int msgid); Task ForgotPassword(JustMail jm); Task ResetPassword(ResetPass rp); + Task CheckVerification(Login login); + Task VerifyFromToken(string token); } } diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 4643937..6c96331 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -1,4 +1,3 @@ -using System.Text; using Api.Database; using Api.Interfaces; using Api.Services; @@ -6,6 +5,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using MongoDB.Driver; +using System.Text; var builder = WebApplication.CreateBuilder(args); @@ -30,7 +30,8 @@ builder.Services.AddHttpContextAccessor(); //Add Authentication builder.Services.AddAuthentication( - JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { + JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => + { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, diff --git a/Backend/Api/Api/Services/JwtService.cs b/Backend/Api/Api/Services/JwtService.cs index 9d928f7..fbf5724 100644 --- a/Backend/Api/Api/Services/JwtService.cs +++ b/Backend/Api/Api/Services/JwtService.cs @@ -72,7 +72,7 @@ namespace Api.Services return tokenHandler.WriteToken(token); } - public string EmailTokenToId(string token) + public string EmailTokenToClaim(string token,string claim) { if (token == null) return null; @@ -90,41 +90,13 @@ namespace Api.Services }, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; - var username = (jwtToken.Claims.First(x => x.Type == "username").Value.ToString()); - return username; + var result = (jwtToken.Claims.First(x => x.Type == claim).Value.ToString()); + return result; } catch { return null; } } - - public string EmailTokenToKod(string token) - { - if (token == null) - return null; - var tokenHandler = new JwtSecurityTokenHandler(); - var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:EmailToken").Value.ToString()); - try - { - tokenHandler.ValidateToken(token, new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(key), - ValidateIssuer = false, - ValidateAudience = false, - ClockSkew = TimeSpan.Zero - }, - out SecurityToken validatedToken); - var jwtToken = (JwtSecurityToken)validatedToken; - var kod = (jwtToken.Claims.First(x => x.Type == "kod").Value.ToString()); - return kod; - } - catch - { - return null; - } - } - } } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 3002f34..034c494 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -114,9 +114,16 @@ namespace Api.Services foreach(var usr in unverified) { //ako user nema validan emailtoken, a nije verifikovan prethodno, onda se brise iz baze - if (_jwtService.EmailTokenToId(usr.emailToken) == null) + if (_jwtService.EmailTokenToClaim(usr.emailToken,"id") == null) await _users.FindOneAndDeleteAsync(x => x._id == usr._id); } + foreach (var usr in unverified) + { + if (usr.email == register.email && _jwtService.EmailTokenToClaim(usr.emailToken,"id") != null) + return "Unverified Email Exists, check your inbox"; + if (usr.username == register.username && _jwtService.EmailTokenToClaim(usr.emailToken,"id") != null) + return "Unverified Username Exists, please select another"; + } } } @@ -133,7 +140,7 @@ namespace Api.Services user.emailToken = _jwtService.GenEmailToken(user); await _users.ReplaceOneAsync(x => x._id == user._id, user); - SendEmailKod(user); + SendEmailKod(user,1); return "User Registered"; } @@ -143,11 +150,12 @@ namespace Api.Services User user = await _users.FindAsync(x => x.email == login.email).Result.FirstOrDefaultAsync(); if (user != null && checkPassword(login.password, user.password)) { - var basekod = _jwtService.EmailTokenToKod(user.emailToken); + var basekod = _jwtService.EmailTokenToClaim(user.emailToken,"kod"); if (basekod != null) if (String.Compare(login.kod,basekod) == 0) { user.verified = true; + user.emailToken = ""; await _users.ReplaceOneAsync(x => x._id == user._id, user); return true; } @@ -188,33 +196,47 @@ namespace Api.Services return id; } - public async Task ResendVerifyKod(Login login) + public async Task ResendVerifyEmail(Login login) { User user = await _users.FindAsync(x => x.email == login.email).Result.FirstOrDefaultAsync(); if (user != null && checkPassword(login.password, user.password)) { user.emailToken = _jwtService.GenEmailToken(user); await _users.ReplaceOneAsync(x => x._id == user._id, user); - SendEmailKod(user); + SendEmailKod(user,1); return true; } return false; } - public Boolean SendEmailKod(User user) + + public Boolean SendEmailKod(User user,int msgid) //1 - email verification, 2 - password reset { MimeMessage message = new MimeMessage(); message.From.Add(new MailboxAddress("Tim Oddyssey", _configuration.GetSection("EmailCfg:Email").Value)); message.To.Add(MailboxAddress.Parse(user.email)); message.Subject = "Vas Oddyssey verifikacioni kod"; //think of something better yeah? - var kod = _jwtService.EmailTokenToKod(user.emailToken); + var kod = _jwtService.EmailTokenToClaim(user.emailToken,"kod"); if (kod == null) return false; var bodybuilder = new BodyBuilder(); - bodybuilder.HtmlBody = String.Format(@"

Verfikacioni kod:

"+kod+"


Kod traje 30 minuta

"); + switch(msgid){ + case 1: + //bodybuilder.HtmlBody = String.Format(@"

Verfikacioni kod:

" + kod + "


Kod traje 30 minuta

"); + bodybuilder.HtmlBody = String.Format(@"

Link za verifikaciju emaila:


" + + "
" + + "" + + "
" + + "

Link traje 30 minuta

"); + break; + case 2: + bodybuilder.HtmlBody = String.Format(@"

Verfikacioni kod:

" + kod + "


Kod traje 30 minuta

"); + break; + } + message.Body = bodybuilder.ToMessageBody(); SmtpClient client = new SmtpClient(); @@ -244,7 +266,7 @@ namespace Api.Services { user.emailToken = _jwtService.GenEmailToken(user); await _users.ReplaceOneAsync(x => x._id == user._id, user); - SendEmailKod(user); + SendEmailKod(user,2); return true; } @@ -256,16 +278,38 @@ namespace Api.Services User user = await _users.FindAsync(x => x.email == rp.email && x.verified == true).Result.FirstOrDefaultAsync(); if (user != null) { - var basekod = _jwtService.EmailTokenToKod(user.emailToken); + var basekod = _jwtService.EmailTokenToClaim(user.emailToken,"kod"); if (basekod != null) if (String.Compare(rp.kod, basekod) == 0) { user.password = hashPassword(rp.newpass); + user.emailToken = ""; await _users.ReplaceOneAsync(x => x._id == user._id, user); return true; } } return false; } + public async Task CheckVerification(Login login) + { + User user = await _users.FindAsync(x => x.email == login.email).Result.FirstOrDefaultAsync(); + if (user != null && checkPassword(login.password, user.password) && user.verified == true) + { + return true; + } + return false; + } + public async Task VerifyFromToken(string token) + { + User user = await _users.FindAsync(x => x.emailToken == token).Result.FirstOrDefaultAsync(); + if(user != null) + { + user.verified = true; + user.emailToken = ""; + await _users.ReplaceOneAsync(x => x._id == user._id, user); + return true; + } + return false; + } } } diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index 48086f3..74cfa27 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -18,9 +18,13 @@ "UserCollectionName": "users" }, - "EmailCfg": { - "Email": "oddyssey.brzodolokacije@gmail.com", - "SmtpServer": "smtp.gmail.com", - "Password": "nrokhfcwahfbqnpp" //msbs#556 - } + "EmailCfg": { + "Email": "oddyssey.brzodolokacije@gmail.com", + "SmtpServer": "smtp.gmail.com", + "Password": "nrokhfcwahfbqnpp" //msbs#556 + }, + "URLs": { + "localhost": "http://localhost:5279/", + "actual":"add url when back put onto server" + } } -- cgit v1.2.3 From 1513d1b5eba692d50c733e7c682c1e31d515158a Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 3 Nov 2022 20:06:46 +0100 Subject: Napravljeni kosturi za PostController i PostServices. Dodata nova kolekcija u bazi. --- Backend/Api/Api/Controllers/PostController.cs | 18 ++++++++++++++++++ Backend/Api/Api/Database/DatabaseConnection.cs | 1 + Backend/Api/Api/Interfaces/IDatabaseConnection.cs | 1 + Backend/Api/Api/Interfaces/IPostService.cs | 9 +++++++++ Backend/Api/Api/Program.cs | 1 + Backend/Api/Api/Services/PostService.cs | 22 ++++++++++++++++++++++ Backend/Api/Api/appsettings.json | 3 ++- 7 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 Backend/Api/Api/Controllers/PostController.cs create mode 100644 Backend/Api/Api/Interfaces/IPostService.cs create mode 100644 Backend/Api/Api/Services/PostService.cs (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs new file mode 100644 index 0000000..4bac0e5 --- /dev/null +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -0,0 +1,18 @@ +using Api.Interfaces; +using Microsoft.AspNetCore.Mvc; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace Api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class PostController : ControllerBase + { + private readonly IPostService _postService; + public PostController(IPostService postService) + { + _postService = postService; + } + } +} diff --git a/Backend/Api/Api/Database/DatabaseConnection.cs b/Backend/Api/Api/Database/DatabaseConnection.cs index 65f4f52..c2fea05 100644 --- a/Backend/Api/Api/Database/DatabaseConnection.cs +++ b/Backend/Api/Api/Database/DatabaseConnection.cs @@ -7,5 +7,6 @@ namespace Api.Database public string ConnectionString { get; set; } = String.Empty; public string DatabaseName { get; set; } = String.Empty; public string UserCollectionName { get; set; } = String.Empty; + public string PostCollectionName { get; set; } = String.Empty; } } diff --git a/Backend/Api/Api/Interfaces/IDatabaseConnection.cs b/Backend/Api/Api/Interfaces/IDatabaseConnection.cs index 8938127..e3fc60c 100644 --- a/Backend/Api/Api/Interfaces/IDatabaseConnection.cs +++ b/Backend/Api/Api/Interfaces/IDatabaseConnection.cs @@ -5,5 +5,6 @@ string ConnectionString { get; set; } string DatabaseName { get; set; } string UserCollectionName { get; set; } + string PostCollectionName { get; set; } } } diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs new file mode 100644 index 0000000..6c34e69 --- /dev/null +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -0,0 +1,9 @@ +using Api.Models; + +namespace Api.Interfaces +{ + public interface IPostService + { + PostSend addPost(PostReceive post); + } +} \ No newline at end of file diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 6c96331..9b80f3c 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -22,6 +22,7 @@ builder.Services.AddSingleton(s => builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs new file mode 100644 index 0000000..2a5e789 --- /dev/null +++ b/Backend/Api/Api/Services/PostService.cs @@ -0,0 +1,22 @@ +using Api.Interfaces; +using Api.Models; +using MongoDB.Driver; + +namespace Api.Services +{ + public class PostService : IPostService + { + private readonly MongoClient _client; + private readonly IMongoCollection _posts; + public PostService(IDatabaseConnection settings, IMongoClient mongoClient) + { + var database = mongoClient.GetDatabase(settings.DatabaseName); + _posts = database.GetCollection(settings.PostCollectionName); + } + + public PostSend addPost(PostReceive post) + { + return null; + } + } +} diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index 74cfa27..2be2426 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -15,7 +15,8 @@ "ConnectionString": "mongodb://127.0.0.1:27017/", "DatabaseName": "Odyssey", - "UserCollectionName": "users" + "UserCollectionName": "users", + "PostCollectionName": "posts" }, "EmailCfg": { -- cgit v1.2.3 From 718a4a30cad0205e00b7d4acdee58c1b7f8cdb08 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 3 Nov 2022 20:32:42 +0100 Subject: Napravljene metode za dodavanje i vracanje objava u servisu i kontroleru. --- Backend/Api/Api/Controllers/PostController.cs | 38 +++++++++++++++++++++ Backend/Api/Api/Interfaces/IPostService.cs | 5 ++- Backend/Api/Api/Services/PostService.cs | 49 ++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 5 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 4bac0e5..8db68a8 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -1,4 +1,7 @@ using Api.Interfaces; +using Api.Models; +using Api.Services; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 @@ -14,5 +17,40 @@ namespace Api.Controllers { _postService = postService; } + + [HttpPost("add")] + [Authorize(Roles ="User")] + public async Task> addPost([FromBody] PostReceive post) + { + var res = await _postService.addPost(post); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } + [HttpGet] + [Authorize(Roles = "User")] + public async Task>> getAllPosts() + { + var res = await _postService.getAllPosts(); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } + [HttpGet("posts /{id}")] + [Authorize(Roles = "User")] + public async Task> getPostByid(string id) + { + var res = await _postService.getPostById(id); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } + } } diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 6c34e69..31e80cd 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -4,6 +4,9 @@ namespace Api.Interfaces { public interface IPostService { - PostSend addPost(PostReceive post); + Task addPost(PostReceive post); + Task> getAllPosts(); + Task getPostById(string id); + PostSend postToPostSend(Post post); } } \ No newline at end of file diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 2a5e789..49c92cb 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -1,4 +1,5 @@ -using Api.Interfaces; +using System.Security.Claims; +using Api.Interfaces; using Api.Models; using MongoDB.Driver; @@ -8,15 +9,55 @@ namespace Api.Services { private readonly MongoClient _client; private readonly IMongoCollection _posts; - public PostService(IDatabaseConnection settings, IMongoClient mongoClient) + private readonly IHttpContextAccessor _httpContext; + public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext) { var database = mongoClient.GetDatabase(settings.DatabaseName); _posts = database.GetCollection(settings.PostCollectionName); + _httpContext = httpContext; } - public PostSend addPost(PostReceive post) + public async Task addPost(PostReceive post) { - return null; + Post p = new Post(); + p._id = ""; + p.ownerId = _httpContext.HttpContext.User.FindFirstValue("id"); + p.location = post.location; + p.description = post.description; + p.views = new List(); + p.reports = new List(); + p.ratings = new List(); + p.comments = new List(); + //add file + //add to database + return postToPostSend(p); + + } + public PostSend postToPostSend(Post post) + { + PostSend p = new PostSend(); + //Convert post to post send (TODO) + p._id = post._id; + return p; + } + + public async Task> getAllPosts() + { + List posts = await _posts.Find(_ => true).ToListAsync(); + List temp = new List(); + foreach (var post in posts) + { + temp.Add(postToPostSend(post)); + } + return temp; + } + + public async Task getPostById(string id) + { + Post p = await _posts.Find(post => post._id == id).FirstOrDefaultAsync(); + return postToPostSend(p); + } + //(TODO) ADD Delete and update } } -- cgit v1.2.3 From e39a826718441946a48e7e8c28a84933c2882d8a Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 3 Nov 2022 21:23:05 +0100 Subject: Napravljena kolekcija za fajlove. Omoguceno uplodovanje fajlova kada se dodaje objava. Dodat role za User-a u jwt-ju. --- Backend/Api/Api/.gitignore | 1 + Backend/Api/Api/Api.csproj | 4 ++ Backend/Api/Api/Controllers/PostController.cs | 2 +- Backend/Api/Api/Database/DatabaseConnection.cs | 1 + Backend/Api/Api/Interfaces/IDatabaseConnection.cs | 1 + Backend/Api/Api/Models/Post.cs | 5 ++- Backend/Api/Api/Program.cs | 5 ++- Backend/Api/Api/Services/FileService.cs | 28 +++++++++++++ Backend/Api/Api/Services/IFileService.cs | 8 ++++ Backend/Api/Api/Services/JwtService.cs | 3 +- Backend/Api/Api/Services/PostService.cs | 49 +++++++++++++++++++++-- Backend/Api/Api/appsettings.json | 13 +++--- 12 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 Backend/Api/Api/.gitignore create mode 100644 Backend/Api/Api/Services/FileService.cs create mode 100644 Backend/Api/Api/Services/IFileService.cs (limited to 'Backend/Api') diff --git a/Backend/Api/Api/.gitignore b/Backend/Api/Api/.gitignore new file mode 100644 index 0000000..f4b4ba8 --- /dev/null +++ b/Backend/Api/Api/.gitignore @@ -0,0 +1 @@ +Files/* \ No newline at end of file diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index 93e31b7..b09c2fd 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 8db68a8..31dbeef 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -20,7 +20,7 @@ namespace Api.Controllers [HttpPost("add")] [Authorize(Roles ="User")] - public async Task> addPost([FromBody] PostReceive post) + public async Task> addPost([FromForm]PostReceive post) { var res = await _postService.addPost(post); if (res != null) diff --git a/Backend/Api/Api/Database/DatabaseConnection.cs b/Backend/Api/Api/Database/DatabaseConnection.cs index c2fea05..24b2b08 100644 --- a/Backend/Api/Api/Database/DatabaseConnection.cs +++ b/Backend/Api/Api/Database/DatabaseConnection.cs @@ -8,5 +8,6 @@ namespace Api.Database public string DatabaseName { get; set; } = String.Empty; public string UserCollectionName { get; set; } = String.Empty; public string PostCollectionName { get; set; } = String.Empty; + public string FileCollectionName { get; set; } = String.Empty; } } diff --git a/Backend/Api/Api/Interfaces/IDatabaseConnection.cs b/Backend/Api/Api/Interfaces/IDatabaseConnection.cs index e3fc60c..744461b 100644 --- a/Backend/Api/Api/Interfaces/IDatabaseConnection.cs +++ b/Backend/Api/Api/Interfaces/IDatabaseConnection.cs @@ -6,5 +6,6 @@ string DatabaseName { get; set; } string UserCollectionName { get; set; } string PostCollectionName { get; set; } + string FileCollectionName { get; set; } } } diff --git a/Backend/Api/Api/Models/Post.cs b/Backend/Api/Api/Models/Post.cs index 456fcea..ee84e0f 100644 --- a/Backend/Api/Api/Models/Post.cs +++ b/Backend/Api/Api/Models/Post.cs @@ -1,5 +1,6 @@ using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson; +using System.ComponentModel.DataAnnotations; namespace Api.Models { @@ -9,7 +10,7 @@ namespace Api.Models [BsonRepresentation(BsonType.ObjectId)] public string _id { get; set; } public string ownerId { get; set; } - public Location location { get; set; } + public string locationId { get; set; } public string description { get; set; } public List views { get; set; } public List reports { get; set; } @@ -22,7 +23,7 @@ namespace Api.Models [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string _id { get; set; } - public Location location { get; set; } + public string locationId { get; set; } public string description { get; set; } public List images { get; set; } diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 9b80f3c..8dee088 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -23,6 +23,7 @@ builder.Services.AddSingleton(s => builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); @@ -70,11 +71,11 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } -app.UseAuthorization(); + //Add Authentication app.UseAuthentication(); - +app.UseAuthorization(); app.MapControllers(); app.Run(); diff --git a/Backend/Api/Api/Services/FileService.cs b/Backend/Api/Api/Services/FileService.cs new file mode 100644 index 0000000..1937c10 --- /dev/null +++ b/Backend/Api/Api/Services/FileService.cs @@ -0,0 +1,28 @@ +using Api.Interfaces; +using Api.Models; +using MongoDB.Driver; +using File = Api.Models.File; + +namespace Api.Services +{ + public class FileService : IFileService + { + private readonly MongoClient _client; + private readonly IMongoCollection _files; + private readonly IHttpContextAccessor _httpContext; + public FileService(IDatabaseConnection settings, IMongoClient mongoClient) + { + var database = mongoClient.GetDatabase(settings.DatabaseName); + _files = database.GetCollection(settings.FileCollectionName); + } + public async Task add(File file) + { + await _files.InsertOneAsync(file); + return file; + } + public async Task getById(string id) + { + return await _files.Find(file => file._id == id).FirstOrDefaultAsync(); + } + } +} diff --git a/Backend/Api/Api/Services/IFileService.cs b/Backend/Api/Api/Services/IFileService.cs new file mode 100644 index 0000000..269e202 --- /dev/null +++ b/Backend/Api/Api/Services/IFileService.cs @@ -0,0 +1,8 @@ +namespace Api.Services +{ + public interface IFileService + { + Task add(Models.File file); + Task getById(string id); + } +} \ No newline at end of file diff --git a/Backend/Api/Api/Services/JwtService.cs b/Backend/Api/Api/Services/JwtService.cs index fbf5724..c199484 100644 --- a/Backend/Api/Api/Services/JwtService.cs +++ b/Backend/Api/Api/Services/JwtService.cs @@ -24,7 +24,8 @@ namespace Api.Services var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:JwtToken").Value); var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("id", user._id) }), + Subject = new ClaimsIdentity(new[] { new Claim("id", user._id), + new Claim("role","User")}), Expires = DateTime.UtcNow.AddDays(7), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 49c92cb..2f29366 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -10,11 +10,13 @@ namespace Api.Services private readonly MongoClient _client; private readonly IMongoCollection _posts; private readonly IHttpContextAccessor _httpContext; - public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext) + private readonly IFileService _fileService; + public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext, IFileService fileService) { var database = mongoClient.GetDatabase(settings.DatabaseName); _posts = database.GetCollection(settings.PostCollectionName); _httpContext = httpContext; + _fileService = fileService; } public async Task addPost(PostReceive post) @@ -22,14 +24,53 @@ namespace Api.Services Post p = new Post(); p._id = ""; p.ownerId = _httpContext.HttpContext.User.FindFirstValue("id"); - p.location = post.location; + + p.locationId = post.locationId; p.description = post.description; p.views = new List(); p.reports = new List(); p.ratings = new List(); p.comments = new List(); - //add file - //add to database + p.images = new List(); + + var folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Files", p.ownerId); + if (!Directory.Exists(folderPath)) + { + Directory.CreateDirectory(folderPath); + } + + foreach (var image in post.images) + { + var filename = image.FileName; + var ext=Path.GetExtension(filename).ToLowerInvariant(); + var name = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); + var fullPath=Path.Combine(folderPath, name); + int i = 0; + while (System.IO.File.Exists(fullPath)) + { + i++; + fullPath=Path.Combine(folderPath, name+i.ToString()+ext); + } + using(var stream=new FileStream(fullPath, FileMode.Create)) + { + await image.CopyToAsync(stream); + } + var f = new Models.File(); + f.path = fullPath; + f._id = ""; + f=await _fileService.add(f); + p.images.Add(f); + + } + await _posts.InsertOneAsync(p); + + + + + + + + return postToPostSend(p); } diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index 2be2426..d506b33 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -11,14 +11,15 @@ } }, "AllowedHosts": "*", - "DatabaseSettings": { + "DatabaseSettings": { - "ConnectionString": "mongodb://127.0.0.1:27017/", - "DatabaseName": "Odyssey", - "UserCollectionName": "users", - "PostCollectionName": "posts" + "ConnectionString": "mongodb://127.0.0.1:27017/", + "DatabaseName": "Odyssey", + "UserCollectionName": "users", + "PostCollectionName": "posts", + "FileCollectionName": "files" - }, + }, "EmailCfg": { "Email": "oddyssey.brzodolokacije@gmail.com", "SmtpServer": "smtp.gmail.com", -- cgit v1.2.3 From 43b5ce5b1c2a0976142a41e77f7caeb378dfd5ba Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 3 Nov 2022 21:36:59 +0100 Subject: Dodata kolekcija za lokacije. Napravljen kontroler i servis za lokacije. Todo(google maps api). --- Backend/Api/Api/Controllers/LocationController.cs | 54 +++++++++++++++++++++++ Backend/Api/Api/Database/DatabaseConnection.cs | 1 + Backend/Api/Api/Interfaces/IDatabaseConnection.cs | 1 + Backend/Api/Api/Interfaces/IFileService.cs | 8 ++++ Backend/Api/Api/Interfaces/ILocationService.cs | 11 +++++ Backend/Api/Api/Program.cs | 1 + Backend/Api/Api/Services/IFileService.cs | 8 ---- Backend/Api/Api/Services/LocationService.cs | 32 ++++++++++++++ Backend/Api/Api/appsettings.json | 3 +- 9 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 Backend/Api/Api/Controllers/LocationController.cs create mode 100644 Backend/Api/Api/Interfaces/IFileService.cs create mode 100644 Backend/Api/Api/Interfaces/ILocationService.cs delete mode 100644 Backend/Api/Api/Services/IFileService.cs create mode 100644 Backend/Api/Api/Services/LocationService.cs (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/LocationController.cs b/Backend/Api/Api/Controllers/LocationController.cs new file mode 100644 index 0000000..bb0b0ab --- /dev/null +++ b/Backend/Api/Api/Controllers/LocationController.cs @@ -0,0 +1,54 @@ +using Api.Interfaces; +using Api.Models; +using Microsoft.AspNetCore.Authorization; +using System.Data; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class LocationController : ControllerBase + { + private readonly ILocationService _locationService; + public LocationController(ILocationService locationService) + { + _locationService = locationService; + } + + [HttpPost("add")] + [Authorize(Roles = "User")] + public async Task> addPost([FromBody] Location loc) + { + var res = await _locationService.add(loc); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } + [HttpGet] + [Authorize(Roles = "User")] + public async Task>> getAllPosts() + { + var res = await _locationService.getAllLocation(); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } + [HttpGet("loc /{id}")] + [Authorize(Roles = "User")] + public async Task> getLocationByid(string id) + { + var res = await _locationService.getById(id); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } + } +} diff --git a/Backend/Api/Api/Database/DatabaseConnection.cs b/Backend/Api/Api/Database/DatabaseConnection.cs index 24b2b08..f26b88e 100644 --- a/Backend/Api/Api/Database/DatabaseConnection.cs +++ b/Backend/Api/Api/Database/DatabaseConnection.cs @@ -9,5 +9,6 @@ namespace Api.Database public string UserCollectionName { get; set; } = String.Empty; public string PostCollectionName { get; set; } = String.Empty; public string FileCollectionName { get; set; } = String.Empty; + public string LocationCollectionName { get; set; } = String.Empty; } } diff --git a/Backend/Api/Api/Interfaces/IDatabaseConnection.cs b/Backend/Api/Api/Interfaces/IDatabaseConnection.cs index 744461b..17b5262 100644 --- a/Backend/Api/Api/Interfaces/IDatabaseConnection.cs +++ b/Backend/Api/Api/Interfaces/IDatabaseConnection.cs @@ -7,5 +7,6 @@ string UserCollectionName { get; set; } string PostCollectionName { get; set; } string FileCollectionName { get; set; } + string LocationCollectionName { get; set; } } } diff --git a/Backend/Api/Api/Interfaces/IFileService.cs b/Backend/Api/Api/Interfaces/IFileService.cs new file mode 100644 index 0000000..e736305 --- /dev/null +++ b/Backend/Api/Api/Interfaces/IFileService.cs @@ -0,0 +1,8 @@ +namespace Api.Interfaces +{ + public interface IFileService + { + Task add(Models.File file); + Task getById(string id); + } +} \ No newline at end of file diff --git a/Backend/Api/Api/Interfaces/ILocationService.cs b/Backend/Api/Api/Interfaces/ILocationService.cs new file mode 100644 index 0000000..16e00a0 --- /dev/null +++ b/Backend/Api/Api/Interfaces/ILocationService.cs @@ -0,0 +1,11 @@ +using Api.Models; + +namespace Api.Interfaces +{ + public interface ILocationService + { + Task add(Location loc); + Task getById(string id); + Task> getAllLocation(); + } +} \ No newline at end of file diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 8dee088..16b0241 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -24,6 +24,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); diff --git a/Backend/Api/Api/Services/IFileService.cs b/Backend/Api/Api/Services/IFileService.cs deleted file mode 100644 index 269e202..0000000 --- a/Backend/Api/Api/Services/IFileService.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Api.Services -{ - public interface IFileService - { - Task add(Models.File file); - Task getById(string id); - } -} \ No newline at end of file diff --git a/Backend/Api/Api/Services/LocationService.cs b/Backend/Api/Api/Services/LocationService.cs new file mode 100644 index 0000000..b44f983 --- /dev/null +++ b/Backend/Api/Api/Services/LocationService.cs @@ -0,0 +1,32 @@ +using Api.Interfaces; +using Api.Models; +using MongoDB.Driver; + +namespace Api.Services +{ + public class LocationService : ILocationService + { + private readonly MongoClient _client; + private readonly IMongoCollection _locations; + private readonly IHttpContextAccessor _httpContext; + public LocationService(IDatabaseConnection settings, IMongoClient mongoClient) + { + var database = mongoClient.GetDatabase(settings.DatabaseName); + _locations = database.GetCollection(settings.FileCollectionName); + } + public async Task add(Location loc) + { + //TODO GOOGLE MAPS API CALL FOR info + await _locations.InsertOneAsync(loc); + return loc; + } + public async Task getById(string id) + { + return await _locations.Find(loc => loc._id == id).FirstOrDefaultAsync(); + } + public async Task> getAllLocation() + { + return await _locations.Find(_=>true).ToListAsync(); + } + } +} diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index d506b33..b7f25b2 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -17,7 +17,8 @@ "DatabaseName": "Odyssey", "UserCollectionName": "users", "PostCollectionName": "posts", - "FileCollectionName": "files" + "FileCollectionName": "files", + "LocationCollectionname": "locations" }, "EmailCfg": { -- cgit v1.2.3 From 759414e3138e02a540cbb74a9675d6dec6362004 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 3 Nov 2022 21:39:34 +0100 Subject: Typo fix. --- Backend/Api/Api/Services/LocationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Services/LocationService.cs b/Backend/Api/Api/Services/LocationService.cs index b44f983..629c2a7 100644 --- a/Backend/Api/Api/Services/LocationService.cs +++ b/Backend/Api/Api/Services/LocationService.cs @@ -12,7 +12,7 @@ namespace Api.Services public LocationService(IDatabaseConnection settings, IMongoClient mongoClient) { var database = mongoClient.GetDatabase(settings.DatabaseName); - _locations = database.GetCollection(settings.FileCollectionName); + _locations = database.GetCollection(settings.LocationCollectionName); } public async Task add(Location loc) { -- cgit v1.2.3 From 3ba0c0557213a9444211b58a6a65ff4a2af09ea3 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 3 Nov 2022 21:54:29 +0100 Subject: fixed typo. --- Backend/Api/Api/Models/Location.cs | 2 +- Client/BrzoDoLokacije/app/src/main/res/layout/post_preview.xml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Models/Location.cs b/Backend/Api/Api/Models/Location.cs index 5e723e4..8cc4377 100644 --- a/Backend/Api/Api/Models/Location.cs +++ b/Backend/Api/Api/Models/Location.cs @@ -11,7 +11,7 @@ namespace Api.Models public String name { get; set; } public String city { get; set; } public String country { get; set; } - public String adress { get; set; } + public String address { get; set; } public double latitude { get; set; } public double longitude { get; set; } public LocationType type { get; set; } diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/post_preview.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/post_preview.xml index abbd549..48a3289 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/post_preview.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/post_preview.xml @@ -4,7 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_padding="5dp" android:layout_margin="0dp" android:background="@drawable/rounded_picture_background" android:clipToOutline="true" @@ -14,7 +13,6 @@ android:id="@+id/imageView8" android:layout_width="match_parent" android:layout_height="330dp" - android:layout_padding="0dp" android:outlineProvider="background" android:src="@drawable/b1" app:layout_constraintBottom_toBottomOf="parent" -- cgit v1.2.3 From bbd8255288db31f4473b000aab2dfbe3d7fb0f38 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Fri, 4 Nov 2022 23:33:50 +0100 Subject: Napravljen controller za refreshJwt-a na backu. --- Backend/Api/Api/Controllers/AuthController.cs | 11 +++++++++++ Backend/Api/Api/Interfaces/IUserService.cs | 2 +- Backend/Api/Api/Services/UserService.cs | 4 ++-- 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs index cbd5eb8..abb7adc 100644 --- a/Backend/Api/Api/Controllers/AuthController.cs +++ b/Backend/Api/Api/Controllers/AuthController.cs @@ -37,6 +37,17 @@ namespace Api.Controllers return Ok(); } + [HttpPost("refreshJwt")] + [Authorize(Roles ="User")] + public async Task> refreshJwt() + { + var jwt = await _userService.RenewToken(); + if (jwt != null) + { + return Ok(jwt); + } + return BadRequest("Pogresno uneti podaci"); + } [HttpPost("login")] public async Task> Login([FromBody] Login creds) { diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 218c67a..db2eac1 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -12,7 +12,7 @@ namespace Api.Interfaces Task deleteUser(String email); Task getUserById(string id); - Task RenewToken(string existingToken); + Task RenewToken(); Task Login(Login login); Task Register(Register register); Task VerifyUser(VerifyUser login); diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 034c494..5fd61f6 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -163,9 +163,9 @@ namespace Api.Services return false; } - public async Task RenewToken(string existingToken) + public async Task RenewToken() { - var id = _jwtService.TokenToId(existingToken); + var id = await UserIdFromJwt(); if (id == null) return null; var user = await getUserById(id); -- cgit v1.2.3 From bf2b7accb869db760ee04c2f33f93f08164b8993 Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Sat, 5 Nov 2022 14:51:17 +0100 Subject: reset sifre na app-u --- Backend/Api/Api/Services/PostService.cs | 10 +--- .../Activities/ActivityForgottenPassword.kt | 56 ++++++++++++++++++++-- .../Activities/ActivityForgottenPasswordVerify.kt | 56 ++++++++++++++++++++-- .../example/brzodolokacije/Interfaces/IAuthApi.kt | 7 +++ .../brzodolokacije/Models/Auth/ResetPass.kt | 4 ++ 5 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ResetPass.kt (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 2f29366..0a12f39 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -23,7 +23,7 @@ namespace Api.Services { Post p = new Post(); p._id = ""; - p.ownerId = _httpContext.HttpContext.User.FindFirstValue("id"); + p.ownerId = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); p.locationId = post.locationId; p.description = post.description; @@ -63,14 +63,6 @@ namespace Api.Services } await _posts.InsertOneAsync(p); - - - - - - - - return postToPostSend(p); } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPassword.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPassword.kt index e7c9836..b0b7f5e 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPassword.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPassword.kt @@ -1,27 +1,73 @@ package com.example.brzodolokacije.Activities import android.content.Intent +import android.graphics.Color import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.util.Log import android.view.View import android.widget.Button +import android.widget.EditText import android.widget.Toast +import com.example.brzodolokacije.Models.Auth.JustMail +import com.example.brzodolokacije.Models.Auth.Login import com.example.brzodolokacije.R +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import okhttp3.ResponseBody +import retrofit2.Call +import retrofit2.Response class ActivityForgottenPassword : AppCompatActivity() { private lateinit var sendCode: Button + private lateinit var email: EditText + private lateinit var emailString:String + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_forgotten_password) sendCode=findViewById(R.id.forgottenPasswordSendCode) as Button - + email=findViewById(R.id.editTextTextPersonName) as EditText sendCode.setOnClickListener{ - intent= Intent(this, ActivityForgottenPasswordVerify::class.java) - startActivity(intent) - } + emailString=email.text.toString().trim() - } + if(!emailString.isEmpty() && checkEmail(emailString)==true) { + + var emailData= JustMail(emailString) + val authApi= RetrofitHelper.getInstance() + val request=authApi.forgotpass(emailData) + val cont=this + request.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + Log.d("main",response.code().toString()) + Log.d("main",response.body().toString()) + if(response.code()==200){ + val intent = Intent(cont, ActivityForgottenPasswordVerify::class.java) + intent.putExtra("email", emailString) + startActivity(intent) + } + } + override fun onFailure(call: Call, t: Throwable) { + } + }) + } + } + } + //from fragment login + fun checkEmail(emailString:String):Boolean{ + val emailRegex = "^[A-Za-z](.*)([@]{1})(.{1,})(\\.)(.{1,})" + if(!(emailRegex.toRegex().matches(emailString))){ + Toast.makeText( + this, "Email adresa nije validna, pokušajte ponovo", Toast.LENGTH_LONG + ).show(); + email.setHintTextColor(Color.RED) + return false + } + else{ + return true + } + } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPasswordVerify.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPasswordVerify.kt index 6533237..a1db97f 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPasswordVerify.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityForgottenPasswordVerify.kt @@ -5,24 +5,72 @@ import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.Button +import android.widget.EditText import android.widget.Toast import com.example.brzodolokacije.MainActivity +import com.example.brzodolokacije.Models.Auth.Login +import com.example.brzodolokacije.Models.Auth.ResetPass import com.example.brzodolokacije.R +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import okhttp3.ResponseBody +import retrofit2.Call +import retrofit2.Response class ActivityForgottenPasswordVerify : AppCompatActivity() { private lateinit var changePassword: Button + private lateinit var pw:EditText + private lateinit var pwchk:EditText + private lateinit var kod:EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_forgotten_password_verify) + kod=findViewById(R.id.editTextTextPersonName) as EditText + pw=findViewById(R.id.editTextoldPassword) as EditText + pwchk =findViewById(R.id.editTextTextPassword) as EditText changePassword=findViewById(R.id.btnChangePassword) as Button changePassword.setOnClickListener{ + + var email =intent.getStringExtra("email") + var pwstr=pw.text.toString().trim() + var pwchkstr=pwchk.text.toString().trim() + var kodstr=kod.text.toString().trim() + + if(!kodstr.isEmpty() && checkPassword(pwstr,pwchkstr)){ + var resetData= ResetPass(email!!,kodstr,pwstr) + val authApi= RetrofitHelper.getInstance() + val request=authApi.resetpass(resetData) + val cont=this + request.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.code()==200){ + intent = Intent(cont, ActivityLoginRegister::class.java) + startActivity(intent) + } + } + override fun onFailure(call: Call, t: Throwable) { + } + }) + } + } + } + + //from fragment login + fun checkPassword(passwordString:String,passwordConfirm:String):Boolean{ + + if(passwordString.length<6){ Toast.makeText( - this, "Lozinka je uspešno promenjena.", Toast.LENGTH_LONG + this, "Lozinke su prekratke", Toast.LENGTH_LONG ).show(); - - intent= Intent(this, ActivityLoginRegister::class.java) - startActivity(intent) + return false + } + if(!passwordString.equals(passwordConfirm)){ + Toast.makeText( + this, "Lozinke su se ne poklapaju", Toast.LENGTH_LONG + ).show(); + return false } + return true } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IAuthApi.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IAuthApi.kt index 57e7e82..25f18a3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IAuthApi.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IAuthApi.kt @@ -1,7 +1,9 @@ package com.example.brzodolokacije.Interfaces +import com.example.brzodolokacije.Models.Auth.JustMail import com.example.brzodolokacije.Models.Auth.Login import com.example.brzodolokacije.Models.Auth.Register +import com.example.brzodolokacije.Models.Auth.ResetPass import com.example.brzodolokacije.Models.Post import okhttp3.ResponseBody import retrofit2.Call @@ -16,6 +18,11 @@ interface IAuthApi { fun register(@Body obj:Register):Call @POST("/api/auth/refreshJwt") fun refreshJwt(@Header("Authorization") authHeader:String): Call + @POST("/api/auth/forgotpass") + fun forgotpass(@Body obj:JustMail):Call + @POST("/api/auth/resetpass") + fun resetpass(@Body obj:ResetPass):Call + //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ResetPass.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ResetPass.kt new file mode 100644 index 0000000..945c8d1 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ResetPass.kt @@ -0,0 +1,4 @@ +package com.example.brzodolokacije.Models.Auth + +data class ResetPass(var email:String,var kod:String,var newpass:String) +data class JustMail(var email:String) \ No newline at end of file -- cgit v1.2.3 From f8b5a5eed843cdd0e94f96be072043f47c5db956 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sat, 5 Nov 2022 15:18:18 +0100 Subject: Kada se dodaje lokacija omoguceno da se koristi MapQuest geocoder da se nadju kordinate tog mesta i da se upisu u lokaciju. --- Backend/Api/Api/Api.csproj | 3 +++ Backend/Api/Api/Services/LocationService.cs | 18 ++++++++++++++++-- Backend/Api/Api/appsettings.json | 19 ++++++++++--------- 3 files changed, 29 insertions(+), 11 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index b09c2fd..80898fd 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -7,6 +7,9 @@ + + + diff --git a/Backend/Api/Api/Services/LocationService.cs b/Backend/Api/Api/Services/LocationService.cs index 629c2a7..292fc0e 100644 --- a/Backend/Api/Api/Services/LocationService.cs +++ b/Backend/Api/Api/Services/LocationService.cs @@ -1,6 +1,11 @@ using Api.Interfaces; using Api.Models; +using Geocoding; +using Geocoding.Google; +using Geocoding.MapQuest; using MongoDB.Driver; +using ZstdSharp.Unsafe; +using Location = Api.Models.Location; namespace Api.Services { @@ -9,15 +14,24 @@ namespace Api.Services private readonly MongoClient _client; private readonly IMongoCollection _locations; private readonly IHttpContextAccessor _httpContext; - public LocationService(IDatabaseConnection settings, IMongoClient mongoClient) + private IConfiguration _configuration; + private MapQuestGeocoder _geocoder; + public LocationService(IDatabaseConnection settings, IMongoClient mongoClient, IConfiguration configuration) { var database = mongoClient.GetDatabase(settings.DatabaseName); _locations = database.GetCollection(settings.LocationCollectionName); + _configuration = configuration; + var _mapQuestApiKey = _configuration.GetSection("AppSettings:MapQuestApiKey").Value; + _geocoder = new MapQuestGeocoder(_mapQuestApiKey); + } public async Task add(Location loc) { - //TODO GOOGLE MAPS API CALL FOR info + IEnumerable
adresses = await _geocoder.GeocodeAsync(loc.name+" "+loc.address+" "+loc.city+" "+loc.country); + loc.latitude = adresses.First().Coordinates.Latitude; + loc.longitude=adresses.First().Coordinates.Longitude; await _locations.InsertOneAsync(loc); + return loc; } public async Task getById(string id) diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index b7f25b2..22d91dc 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -1,8 +1,9 @@ { - "AppSettings": { - "JwtToken": "PjrVqQJ1P2VOkuWLw7NaZUluT4z7bkau", - "EmailToken": "e8X8c0lm9KS7itWi3wgE6BiPXR21WPvO" - }, + "AppSettings": { + "JwtToken": "PjrVqQJ1P2VOkuWLw7NaZUluT4z7bkau", + "EmailToken": "e8X8c0lm9KS7itWi3wgE6BiPXR21WPvO", + "MapQuestApiKey": "47oeviBUoCI2JxWzNARmCtrH9fDp5Mtk" //msbs#556ASDFGGSGSD + }, "Logging": { "LogLevel": { @@ -21,11 +22,11 @@ "LocationCollectionname": "locations" }, - "EmailCfg": { - "Email": "oddyssey.brzodolokacije@gmail.com", - "SmtpServer": "smtp.gmail.com", - "Password": "nrokhfcwahfbqnpp" //msbs#556 - }, + "EmailCfg": { + "Email": "oddyssey.brzodolokacije@gmail.com", + "SmtpServer": "smtp.gmail.com", + "Password": "nrokhfcwahfbqnpp" //msbs#556 + }, "URLs": { "localhost": "http://localhost:5279/", "actual":"add url when back put onto server" -- cgit v1.2.3 From 8123a815bd0591ec0d5ecb9b874c6141d65da9c7 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sun, 6 Nov 2022 20:40:07 +0100 Subject: Dodat api za preuzimanje slika pomocu id-a. --- Backend/Api/Api/Controllers/PostController.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 31dbeef..62f77f1 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -13,9 +13,11 @@ namespace Api.Controllers public class PostController : ControllerBase { private readonly IPostService _postService; - public PostController(IPostService postService) + private readonly IFileService _fileService; + public PostController(IPostService postService, IFileService fileService) { _postService = postService; + _fileService = fileService; } [HttpPost("add")] @@ -52,5 +54,18 @@ namespace Api.Controllers return BadRequest(); } + [HttpGet("image/{id}")] + [Authorize(Roles = "User")] + public async Task getImage(string id) + { + Models.File f =await _fileService.getById(id); + if (f == null || !System.IO.File.Exists(f.path)) + return BadRequest("Slika ne postoji"); + return File(System.IO.File.ReadAllBytes(f.path), "image/*", Path.GetFileName(f.path)); + + + } + + } } -- cgit v1.2.3 From f5b8977e911adf5caba238d624c2668f2a57ba92 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sun, 6 Nov 2022 21:44:54 +0100 Subject: Pretvaranje Post-a u PostSend. --- Backend/Api/Api/Controllers/PostController.cs | 2 +- Backend/Api/Api/Interfaces/IPostService.cs | 2 +- Backend/Api/Api/Services/PostService.cs | 21 ++++++++++++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 62f77f1..a61ee2e 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -42,7 +42,7 @@ namespace Api.Controllers } return BadRequest(); } - [HttpGet("posts /{id}")] + [HttpGet("posts/{id}")] [Authorize(Roles = "User")] public async Task> getPostByid(string id) { diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 31e80cd..29a824a 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -7,6 +7,6 @@ namespace Api.Interfaces Task addPost(PostReceive post); Task> getAllPosts(); Task getPostById(string id); - PostSend postToPostSend(Post post); + Task postToPostSend(Post post); } } \ No newline at end of file diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 0a12f39..e9a56d2 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -11,12 +11,14 @@ namespace Api.Services private readonly IMongoCollection _posts; private readonly IHttpContextAccessor _httpContext; private readonly IFileService _fileService; - public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext, IFileService fileService) + private readonly ILocationService _locationService; + public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext, IFileService fileService,ILocationService locationService) { var database = mongoClient.GetDatabase(settings.DatabaseName); _posts = database.GetCollection(settings.PostCollectionName); _httpContext = httpContext; _fileService = fileService; + _locationService = locationService; } public async Task addPost(PostReceive post) @@ -63,14 +65,23 @@ namespace Api.Services } await _posts.InsertOneAsync(p); - return postToPostSend(p); + return await postToPostSend(p); } - public PostSend postToPostSend(Post post) + public async Task postToPostSend(Post post) { PostSend p = new PostSend(); //Convert post to post send (TODO) p._id = post._id; + p.ownerId = post.ownerId; + p.description = post.description; + p.location = await _locationService.getById(post.locationId); + p.images = post.images; + p.views = 1;//Default values todo + p.ratings = 1; + p.comments = null; + + return p; } @@ -80,7 +91,7 @@ namespace Api.Services List temp = new List(); foreach (var post in posts) { - temp.Add(postToPostSend(post)); + temp.Add(await postToPostSend(post)); } return temp; } @@ -88,7 +99,7 @@ namespace Api.Services public async Task getPostById(string id) { Post p = await _posts.Find(post => post._id == id).FirstOrDefaultAsync(); - return postToPostSend(p); + return await postToPostSend(p); } //(TODO) ADD Delete and update -- cgit v1.2.3 From ff5ff5e2934ce35b70fb75b1077c3fc5d21abbe7 Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Mon, 7 Nov 2022 15:27:57 +0100 Subject: swaggerauth,views,ratings,cascading comments, bugs --- Backend/Api/Api/Api.csproj | 1 + Backend/Api/Api/Controllers/PostController.cs | 53 +++++++- Backend/Api/Api/Interfaces/IPostService.cs | 9 +- Backend/Api/Api/Models/Post.cs | 36 +++-- Backend/Api/Api/Program.cs | 14 +- Backend/Api/Api/Services/PostService.cs | 182 +++++++++++++++++++++++++- 6 files changed, 278 insertions(+), 17 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index 80898fd..24c41b7 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -13,6 +13,7 @@ + diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index a61ee2e..27823bc 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -14,10 +14,12 @@ namespace Api.Controllers { private readonly IPostService _postService; private readonly IFileService _fileService; - public PostController(IPostService postService, IFileService fileService) + private readonly IUserService _userService; + public PostController(IPostService postService, IFileService fileService,IUserService userService) { _postService = postService; _fileService = fileService; + _userService = userService; } [HttpPost("add")] @@ -46,7 +48,8 @@ namespace Api.Controllers [Authorize(Roles = "User")] public async Task> getPostByid(string id) { - var res = await _postService.getPostById(id); + var userid = await _userService.UserIdFromJwt(); + var res = await _postService.getPostById(id,userid); if (res != null) { return Ok(res); @@ -62,10 +65,56 @@ namespace Api.Controllers if (f == null || !System.IO.File.Exists(f.path)) return BadRequest("Slika ne postoji"); return File(System.IO.File.ReadAllBytes(f.path), "image/*", Path.GetFileName(f.path)); + } + [HttpPost("posts/{id}/addrating")] + [Authorize(Roles = "User")] + public async Task addRating([FromBody] RatingReceive rating,string id) + { + var userid = await _userService.UserIdFromJwt(); + if (await _postService.AddOrReplaceRating(rating, userid)) + return Ok(); + return BadRequest(); + } + [HttpDelete("posts/{id}/removerating")] + [Authorize(Roles = "User")] + public async Task removeRating(string id) + { + var userid = await _userService.UserIdFromJwt(); + if (await _postService.RemoveRating(id,userid)) + return Ok(); + return BadRequest(); } + [HttpPost("posts/{id}/addcomment")] + [Authorize(Roles = "User")] + public async Task addComment([FromBody] CommentReceive cmnt,string id) + { + var userid = await _userService.UserIdFromJwt(); + if (await _postService.AddComment(cmnt,userid,id)) + return Ok(); + return BadRequest(); + } + + [HttpGet("posts/{id}/listcomments")] + [Authorize(Roles = "User")] + public async Task>> listComments(string id) + { + var ret = await _postService.ListComments(id); + if(ret != null) + return Ok(ret); + return BadRequest(); + } + [HttpDelete("posts/{id}/removecomment/{cmntid}")] + [Authorize(Roles = "User")] + public async Task removeRating(string id,string cmntid) + { + var userid = await _userService.UserIdFromJwt(); + if (await _postService.DeleteComments(id,cmntid,userid)) + return Ok(); + return BadRequest(); + } } } diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 29a824a..daeee92 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -6,7 +6,14 @@ namespace Api.Interfaces { Task addPost(PostReceive post); Task> getAllPosts(); - Task getPostById(string id); + Task getPostById(string id,string userid); Task postToPostSend(Post post); + Task AddOrReplaceRating(RatingReceive rating, string userid); + Task RemoveRating(string postid, string userid); + Task AddComment(CommentReceive cmnt, string userid, string postid); + Task> ListComments(string postid); + Task> CascadeComments(string parentid, Post p); + Task DeleteComments(string postid, string cmntid,string userid); + Task CascadeDeleteComments(string cmntid, Post p); } } \ No newline at end of file diff --git a/Backend/Api/Api/Models/Post.cs b/Backend/Api/Api/Models/Post.cs index ee84e0f..c832d23 100644 --- a/Backend/Api/Api/Models/Post.cs +++ b/Backend/Api/Api/Models/Post.cs @@ -20,9 +20,7 @@ namespace Api.Models } public class PostReceive { - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - public string _id { get; set; } + public string? _id { get; set; } public string locationId { get; set; } public string description { get; set; } public List images { get; set; } @@ -31,15 +29,13 @@ namespace Api.Models } public class PostSend { - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] public string _id { get; set; } public string ownerId { get; set; } public Location location { get; set; } public string description { get; set; } public int views { get; set; } - public float ratings { get; set; } - public List comments { get; set; } + public double ratings { get; set; } + public List comments { get; set; } public List images { get; set; } } public class Rating @@ -49,9 +45,33 @@ namespace Api.Models } public class Comment { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string _id { get; set; } + public string userId { get; set; } + public string comment { get; set; } + public string parentId { get; set; } + public DateTime timestamp { get; set; } + } + + public class RatingReceive + { + public int rating { get; set; } + public string postId { get; set; } + } + public class CommentSend + { + public string _id { get; set; } public string userId { get; set; } public string comment { get; set; } - public Comment parent { get; set; } + public string? parentId { get; set; } public DateTime timestamp { get; set; } + public string username { get; set; } + public List replies { get; set; } + } + public class CommentReceive + { + public string comment { get; set; } + public string parentId { get; set; } } } diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 16b0241..7d6b03e 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -4,7 +4,9 @@ using Api.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; using MongoDB.Driver; +using Swashbuckle.AspNetCore.Filters; using System.Text; var builder = WebApplication.CreateBuilder(args); @@ -50,7 +52,17 @@ builder.Services.AddAuthentication( builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); +builder.Services.AddSwaggerGen(options => { + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + { + Description = "Standard Authorization header using the Bearer scheme (\"bearer {token}\")", + In = ParameterLocation.Header, + Name = "Authorization", + Type = SecuritySchemeType.ApiKey + }); + + options.OperationFilter(); +}); builder.Services.AddCors(options => { diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index e9a56d2..78167bd 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -2,6 +2,8 @@ using Api.Interfaces; using Api.Models; using MongoDB.Driver; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson; namespace Api.Services { @@ -12,10 +14,12 @@ namespace Api.Services private readonly IHttpContextAccessor _httpContext; private readonly IFileService _fileService; private readonly ILocationService _locationService; + private readonly IMongoCollection _users; public PostService(IDatabaseConnection settings, IMongoClient mongoClient, IHttpContextAccessor httpContext, IFileService fileService,ILocationService locationService) { var database = mongoClient.GetDatabase(settings.DatabaseName); _posts = database.GetCollection(settings.PostCollectionName); + _users = database.GetCollection(settings.UserCollectionName); _httpContext = httpContext; _fileService = fileService; _locationService = locationService; @@ -25,7 +29,7 @@ namespace Api.Services { Post p = new Post(); p._id = ""; - p.ownerId = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + p.ownerId = _httpContext.HttpContext.User.FindFirstValue("id"); p.locationId = post.locationId; p.description = post.description; @@ -77,8 +81,16 @@ namespace Api.Services p.description = post.description; p.location = await _locationService.getById(post.locationId); p.images = post.images; - p.views = 1;//Default values todo - p.ratings = 1; + p.views = post.views.Count(); + if (post.ratings.Count() > 0) + { + List ratings = new List(); + foreach (var r in post.ratings) + ratings.Add(r.rating); + p.ratings = ratings.Average(); + } + else + p.ratings = 0; p.comments = null; @@ -96,12 +108,172 @@ namespace Api.Services return temp; } - public async Task getPostById(string id) + public async Task getPostById(string id,string userid) { Post p = await _posts.Find(post => post._id == id).FirstOrDefaultAsync(); + if (p != null) + { + if (!p.views.Any(x => x == userid)) + { + p.views.Add(userid); + await _posts.ReplaceOneAsync(x => x._id == id, p); + } + } return await postToPostSend(p); + } + + public async Task AddOrReplaceRating(RatingReceive rating,string userid) + { + Post p = await _posts.Find(post => post._id == rating.postId).FirstOrDefaultAsync(); + if (p != null) + { + if (p.ownerId == userid) + return false; + if(!p.ratings.Any(x => x.userId == userid)) + { + Rating r = new Rating(); + r.rating = rating.rating; + r.userId = userid; + p.ratings.Add(r); + await _posts.ReplaceOneAsync(x => x._id == p._id, p); + } + else + { + var r = p.ratings.Find(x => x.userId == userid); + p.ratings.Remove(r); + r.rating = rating.rating; + p.ratings.Add(r); + await _posts.ReplaceOneAsync(x => x._id == p._id, p); + } + return true; + } + return false; + } + public async Task RemoveRating(string postid, string userid) + { + Post p = await _posts.Find(post => post._id == postid).FirstOrDefaultAsync(); + if (p != null) + { + if (p.ratings.Any(x => x.userId == userid)) + { + var r = p.ratings.Find(x => x.userId == userid); + p.ratings.Remove(r); + await _posts.ReplaceOneAsync(x => x._id == postid, p); + return true; + } + } + return false; + } + public async Task AddComment(CommentReceive cmnt,string userid,string postid) + { + Post p = await _posts.Find(post => post._id == postid).FirstOrDefaultAsync(); + if (p != null) + { + Comment c= new Comment(); + c.parentId = cmnt.parentId; + c.userId = userid; + c.comment = cmnt.comment; + c.timestamp = DateTime.Now.ToUniversalTime(); + c._id = ObjectId.GenerateNewId().ToString(); + p.comments.Add(c); + await _posts.ReplaceOneAsync(x => x._id == postid, p); + return true; + } + return false; + } + public async Task> ListComments(string postid) + { + Post p = await _posts.Find(post => post._id == postid).FirstOrDefaultAsync(); + if (p != null) + { + List lista = new List(); + lista = p.comments.FindAll(x => x.parentId == null || x.parentId == ""); + if (lista.Count() > 0) + { + List tosend = new List(); + foreach(var comment in lista) + { + CommentSend c = new CommentSend(); + c.userId = comment.userId; + c._id = comment._id; + c.parentId = comment.parentId; + c.comment = comment.comment; + c.timestamp = comment.timestamp; + + var user = await _users.Find(x => x._id == comment.userId).FirstOrDefaultAsync(); + if (user != null) + c.username = user.username; + else c.username = "Deleted user"; + + c.replies = await CascadeComments(comment._id, p); + + tosend.Add(c); + } + return tosend; + } + } + return null; + } + public async Task> CascadeComments(string parentid,Post p) + { + List lista = new List(); + lista = p.comments.FindAll(x => x.parentId == parentid); + if (lista.Count()>0) + { + List replies = new List(); + foreach (var comment in lista) + { + CommentSend c = new CommentSend(); + c.userId = comment.userId; + c._id = comment._id; + c.parentId = comment.parentId; + c.comment = comment.comment; + c.timestamp = comment.timestamp; + + var user= await _users.Find(x => x._id == comment.userId).FirstOrDefaultAsync(); + if (user != null) + c.username = user.username; + else c.username = "Deleted user"; + + c.replies = await CascadeComments(comment._id, p); + + replies.Add(c); + } + return replies; + } + return null; + } + public async Task DeleteComments(string postid,string cmntid,string userid) + { + Post p = await _posts.Find(post => post._id == postid).FirstOrDefaultAsync(); + if (p != null) + { + var com = p.comments.Find(x => x._id == cmntid); + if (com != null && com.userId == userid) + { + var comment = p.comments.Find(x => x._id == cmntid); + p.comments.Remove(comment); + await _posts.ReplaceOneAsync(x => x._id == p._id, p); + await CascadeDeleteComments(cmntid, p); + return true; + } + } + return false; + } + public async Task CascadeDeleteComments(string cmntid,Post p) + { + List lista = new List(); + lista = p.comments.FindAll(x => x.parentId == cmntid); + if (lista.Count() > 0) + { + foreach (var comment in lista) + { + p.comments.Remove(comment); + await _posts.ReplaceOneAsync(x => x._id == p._id, p); + await CascadeDeleteComments(comment._id, p); + } + } } - //(TODO) ADD Delete and update } } -- cgit v1.2.3 From 89d526c9e9d28bd2802d9033318e9eac3d507e34 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 7 Nov 2022 22:31:17 +0100 Subject: Napravljen kontroler za preuzimanje aplikacije. --- Backend/Api/Api/.gitignore | 3 ++- Backend/Api/Api/Controllers/appController.cs | 27 +++++++++++++++++++++++++++ Backend/Api/Api/appsettings.json | 3 ++- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 Backend/Api/Api/Controllers/appController.cs (limited to 'Backend/Api') diff --git a/Backend/Api/Api/.gitignore b/Backend/Api/Api/.gitignore index f4b4ba8..5582dbb 100644 --- a/Backend/Api/Api/.gitignore +++ b/Backend/Api/Api/.gitignore @@ -1 +1,2 @@ -Files/* \ No newline at end of file +Files/* +app-debug.apk \ No newline at end of file diff --git a/Backend/Api/Api/Controllers/appController.cs b/Backend/Api/Api/Controllers/appController.cs new file mode 100644 index 0000000..004c941 --- /dev/null +++ b/Backend/Api/Api/Controllers/appController.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Authorization; +using System.Data; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class appController : ControllerBase + { + private readonly IConfiguration _configuration; + public appController(IConfiguration configuration) { + _configuration = configuration; + } + + [HttpGet("download")] + public async Task getApp() + { + string appPath = _configuration.GetSection("AppSettings:AppName").Value; + if (appPath == null || !System.IO.File.Exists(appPath)) + return BadRequest("Aplikacija ne postoji"); + return File(System.IO.File.ReadAllBytes(appPath), "application/octet-stream", Path.GetFileName(appPath)); + } + + } +} diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index 22d91dc..b1bc59c 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -2,7 +2,8 @@ "AppSettings": { "JwtToken": "PjrVqQJ1P2VOkuWLw7NaZUluT4z7bkau", "EmailToken": "e8X8c0lm9KS7itWi3wgE6BiPXR21WPvO", - "MapQuestApiKey": "47oeviBUoCI2JxWzNARmCtrH9fDp5Mtk" //msbs#556ASDFGGSGSD + "MapQuestApiKey": "47oeviBUoCI2JxWzNARmCtrH9fDp5Mtk", //msbs#556ASDFGGSGSD + "AppName": "app-debug.apk" }, "Logging": { -- cgit v1.2.3 From 7e19e80edabe3d974108694021a2e426228dee02 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Tue, 8 Nov 2022 00:32:54 +0100 Subject: odradjeno ucitavanje prve slike svake objave na listi, uklonjena autorizacija za preuzimanje slika #17 --- Backend/Api/Api/Controllers/PostController.cs | 2 +- Client/BrzoDoLokacije/app/build.gradle | 3 ++ .../brzodolokacije/Adapters/ShowPostsAdapter.kt | 33 ++++------------------ .../brzodolokacije/Interfaces/IBackendApi.kt | 3 -- .../brzodolokacije/Services/MyAppGlideModule.kt | 7 +++++ 5 files changed, 17 insertions(+), 31 deletions(-) create mode 100644 Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/MyAppGlideModule.kt (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 27823bc..3857ce0 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -58,7 +58,7 @@ namespace Api.Controllers } [HttpGet("image/{id}")] - [Authorize(Roles = "User")] + //[Authorize(Roles = "User")] public async Task getImage(string id) { Models.File f =await _fileService.getById(id); diff --git a/Client/BrzoDoLokacije/app/build.gradle b/Client/BrzoDoLokacije/app/build.gradle index fa85692..72f1f0d 100644 --- a/Client/BrzoDoLokacije/app/build.gradle +++ b/Client/BrzoDoLokacije/app/build.gradle @@ -56,4 +56,7 @@ dependencies { //JWT implementation 'com.auth0.android:jwtdecode:2.0.1' + //Glide + implementation 'com.github.bumptech.glide:glide:4.12.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt index 134b665..bbcf9e4 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt @@ -9,6 +9,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import android.widget.Toast import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide import com.example.brzodolokacije.Activities.ActivitySinglePost import com.example.brzodolokacije.Interfaces.IBackendApi import com.example.brzodolokacije.Models.LocationType @@ -61,33 +62,11 @@ class ShowPostsAdapter (val activity:Activity,val items : MutableList { - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful) { - val image: ResponseBody = response.body()!! - binding.locationImage.setImageBitmap(BitmapFactory.decodeStream(image.byteStream())) - Toast.makeText( - activity, "prosao zahtev", Toast.LENGTH_LONG - ).show() - } else { - if (response.errorBody() != null) - Toast.makeText( - activity, - response.errorBody()!!.string(), - Toast.LENGTH_LONG - ).show(); - } - } - - override fun onFailure(call: Call, t: Throwable) { - Toast.makeText( - activity, t.toString(), Toast.LENGTH_LONG - ).show(); - } - }) + if(item.images.isNotEmpty()) { + Glide.with(activity) + .load(RetrofitHelper.baseUrl + "/api/post/image/" + item.images[0]._id) + .into(locationImage) + } } } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt index 49dda46..131233c 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt @@ -22,9 +22,6 @@ interface IBackendApi { fun resetpass(@Body obj:ResetPass):Call @GET("/api/post") fun getPosts(@Header("Authorization") authHeader:String):Call> - @Streaming - @GET("/api/post/image/{id}") - fun getImage(@Header("Authorization") authHeader:String,@Path("id") obj:String):Call //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/MyAppGlideModule.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/MyAppGlideModule.kt new file mode 100644 index 0000000..95171cb --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/MyAppGlideModule.kt @@ -0,0 +1,7 @@ +package com.example.brzodolokacije.Services + +import com.bumptech.glide.module.AppGlideModule + +class MyAppGlideModule: AppGlideModule() { + +} \ No newline at end of file -- cgit v1.2.3 From 22e87004cb7c469b586d24aa65e04b31307ccacf Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Tue, 8 Nov 2022 14:09:25 +0100 Subject: Dodati upiti sa clienta ka backend-u za dodavanje lokacije i objave. Omoguceno uplodovanje slike sa clienta. --- Backend/Api/Api/Models/Location.cs | 9 +- Backend/Api/Api/Services/LocationService.cs | 1 + .../app/src/main/AndroidManifest.xml | 3 + .../brzodolokacije/Activities/ActivityAddPost.kt | 125 +++++++++++++++++---- .../brzodolokacije/Fragments/FragmentShowPosts.kt | 2 +- .../brzodolokacije/Interfaces/IBackendApi.kt | 13 ++- .../java/com/example/brzodolokacije/Models/Post.kt | 2 +- 7 files changed, 124 insertions(+), 31 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Models/Location.cs b/Backend/Api/Api/Models/Location.cs index 8cc4377..7c1a0bf 100644 --- a/Backend/Api/Api/Models/Location.cs +++ b/Backend/Api/Api/Models/Location.cs @@ -14,16 +14,15 @@ namespace Api.Models public String address { get; set; } public double latitude { get; set; } public double longitude { get; set; } - public LocationType type { get; set; } + //public LocationType type { get; set; } } public enum LocationType { - Plaza, - Grad, - Zgrada, - Itd + GRAD,ULICA,JEZERO,REKA,PLAZA,OKEAN, MORE, MOREUZ, MOST,BANJA, + PLANINA, VISORAVAN, PIRAMIDA, LIVADA, SELO, OSTRVO, POLUOSTRVO, KLISURA, ARHIPELAG, + ADA, DELTA, FJORD, GEJZIR, IZVOR, KOTLINA, MINERALNI_IZVOR, PECINA ,SUMA, VODOPAD,VULKAN } } diff --git a/Backend/Api/Api/Services/LocationService.cs b/Backend/Api/Api/Services/LocationService.cs index 292fc0e..e244ed6 100644 --- a/Backend/Api/Api/Services/LocationService.cs +++ b/Backend/Api/Api/Services/LocationService.cs @@ -28,6 +28,7 @@ namespace Api.Services public async Task add(Location loc) { IEnumerable
adresses = await _geocoder.GeocodeAsync(loc.name+" "+loc.address+" "+loc.city+" "+loc.country); + loc.country = loc.name; loc.latitude = adresses.First().Coordinates.Latitude; loc.longitude=adresses.First().Coordinates.Longitude; await _locations.InsertOneAsync(loc); diff --git a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml index dc4b3bb..362e82b 100644 --- a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml +++ b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml @@ -8,9 +8,12 @@ + + diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt index 3334518..40d8f11 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt @@ -1,33 +1,30 @@ package com.example.brzodolokacije.Activities import android.Manifest -import android.content.Context import android.content.Intent import android.content.pm.PackageManager -import android.database.Cursor -import android.graphics.BitmapFactory import android.graphics.Color import android.net.Uri -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle -import android.provider.MediaStore -import android.provider.MediaStore.Audio.Media import android.util.Log import android.view.View -import android.view.ViewGroup import android.widget.* -import androidx.constraintlayout.motion.widget.TransitionBuilder.validate +import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat -import com.example.brzodolokacije.Interfaces.IBackendApi -import com.example.brzodolokacije.Models.Post -import com.example.brzodolokacije.Models.PostImage -import com.example.brzodolokacije.Models.PostSend +import com.example.brzodolokacije.Models.Location +import com.example.brzodolokacije.Models.LocationType +import com.example.brzodolokacije.Models.PostPreview import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import java.net.URI +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import okhttp3.MediaType +import okhttp3.MultipartBody +import okhttp3.RequestBody +import retrofit2.Call +import retrofit2.Response +import java.io.File +import java.io.IOException class ActivityAddPost : AppCompatActivity() { @@ -162,20 +159,106 @@ class ActivityAddPost : AppCompatActivity() { } } private fun sendPost(){ + uploadLocation() + + } + fun uploadLocation() { val api =RetrofitHelper.getInstance() + var loc:Location=Location("",locationString,"","","",0.0,0.0,LocationType.GRAD) + var jwtString= SharedPreferencesHelper.getValue("jwt",this) + var data=api.addLocation("Bearer "+jwtString,loc) + + + data.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.isSuccessful()){ + Toast.makeText( + applicationContext, "USPEH", Toast.LENGTH_LONG + ).show(); + uploadPost(response.body()!!._id) + Log.d("MAIN","RADI") + Log.d("MAIN","RADI") + + }else { + + if (response.errorBody() != null) { + Log.d("Main",response.errorBody()!!.string()) + Log.d("Main",response.message()) + } + Log.d("Main","sadadsa") + Log.d("Main",response.errorBody()!!.string()) + Log.d("Main",response.message()) + } - var obj=PostSend("","","") + } - var loc=locationString - location.text.clear() + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + applicationContext, t.toString(), Toast.LENGTH_LONG + ).show(); + Log.d("Main",t.toString()) + } + }) + } + fun uploadPost(loc:String){ + val api =RetrofitHelper.getInstance() var desc=descriptionString description.text.clear() - - obj.locationId=loc - obj.description=desc + //loc + //desc + var locReq=RequestBody.create(MediaType.parse("text/plain"),loc) + var descReq=RequestBody.create(MediaType.parse("text/plain"),desc) + var idReq=RequestBody.create(MediaType.parse("text/plain"),"dsa") + val imagesParts = arrayOfNulls( + uploadedImages!!.size + ) //dodavanje u bazu + for (i in 0..uploadedImages!!.size - 1){ + //var file=File(uploadedImages!![i]!!.path) + Log.d("Main", uploadedImages!![i]!!.path!!) + var inputStream=getContentResolver().openInputStream(uploadedImages!![i]!!) + val file: File = File.createTempFile("temp",i.toString()) + file!!.writeBytes(inputStream!!.readBytes()) + + + var imageBody=RequestBody.create(MediaType.parse("image/*"),file) + imagesParts[i]=MultipartBody.Part.createFormData("images",file.name,imageBody) + } + var jwtString= SharedPreferencesHelper.getValue("jwt",this) + var data=api.addPost("Bearer "+jwtString,imagesParts,idReq,descReq,locReq) + + + data.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.isSuccessful()){ + Toast.makeText( + applicationContext, "USPEH", Toast.LENGTH_LONG + ).show(); + }else { + + if (response.errorBody() != null) { + Toast.makeText( + applicationContext, + response.errorBody()!!.string(), + Toast.LENGTH_LONG + ).show(); + Log.d("Main",response.errorBody()!!.string()) + } + } + + + } + + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + applicationContext, t.toString(), Toast.LENGTH_LONG + ).show(); + Log.d("Main",t.toString()) + } + }) } + } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt index 9fc0754..807cbde 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt @@ -96,7 +96,7 @@ class FragmentShowPosts : Fragment() { val rootView = inflater?.inflate(R.layout.fragment_show_posts, container, false) recyclerView = rootView?.findViewById(R.id.rvMain) // set recyclerView attributes - recyclerView?.setHasFixedSize(true) + recyclerView?.setHasFixedSize(false) recyclerView?.layoutManager = layoutManagerVar recyclerView?.adapter = adapterVar return rootView diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt index 3f81899..c712597 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt @@ -6,11 +6,14 @@ import com.example.brzodolokacije.Models.Auth.Register import com.example.brzodolokacije.Models.Auth.ResetPass import com.example.brzodolokacije.Models.Location import com.example.brzodolokacije.Models.PostPreview -import com.example.brzodolokacije.Models.PostSend +import okhttp3.MultipartBody +import okhttp3.Request +import okhttp3.RequestBody import okhttp3.ResponseBody import retrofit2.Call import retrofit2.http.* + interface IBackendApi { @POST("/api/auth/login") fun login(@Body obj:Login): Call @@ -25,10 +28,14 @@ interface IBackendApi { @GET("/api/post") fun getPosts(@Header("Authorization") authHeader:String):Call> @POST("/api/Location/add") - fun addLocation(@Body obj:Location,@Header("Authorization") authHeader:String):Call + fun addLocation(@Header("Authorization") authHeader:String,@Body obj: Location ):Call @Multipart @POST("/api/Post/add") - fun addPost(@Part obj:PostSend,@Header("Authorization") authHeader:String):Call + fun addPost(@Header("Authorization") authHeader:String, @Part images: Array? + ,@Part("_id") _id:RequestBody + ,@Part("description") description:RequestBody + ,@Part("locationId") locationId:RequestBody + ):Call //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt index 155f6d3..9b9afaa 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt @@ -22,7 +22,7 @@ data class PostSend( var _id:String, var locationId:String, var description:String, - //var images: List + var images: List ) @Parcelize -- cgit v1.2.3