Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fixes #24298: Display current session permission and split appart form to update user details #676

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 22 additions & 6 deletions user-management/src/main/elm/sources/ApiCalls.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ module ApiCalls exposing (..)
-- API call to get the category tree


import DataTypes exposing (AddUserForm, Model, Msg(..), Username)
import DataTypes exposing (AddUserForm, Model, Msg(..), Username, UserInfoForm, UserAuth)
import Http exposing (emptyBody, expectJson, jsonBody, request, send)
import JsonDecoder exposing (decodeApiAddUserResult, decodeApiCurrentUsersConf, decodeApiDeleteUserResult, decodeApiReloadResult, decodeApiUpdateUserResult, decodeGetRoleApiResult)
import JsonEncoder exposing (encodeAddUser)
import JsonDecoder exposing (decodeApiStatusResult)
import JsonDecoder exposing (decodeApiAddUserResult, decodeApiCurrentUsersConf, decodeApiDeleteUserResult, decodeApiReloadResult, decodeApiUpdateUserResult, decodeGetRoleApiResult, decodeApiStatusResult, decodeApiUpdateUserInfoResult)
import JsonEncoder exposing (encodeAddUser, encodeUserInfo, encodeUserAuth)
import Json.Decode as Decode

getUrl: DataTypes.Model -> String -> String
Expand Down Expand Up @@ -82,22 +81,39 @@ deleteUser username model =
in
send DeleteUser req

updateUser : Model -> String -> AddUserForm -> Cmd Msg
updateUser : Model -> String -> UserAuth -> Cmd Msg
updateUser model toUpdate userForm =
let
req =
request
{ method = "POST"
, headers = []
, url = getUrl model ("/usermanagement/update/" ++ toUpdate)
, body = jsonBody (encodeAddUser userForm)
, body = jsonBody (encodeUserAuth userForm)
, expect = expectJson decodeApiUpdateUserResult
, timeout = Nothing
, withCredentials = False
}
in
send UpdateUser req

updateUserInfo : Model -> String -> UserInfoForm -> Cmd Msg
updateUserInfo model toUpdate userForm =
let
req =
request
{ method = "POST"
, headers = []
, url = getUrl model ("/usermanagement/update/info/" ++ toUpdate)
, body = jsonBody (encodeUserInfo userForm)
, expect = expectJson decodeApiUpdateUserInfoResult
, timeout = Nothing
, withCredentials = False
}
in
send UpdateUserInfo req


activateUser : Model -> Username -> Cmd Msg
activateUser model username =
let
Expand Down
70 changes: 54 additions & 16 deletions user-management/src/main/elm/sources/DataTypes.elm
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,24 @@ type alias AddUserForm =
, isPreHashed : Bool
}

type alias UserInfoForm =
{ name : String
, email : String
, otherInfo : Dict String String
}

type alias Role =
{ id: String
, rights: List String
}

type alias UserAuth =
{ login : String
, password : String
, permissions : List String
, isPreHashed : Bool
}

