Move user reconciliation logic to lib (#8)

This commit is contained in:
Patrick Stevens
2022-12-30 12:54:35 +00:00
committed by GitHub
parent 99df76b22b
commit 5c275c3316
4 changed files with 122 additions and 114 deletions

View File

@@ -40,116 +40,9 @@ module Program =
m
|> Map.iter (fun (User u) errMap -> errMap |> Map.iter (fun (RepoName r) err -> printfn $"%s{u}: %s{r}: {err}"))
let rec getUserInputDefaultNo (getUserInput : unit -> string) (message : string) : bool =
Console.Write $"${message} (y/N): "
let answer = getUserInput ()
match answer with
| "y"
| "Y" -> true
| "n"
| "N"
| "" -> false
| _ -> getUserInputDefaultNo getUserInput message
let reconcileUserErrors
(log : ILogger)
(getUserInput : unit -> string)
(client : Gitea.Client)
(m : Map<User, AlignmentError<UserInfo>>)
=
let userInputLock = obj ()
m
|> Map.toSeq
|> Seq.map (fun (User user, err) ->
match err with
| AlignmentError.DoesNotExist desired ->
async {
let rand = Random ()
let pwd =
Array.init 15 (fun _ -> rand.Next (65, 65 + 25) |> byte)
|> System.Text.Encoding.ASCII.GetString
let options = Gitea.CreateUserOption ()
options.Email <- desired.Email
options.Username <- user
options.FullName <- user
options.Visibility <-
match desired.Visibility with
| None -> "public"
| Some v -> v
options.LoginName <- user
options.MustChangePassword <- Some true
options.Password <- pwd
let! _ = client.AdminCreateUser options |> Async.AwaitTask
lock
userInputLock
(fun () ->
log.LogCritical (
"Created user {User} with password {Password}, which you must now change",
user,
pwd
)
)
return ()
}
| AlignmentError.UnexpectedlyPresent ->
async {
lock
userInputLock
(fun () ->
let answer =
getUserInputDefaultNo getUserInput $"User %s{user} unexpectedly present. Remove?"
if answer then
client.AdminDeleteUser(user).Result
else
log.LogCritical ("Refusing to delete user {User}, who is unexpectedly present.", user)
)
}
| AlignmentError.ConfigurationDiffers (desired, actual) ->
let updates = UserInfo.Resolve desired actual
async {
lock
userInputLock
(fun () ->
let body = Gitea.EditUserOption ()
for update in updates do
match update with
| UserInfoUpdate.Admin (desired, _) -> body.Admin <- desired
| UserInfoUpdate.Email (desired, _) -> body.Email <- desired
| UserInfoUpdate.Visibility (desired, _) -> body.Visibility <- desired
| UserInfoUpdate.Website (desired, actual) ->
// Per https://github.com/go-gitea/gitea/issues/17126,
// the website parameter can't currently be edited.
// This is a bug that is unlikely to be fixed.
let actual =
match actual with
| None -> "<no website>"
| Some uri -> uri.ToString ()
log.LogCritical (
"User {User} has conflicting website, desired {DesiredWebsite}, existing {ActualWebsite}, which a bug in Gitea means can't be reconciled via the API.",
user,
desired,
actual
)
body.LoginName <- user
client.AdminEditUser(user, body).Result |> ignore
)
}
)
|> Async.Parallel
|> fun a -> async.Bind (a, Array.iter id >> async.Return)
let getUserInput (s : string) : string =
Console.Write s
Console.ReadLine ()
[<EntryPoint>]
let main argv =
@@ -180,7 +73,7 @@ module Program =
}
use loggerProvider = new ConsoleLoggerProvider (options)
let logger = loggerProvider.CreateLogger "Gitea.App"
let logger = loggerProvider.CreateLogger "Gitea.Declarative"
use client = new HttpClient ()
client.BaseAddress <- args.GiteaHost
@@ -189,14 +82,14 @@ module Program =
let client = Gitea.Client client
task {
Console.WriteLine "Checking users..."
logger.LogInformation "Checking users..."
let! userErrors = Gitea.checkUsers config client
match userErrors with
| Ok () -> ()
| Error errors -> do! reconcileUserErrors logger Console.ReadLine client errors
| Error errors -> do! Gitea.reconcileUserErrors logger getUserInput client errors
Console.WriteLine "Checking repos..."
logger.LogInformation "Checking repos..."
let! repoErrors = Gitea.checkRepos config client
match repoErrors with