loadUserByUsername overrides nothing in springboot authentication - spring-boot

I am new to microservice. I want to access username(email)and password
from another service which is userregistration service. when I create
a authentication service and try to access email password I am
getting compile time error.
e: E:\Nil Projects\NewMicroService\security-service\src\main\kotlin\com\security\securityservice\service\JwtUserDetailsService.kt: (16, 5): 'loadUserByUsername' overrides nothing
Here is the my codes
jwtuserdetailsservice.kt
package com.security.securityservice.service
import com.security.securityservice.UserRepository
import com.security.securityservice.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.stereotype.Service
#Service
class JwtUserDetailsService {
#Autowired
private lateinit var userDTO:UserRepository
#Throws(Exception::class)
override fun loadUserByUsername(email: String?): UserDetails {
val user: User =userDTO.findUserByEmail(email)
if (userDTO == null){
UsernameNotFoundException("your email id doesn't exist" + email)
}
return org.springframework.security.core.userdetails.User(user.userId.email,user.userId.password,ArrayList())
}
}
Above i define user.userId.email and user.userId.password because I
define userId in my User.kt . this userId comes from
userRegistration-service, this id holds username and password, but I
am not able to access email and password in authentication servicie I
am getting error at this particular point "return
org.springframework.security.core.userdetails.User(user.userId.email,user.userId.password,ArrayList())"
User.kt
package com.security.securityservice.entity
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
#Entity
data class User(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val userAuthId:Long=-1,
val otp:Int=0,
val token:String="",
var userId:Long=-1,
)
ResponseTemplate.kt
package com.security.securityservice.VO
import com.security.securityservice.entity.User
data class ResponseTemplate(
val user:User?=null,
val userRegistration: UserRegistration?=null,
)
UserRegistration.kt
package com.security.securityservice.VO
data class UserRegistration(
val userId:Long=-1,
val firstName:String="",
val lastName:String="",
val email:String="",
)