type alias User =
{ login : String
, name : String
Expand Down Expand Up @@ -57,7 +70,6 @@ type alias NewUser =

type alias ProviderProperties =
{ roleListOverride : RoleListOverride
, hasModifiablePassword : Bool
}

type alias ProviderInfo =
Expand Down Expand Up @@ -85,6 +97,20 @@ filterExternalProviders: List String -> List String
filterExternalProviders providers =
List.filter (\p -> p /= "file" && p /= "rootAdmin") providers

filterUserProviderEnablingRoles: Model -> User -> List ProviderInfo
filterUserProviderEnablingRoles model user =
user.providers
|> filterExternalProviders
|> List.filter (\p ->
Dict.get p model.providersProperties
|> Maybe.map (\pp -> pp.roleListOverride /= None)
|> Maybe.withDefault False
)
|> List.filterMap (\p ->
Dict.get p user.providersInfo
)


filterUserProviderByRoleListOverride: RoleListOverride -> Model -> User -> List ProviderInfo
filterUserProviderByRoleListOverride value model user =
user.providers
Expand Down Expand Up @@ -115,14 +141,6 @@ takeFirstExtendProviderInfo model user =
filterUserProviderByRoleListOverride Extend model user
|> List.head

providerHasModifiablePassword : Model -> Provider -> Bool
providerHasModifiablePassword model provider =
provider == "file" || (
Dict.get provider model.providersProperties
|> Maybe.map .hasModifiablePassword
|> Maybe.withDefault False
)

providerCanEditRoles : Model -> Provider -> Bool
providerCanEditRoles model provider =
provider == "file" || (
Expand Down Expand Up @@ -155,9 +173,7 @@ type alias UserForm =
, isHashedPasswd : Bool
, userForcePasswdInput : Bool
, rolesToAddOnSave : List String
, name : String
, email : String
, otherInfo : Dict String String
, userInfoForm : UserInfoForm
, newUserInfoFields : List (String, String)
, isValidInput : StateInput
}
Expand Down Expand Up @@ -190,6 +206,7 @@ type Msg
| AddUser (Result Error String)
| DeleteUser (Result Error String)
| UpdateUser (Result Error String)
| UpdateUserInfo (Result Error UserInfoForm)
| UpdateUserStatus (Result Error Username)
| CallApi (Model -> Cmd Msg)
| ActivePanelSettings User
Expand All @@ -210,7 +227,8 @@ type Msg
| UserInfoFields (Dict String String)
| ActivateUser Username
| DisableUser Username
| SubmitUpdatedInfos NewUser
| SubmitUpdateUser UserAuth
| SubmitUserInfo
| SubmitNewUser NewUser
| PreHashedPasswd Bool
| AddPasswdAnyway
Expand All @@ -223,7 +241,27 @@ type Msg
| Notification (Toasty.Msg Toasty.Defaults.Toast)


mergeUserNewInfo : UserForm -> Dict String String
mergeUserNewInfo : UserForm -> UserInfoForm
mergeUserNewInfo userForm =
Dict.fromList (Dict.toList userForm.otherInfo ++ userForm.newUserInfoFields)
|> Dict.remove "" -- empty fields are invalid, we remove them for now but they may be used for explicit errors later
let
userInfo = userForm.userInfoForm
in
{ name = userInfo.name
, email = userInfo.email
, otherInfo =
Dict.fromList (Dict.toList userForm.userInfoForm.otherInfo ++ userForm.newUserInfoFields)
|> Dict.remove "" -- empty fields are invalid, we remove them for now but they may be used for explicit errors later
}

userFormToNewUser : UserForm -> NewUser
userFormToNewUser userForm =
let
userInfo = mergeUserNewInfo userForm
in
{ login = userForm.login
, authz = []
, roles = userForm.rolesToAddOnSave
, name = userInfo.name
, email = userInfo.email
, otherInfo = userInfo.otherInfo
}
5 changes: 3 additions & 2 deletions user-management/src/main/elm/sources/Init.elm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Init exposing (..)

import ApiCalls exposing (getUsersConf)
import DataTypes exposing (Model, Msg(..), PanelMode(..), RoleListOverride(..), StateInput(..), UserForm, UI)
import DataTypes exposing (Model, Msg(..), PanelMode(..), RoleListOverride(..), StateInput(..), UserForm, UI, UserInfoForm)
import Dict exposing (fromList)
import Html.Attributes exposing (style)
import Http
Expand All @@ -16,7 +16,8 @@ init : { contextPath : String } -> ( Model, Cmd Msg )
init flags =
let
initUi = UI Closed False
initUserForm = UserForm "" "" True False [] "" "" Dict.empty [] ValidInputs
initUserInfoForm = UserInfoForm "" "" Dict.empty
initUserForm = UserForm "" "" True False [] initUserInfoForm [] ValidInputs
initModel = Model flags.contextPath "" (fromList []) (fromList []) [] None Toasty.initialState initUserForm initUi [] Dict.empty
in
( initModel
Expand Down
24 changes: 18 additions & 6 deletions user-management/src/main/elm/sources/JsonDecoder.elm
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
module JsonDecoder exposing (..)

import DataTypes exposing (Role, RoleConf, RoleListOverride(..), User, UserStatus(..), UsersConf)
import DataTypes exposing (Role, RoleConf, RoleListOverride(..), User, UserStatus(..), UsersConf, ProviderInfo, ProvidersInfo, ProviderProperties, UserInfoForm)
import Json.Decode as D exposing (Decoder)
import Json.Decode.Pipeline exposing (optional, required)
import DataTypes exposing (ProviderInfo)
import DataTypes exposing (ProvidersInfo)
import DataTypes exposing (ProviderProperties)
import Dict

decodeApiReloadResult : Decoder String
decodeApiReloadResult =
Expand Down Expand Up @@ -34,14 +32,13 @@ decodeProviderProperties : Decoder ProviderProperties
decodeProviderProperties =
D.succeed ProviderProperties
|> required "roleListOverride" decodeRoleListOverride
|> required "hasModifiablePassword" D.bool

decodeRoleListOverride : Decoder RoleListOverride
decodeRoleListOverride =
D.string |> D.andThen
(\str ->
case str of
"extend" -> D.succeed Extend
"no-override" -> D.succeed Extend
"override" -> D.succeed Override
_ -> D.succeed None
)
Expand Down Expand Up @@ -101,6 +98,21 @@ decodeUpdateUser : Decoder String
decodeUpdateUser =
D.at [ "updatedUser" ] (D.at [ "username" ] D.string)

decodeApiUpdateUserInfoResult : Decoder UserInfoForm
decodeApiUpdateUserInfoResult =
D.at [ "data" ] decodeUpdateUserInfo

decodeUpdateUserInfoResult : Decoder UserInfoForm
decodeUpdateUserInfoResult =
D.at [ "updatedUser" ] decodeUpdateUserInfo

decodeUpdateUserInfo : Decoder UserInfoForm
decodeUpdateUserInfo =
D.succeed UserInfoForm
|> optional "name" D.string ""
|> optional "email" D.string ""
|> optional "otherInfo" (D.dict D.string) Dict.empty

decodeApiDeleteUserResult : Decoder String
decodeApiDeleteUserResult =
D.at [ "data" ] decodeDeletedUser
Expand Down
20 changes: 14 additions & 6 deletions user-management/src/main/elm/sources/JsonEncoder.elm
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module JsonEncoder exposing (..)

import DataTypes exposing (AddUserForm, NewUser, User)
import DataTypes exposing (AddUserForm, UserAuth, UserInfoForm)
import Json.Encode exposing (Value, bool, list, object, string)
import Dict

encodeUser: (User, String) -> Value
encodeUser (user, password) =
encodeUserAuth: UserAuth -> Value
encodeUserAuth user =
object
[ ("username", string user.login)
, ("password", string password)
, ("permissions", list (\s -> string s) (user.authz ++ user.roles))
, ("password", string user.password)
, ("permissions", list (\s -> string s) user.permissions)
, ("isPreHashed", bool user.isPreHashed)
]

encodeAddUser: AddUserForm -> Value
Expand All @@ -23,3 +23,11 @@ encodeAddUser userForm =
, ("email", string userForm.user.email)
, ("otherInfo", object (List.map (\(k, v) -> (k, string v)) (Dict.toList userForm.user.otherInfo)))
]

encodeUserInfo: UserInfoForm -> Value
encodeUserInfo user =
object
[ ("name", string user.name)
, ("email", string user.email)
, ("otherInfo", object (List.map (\(k, v) -> (k, string v)) (Dict.toList user.otherInfo)))
]