From 8bcf56d905c7f0e9586c8920009dc4126574555e Mon Sep 17 00:00:00 2001 From: Izlydov Date: Wed, 19 Feb 2025 18:18:39 +0300 Subject: [PATCH] added roles logic, some fixes --- .../java/com/displaynone/acss/MainActivity.kt | 11 +++- .../auth/internal_utils/AuthTokenManager.java | 2 +- .../auth/internal_utils/UserManager.java | 61 +++++++++++++++++++ .../components/auth/models/user/UserMapper.kt | 1 + .../auth/models/user/UserServiceST.kt | 18 +++++- .../user/repository/dto/AuthorityDTO.kt | 12 ++++ .../models/user/repository/dto/UserDTO.kt | 2 + .../displaynone/acss/ui/auth/AuthFragment.kt | 1 + .../acss/ui/profile/ProfileFragment.kt | 24 ++++++-- .../acss/ui/profile/ProfileViewModel.kt | 4 +- app/src/main/res/layout/fragment_profile.xml | 5 +- app/src/main/res/navigation/nav_graph.xml | 2 +- app/src/main/res/values/strings.xml | 1 + 13 files changed, 128 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java create mode 100644 app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/AuthorityDTO.kt diff --git a/app/src/main/java/com/displaynone/acss/MainActivity.kt b/app/src/main/java/com/displaynone/acss/MainActivity.kt index cc1c80f..1cdb7df 100644 --- a/app/src/main/java/com/displaynone/acss/MainActivity.kt +++ b/app/src/main/java/com/displaynone/acss/MainActivity.kt @@ -26,8 +26,6 @@ class MainActivity : AppCompatActivity() { v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } - Log.d("123", R.id.action_nav_main_to_nav_profile.toString()) - Log.d("123", R.id.action_nav_main_to_nav_auth.toString()) val navController: NavController = this.setupNavigation() @@ -54,12 +52,19 @@ class MainActivity : AppCompatActivity() { navController.addOnDestinationChangedListener { _, destination, _ -> Log.d("Navigate", "Navigate to " + destination.label) navView.visibility = if (destination.id == R.id.nav_auth) View.GONE else View.VISIBLE + val userDTO = UserServiceST.getInstance().getUserDTO() + if (!userDTO.roles.any {it.name == "ROLE_ADMIN"}) navView.menu.findItem(R.id.nav_admin).setVisible(false) else navView.menu.findItem(R.id.nav_admin).setVisible(true) } - return navController } private fun isUserAuthenticated(): Boolean { return UserServiceST.getInstance().hasTokens() } + private fun checkForAdmin() { + val userDTO = UserServiceST.getInstance().getUserDTO() + if (userDTO.roles.any {it.name == "ROLE_ADMIN"}){ + Log.d("adminlog", "i'm admin") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/AuthTokenManager.java b/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/AuthTokenManager.java index 1a782b5..a88dca3 100644 --- a/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/AuthTokenManager.java +++ b/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/AuthTokenManager.java @@ -14,7 +14,6 @@ import java.io.IOException; import java.security.GeneralSecurityException; public class AuthTokenManager { - // Preferences private static final String _PREFERENCES_FILENAME = "authData"; private final SharedPreferences _preferences; @@ -46,6 +45,7 @@ public class AuthTokenManager { public void clear() { _preferences.edit().clear().apply(); + this._tokenPair = null; } public boolean hasTokens() { diff --git a/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java b/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java new file mode 100644 index 0000000..b28ba7f --- /dev/null +++ b/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java @@ -0,0 +1,61 @@ +package com.displaynone.acss.components.auth.internal_utils; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.security.crypto.EncryptedSharedPreferences; +import androidx.security.crypto.MasterKeys; + +import com.displaynone.acss.components.auth.models.AuthTokenPair; +import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO; +import com.google.gson.Gson; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Collections; +import java.util.Optional; + +public class UserManager { + private static final String _PREFERENCES_FILENAME = "userData"; + private final SharedPreferences _preferences; + private UserDTO userDTO; + private static final String ACCESS_KEY = "user"; + private Gson gson = new Gson(); + + public UserManager(Context context) { + this._preferences = this._createEncryptedPreferences(context); + } + + private SharedPreferences _createEncryptedPreferences(Context ctx) { + try { + return EncryptedSharedPreferences.create( + _PREFERENCES_FILENAME, + MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC), + ctx, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + ); + } catch (GeneralSecurityException | IOException e) { + throw new RuntimeException(e); + } + } + public void saveDto(UserDTO userDTO) { + this.userDTO = userDTO; + _preferences.edit() + .putString(ACCESS_KEY,toJson(userDTO)) + .apply(); + } + public UserDTO getDto() { + if (this.userDTO != null) return this.userDTO; + UserDTO userDTO = fromJson( _preferences.getString(ACCESS_KEY, null)); + return userDTO; + } + private UserDTO fromJson(String userJSON){ + UserDTO userDTO = gson.fromJson(userJSON, UserDTO.class); + return userDTO; + } + private String toJson(UserDTO userDTO){ + return gson.toJson(userDTO); + } + +} diff --git a/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserMapper.kt b/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserMapper.kt index 633f8ac..d6a11ce 100644 --- a/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserMapper.kt +++ b/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserMapper.kt @@ -22,6 +22,7 @@ class UserMapper { name = userEntity.name, photo = userEntity.photo, position = userEntity.position, + roles = emptyList(), // lastVisit = userEntity.lastVisit, ) return userDto diff --git a/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserServiceST.kt b/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserServiceST.kt index b61b63b..3e8a030 100644 --- a/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserServiceST.kt +++ b/app/src/main/java/com/displaynone/acss/components/auth/models/user/UserServiceST.kt @@ -1,15 +1,19 @@ package com.displaynone.acss.components.auth.models.user import android.content.Context +import android.util.Log import com.displaynone.acss.components.auth.internal_utils.AuthTokenManager +import com.displaynone.acss.components.auth.internal_utils.UserManager import com.displaynone.acss.components.auth.models.user.repository.UserRepository import com.displaynone.acss.components.auth.models.user.repository.dto.LastVisitsDto import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO import com.displaynone.acss.components.auth.models.user.repository.dto.VisitDto +import java.util.Optional class UserServiceST( private val tokenManager: AuthTokenManager, + private val userManager: UserManager, ) { private val userRepository: UserRepository = UserRepository() @@ -22,7 +26,9 @@ class UserServiceST( AuthTokenManager( context ) - instance = UserServiceST(tokenManager) + val userManager = + UserManager(context) + instance = UserServiceST(tokenManager, userManager) } } @@ -50,8 +56,7 @@ class UserServiceST( pageNum = pageNum, pageSize = pageSize, token = tokenManager.authTokenPair!!.accessToken - ).map { pagingDto -> pagingDto.content - } + ).map { pagingDto -> pagingDto.content } } suspend fun getLastVisitsByLogin(pageNum: Int, pageSize: Int, @@ -79,4 +84,11 @@ class UserServiceST( suspend fun openDoor(code: String): Result { return userRepository.openDoor(tokenManager.authTokenPair!!.accessToken, code = code) } + fun getUserDTO(): UserDTO { + return userManager.dto + } + fun saveUserDTO(userDTO: UserDTO){ + return userManager.saveDto(userDTO) + + } } \ No newline at end of file diff --git a/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/AuthorityDTO.kt b/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/AuthorityDTO.kt new file mode 100644 index 0000000..97841b5 --- /dev/null +++ b/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/AuthorityDTO.kt @@ -0,0 +1,12 @@ +package com.displaynone.acss.components.auth.models.user.repository.dto + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class AuthorityDTO ( + @SerialName("id") + val id: Long, + @SerialName("name") + val name: String +) \ No newline at end of file diff --git a/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/UserDTO.kt b/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/UserDTO.kt index 79a9c32..141492a 100644 --- a/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/UserDTO.kt +++ b/app/src/main/java/com/displaynone/acss/components/auth/models/user/repository/dto/UserDTO.kt @@ -20,6 +20,8 @@ data class UserDTO ( @SerialName("position") val position: String, + @SerialName("roles") + val roles: List, // @SerialName("lastVisit") // val lastVisit: String, diff --git a/app/src/main/java/com/displaynone/acss/ui/auth/AuthFragment.kt b/app/src/main/java/com/displaynone/acss/ui/auth/AuthFragment.kt index 9b39383..700d3ac 100644 --- a/app/src/main/java/com/displaynone/acss/ui/auth/AuthFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/auth/AuthFragment.kt @@ -110,6 +110,7 @@ class AuthFragment: Fragment(R.layout.fragment_auth) { return password.isNotEmpty() && password.length >= 8 } + // private fun subscribe() { // viewModel.state.collectWhenStarted(this) { state -> // binding.login.setOnClickListener(this::onLoginButtonClicked) diff --git a/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt b/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt index d7667ea..57030c8 100644 --- a/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt @@ -11,6 +11,7 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.bumptech.glide.Glide import com.displaynone.acss.R +import com.displaynone.acss.components.auth.models.user.UserServiceST import com.displaynone.acss.components.auth.models.user.repository.VisitAdapter import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO import com.displaynone.acss.databinding.FragmentProfileBinding @@ -29,6 +30,7 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FragmentProfileBinding.bind(view) + checkForAdmin() binding.swipeRefresh.setOnRefreshListener { if (getIsMe()){ @@ -61,8 +63,6 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { Log.d("ProfileFragment", "adapter submitted data") } hideButtons() - - } subscribe() binding.recyclerViewLogs.layoutManager = LinearLayoutManager(requireContext()) @@ -71,11 +71,25 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { // } } + private fun checkForAdmin() { + Log.d("check", "cheking for roles") + val userDTO = UserServiceST.getInstance().getUserDTO() + if (userDTO.roles.any {it.name == "ROLE_ADMIN"}){ + Log.d("adminlog", "i'm admin") + binding.buttonSearch.visibility = View.VISIBLE + binding.rightsUsingSmartphone.text = "Пропуск действителен" + } + if (userDTO.roles.any {it.name == "ROLE_USER"}){ + Log.d("userlog", "i'm user") + + binding.rightsUsingSmartphone.text = "Пропуск действителен" + } + } private fun hideButtons() { - binding.logout.visibility = View.INVISIBLE - binding.scan.visibility = View.INVISIBLE - binding.buttonSearch.visibility = View.INVISIBLE + binding.logout.visibility = View.GONE + binding.scan.visibility = View.GONE + binding.buttonSearch.visibility = View.GONE } fun showMyData(userDTO: UserDTO){ binding.fio.text = userDTO.name diff --git a/app/src/main/java/com/displaynone/acss/ui/profile/ProfileViewModel.kt b/app/src/main/java/com/displaynone/acss/ui/profile/ProfileViewModel.kt index 308ca53..fe45d33 100644 --- a/app/src/main/java/com/displaynone/acss/ui/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/displaynone/acss/ui/profile/ProfileViewModel.kt @@ -22,7 +22,7 @@ class ProfileViewModel(): ViewModel() { capacity = Channel.BUFFERED, onBufferOverflow = BufferOverflow.DROP_OLDEST, ) - private var login: String = "" // FIXME() + private var login: String = "" fun setLogin(login1: String){ login = login1 } @@ -56,6 +56,8 @@ class ProfileViewModel(): ViewModel() { UserServiceST.getInstance().getInfo().fold( onSuccess = { data -> _state.emit(State.Show(data)) + UserServiceST.getInstance().saveUserDTO(data) + Log.d("Pvm", data.login) }, onFailure = { error -> error.message?.let { error(it) } diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index aaeb3ac..01e5175 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -138,7 +138,7 @@ android:id="@+id/button_search" app:cardElevation="8dp" android:maxHeight="200dp" - + android:visibility="gone" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/administrator_searc_button_search" @@ -175,9 +175,10 @@ app:backgroundTint="@color/primary" app:rippleColor="@color/white"/> Your profile Change rights using smartphone Admin panel + Profile \ No newline at end of file