This has nothing to do with microservice instead with simple OOPs programming.
When you say the child class override certain behaviour then it must have one before, which in your case is None. Looking closely at the definition of the class JwtUserDetailsService there is no parent class/neither any interface present hence there is nothing to override. So line
override fun loadUserByUsername(email: String?): UserDetails {
will never compile. I think you should be implementing* the interface here to provide the behaviour UserDetailsService. You see that loadUserByUsername comes from the interface UserDetailsService
Now the code may compile but in order to make authentication work correctly, you have to properly integrate with the authentication manager.

Related

How to store enum data as Array List in a database using Kotlin

I have an enum class that contain multiple data ,I want to store that
enum data as list in database. for example Developer table it contain
technology column ,that column store enum data, Suppose one user want
to store Developer1 working on many technologies like java , Kotllin ,
.Net etc these technologies are belongs from enum class , How to store
.
Same as I have a Subject enum class that contain multiple subject name
,When I Register a new teacher then I want to store how many subjects
teacher know ,If he know multiple subjects that present in our enum
class list then store the subjects id which known by the teacher.But I
am not able to store multiple data in a single column in subjectId ,It
store only one Data in SubjectId column,If I pass multiple data in
subjectId column in postman it throws error 400
teacherEntity class
package com.nilmani.jpqlprojectexample.entity
import com.nilmani.jpqlprojectexample.enum.Subject
import com.nilmani.jpqlprojectexample.enum.University
import java.util.*
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
#Entity
data class Teacher(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val nameOfTeacher:String="",
val price:Long=-1,
val subject:Int = Subject.MATH.type,//List<Int> = listOf(Subject.MATH.type)
val university:Int=University.OTHER.type
)
Subject enum class
package com.nilmani.jpqlprojectexample.enum
enum class Subject(val type:Int) {
MATH(1),
PHYSIC(2),
ACCOUNTING(3),
ZOOLOGY(4),
BIOLOGY(5),
PROGRAMMING(6),
STATICS(7),
CHEMISTRY(8),
HISTORY(9)
}
ReqTeacher Model class
package com.nilmani.jpqlprojectexample.model.request
import com.nilmani.jpqlprojectexample.enum.Subject import com.nilmani.jpqlprojectexample.enum.University
data class ReqTeacher(
val nameOfTeacher:String="",
val price:Long=-1,
val subject:Int= Subject.MATH.type,
val university:Int= University.OTHER.type, )
Response Teacher Model class
package com.nilmani.jpqlprojectexample.model.response
import com.nilmani.jpqlprojectexample.enum.Subject
import com.nilmani.jpqlprojectexample.enum.University
data class ResTeacher(
val nameOfTeacher:String="",
val price:Long=-1,
val subject:Int= Subject.MATH.type,
val university:Int= University.OTHER.type,
)
Teacher controller class
package com.nilmani.jpqlprojectexample.controller
import com.nilmani.jpqlprojectexample.entity.Teacher
import com.nilmani.jpqlprojectexample.model.request.ReqTeacher
import com.nilmani.jpqlprojectexample.model.response.ResTeacher
import com.nilmani.jpqlprojectexample.repository.TeacherRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
#RestController
#RequestMapping("/teachTest")
class TeacherController {
#Autowired
private lateinit var teachRopo:TeacherRepository
#PostMapping("/add")
fun addTeacher(#ModelAttribute request:ReqTeacher):ResponseEntity<*>{
// val newTeacher = teachRopo.findById(request.)
var newTeacher = Teacher(
nameOfTeacher = request.nameOfTeacher,
price = request.price,
subject = request.subject,
university = request.university,
)
val saveTeacher = teachRopo.save(newTeacher)
val respTeacher = ResTeacher(
saveTeacher.nameOfTeacher,
saveTeacher.price,
saveTeacher.subject,
saveTeacher.university
)
return ResponseEntity(respTeacher,HttpStatus.OK)
}
}
I want to store multiple data or single data in SubjectId column of a
particular teacherId,But My code store only one data for a particular
teacherId
You should have a new table (Entity) that represents the 1-to-many relationship between Teacher and Subject, e.g. teacher_subject. This is the proper approach. If you attempt to store the subjects as space/comma-separated values in a single cell, e.g. "math, physics, biology" that would be bad practice.

Spring Boot REST API - Deserialise a query attribute with square braces with Jackson

i am calling a legacy rest endpoint. There i have to deserialise a query parameter in a rest endpoint with square braces author[name].
Question: Is it possible to deserialise the attribute author name into the AuthorDto(spring boot + kotlin)?
import com.fasterxml.jackson.annotation.JsonAutoDetect
import com.fasterxml.jackson.annotation.JsonProperty
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RestController
#RestController
class AuthorController {
#GetMapping("/author/{id}")
fun getAuthorFromLegacyApi(
#PathVariable("id") id: Long,
authorDto: AuthorDto?
) = ResponseEntity.ok(authorDto)
}
#JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
data class AuthorDto(
#RequestParam(name = "author[name]")
val name: String?,
// long list of different query parameters
val country: String? = null,
)
code: https://github.com/nusmanov/spring-boot-validation-hibernate/blob/main/src/main/kotlin/com/example/bookvalidation/author/AuthorController.kt
to test: GET http://localhost:8080/author/5?author[name]=Joe
there is a junit test see above
Yes, it is possible, if you annotate authorDto with #RequestParam("author[name]"):
#GetMapping("/author/{id}")
fun getAuthorFromLegacyApi(#PathVariable("id") id: Long, #RequestParam("author[name]") authorDto: AuthorDto) = ResponseEntity.ok(authorDto.name)
How about using the map.
#GetMapping("/author/{id}")
fun getAuthorFromLegacyApi(#PathVariable("id") id: Long, #RequestParam authorDto: Map<String, String>): String {
return "Hello $id ${authorDto["author[name]"]} ${authorDto["currency"]}"
}
I tried with author/5?author%5Bname%5D=Tom&currency=INR got the response of Hello 5 Tom INR

How to handle this Type MisMatch found List required Entity spring Boot JPA

I create a some operations in my controller class ,I want to store
the results what i get from the operation but when I store these list
of things it show me an error like Below
Type mismatch.
Required:
DepositMaterial!
Found:
List<Result>
Here is my controller class
#PatchMapping("/pendingValue")
fun pend(#ModelAttribute request:ReqFindPending):ResponseEntity<*>{
val existingWithdraw = depositRepository.findPendingByWithDrawId(request.withDrawId)
if (existingWithdraw != null){
val upPending = depositRepository.getPending(withDrawId = request.withDrawId)
depositRepository.save(upPending)
return ResponseEntity(ResMessage("Pending update successfull"),HttpStatus.OK)
}else{
return ResponseEntity(ResMessage(" id getting null value"),HttpStatus.NOT_ACCEPTABLE)
}
}
My repository
package com.nilmani.workload.repository
import com.nilmani.workload.entity.DepositMaterial
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.RequestParam
interface DepositRepository : JpaRepository<DepositMaterial, Long> {
#Query("SELECT wm.quantity ,dd.totalDeposit,wm.quantity -dd.totalDeposit AS pending FROM WithdrawMaterial wm INNER JOIN DepositMaterial dd ON wm.id = dd.withDrawId ")
fun getPending(#Param("withDrawId")withDrawId: Long?):List<Result>
}
Here is my result Model
data class Result(
val pending: Long,
val quantity: Long,
val totalDeposit: Long
)
DepositMaterial Entity Class
package com.nilmani.workload.entity
import com.nilmani.workload.enum.Material
import java.time.LocalDateTime
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
#Entity
data class DepositMaterial (
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val withDrawId:Long=-1,
val totalDeposit:Long=-1,
val material:Int= Material.NONE.type,
val depositTime:LocalDateTime = LocalDateTime.now(),
val pending:Long = -1,
val isDeposited:Boolean=false,
)
What is the reason for this issue,I want to only return these three
things, and store the result subtraction result of totalDeposit and
quantity in pending column to update the table but , It give me error
to store the depositMaterial
You are returning a list of Results from getPending, not an individual DepositMaterial. But the save method requires a single object to save. Try only requesting one object from getPending by changing the return signature.
depositRepository.getPending
returns a list of Entities.
depositRepository.save(upPending)
takes a single Entity to save in the database.
Solution:
Either change your save(upPending) method to saveAll(upPending), or update your getPending repo method to return a unique Entity object.

JpaRepository query parameters are not getting updated dynamically

Query parameters are not getting updated -
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.erecruitment.app.model.user;
#Repository
public interface updatePassword extends JpaRepository<user, Long>{
#Transactional
#Modifying
#Query(value="UPDATE user SET password=?1 WHERE username=?2",nativeQuery=true)
int updtPassword(String password,String username);
}
Result upon execution is -
Hibernate:
UPDATE
user
SET
password=?
WHERE
username=?
I tried hardcoding the parameters like -
#Query(value="UPDATE user SET password='ee' WHERE username='w#g.com'",nativeQuery=true)
And , it worked .But , the first one not worked .Can you please take a minute in helping me , because I am not getting where am I getting wrong?
The above code looks good and worked on my local machine.
Can you please add more details about your question?
Please try:
#Transactional
#Modifying
#Query(value="UPDATE user SET password= :password WHERE username= :username ",nativeQuery=true)
int updtPassword(#Param("password") String password,#Param("username") String username);
Param class to be imported:
import org.springframework.data.repository.query.Param;

#Query does not give desired result when native query is used

iam using spring data jpa in my project
package com.mf.acrs.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Data
#Entity(name= "mv_garage_asset_mapping")
public class GarageAssetMapping implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2535545189473989744L;
#Id
#Column(name="GARAGE_CODE")
private String garageCode;
#Column(name="GARAGE_NAME")
private String garageName;
#Column(name="GARAGE_ADDRESS")
private String garageAddress;
#Column(name="GARAGE_BRANCH")
private String garageBranch;
#Column(name="CONTRACT_NUMBER")
private String contractNumber;
}
this is my entity object
package com.mf.acrs.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.mf.acrs.model.GarageAssetMapping;
public interface GarageAssetMappingRepository extends JpaRepository<GarageAssetMapping, String> {
// #Query(name="select u.CONTRACT_NUMBER from mv_garage_asset_mapping u where u.GARAGE_CODE = ?1", nativeQuery = true) //**QUERY 1**
#Query("select u.contractNumber from mv_garage_asset_mapping u where u.garageCode = ?1") // **QUERY 2**
List<String> findByGarageCode(String garageCode);
}
this is my repository interface
when i use the QUERY 1 in my application the query fired by spring data jpa is
Hibernate: select garageasse0_.garage_code as garage_code1_2_, garageasse0_.contract_number as contract_number2_2_, garageasse0_.garage_address as garage_address3_2_, garageasse0_.garage_branch as garage_branch4_2_, garageasse0_.garage_name as garage_name5_2_ from mv_garage_asset_mapping garageasse0_ where garageasse0_.garage_code=?
but when i use QUERY 2 the query fired is
Hibernate: select garageasse0_.contract_number as col_0_0_ from mv_garage_asset_mapping garageasse0_ where garageasse0_.garage_code=?
QUERY 2 gives me desired result.
but my question is why spring data jpa fires a incorrect query in 1st case.
in QUERY 1 hibernate tries to pull all the data fields despite the fact i have explicitly written in query that i want to fetch only one field.
What mistake iam doing in this case?
The method defined in the controller which calls the method is below:
#PostMapping("/searchAssetsAjax")
#ResponseBody
public String searchAssetsAjax(#RequestBody SearchAssetData searchAssetData) throws IOException{
System.out.println("iam in the searchAssetsAjax "+searchAssetData);
System.out.println("iam in the searchAssetsAjax "+searchAssetData.toString());
// System.out.println("throwing exceptions" ); throw new IOException();
System.out.println("hitting the db "+searchAssetData.getGarageCode());
// List<String> contractNums = garageAssetMapRepository.findContractNumberByGarageCode(searchAssetData.getGarageCode());
List<String> contractNums = garageAssetMapRepository.findByGarageCode(searchAssetData.getGarageCode());
System.out.println("############contract num size is "+contractNums.size());
for(String contract: contractNums) {
System.out.println("contract nums are "+contract);
}
return "success";
}

Resources