generated from karsten.jeppesen/KAJE-Template
Quizzer-8: Migrating to .NET 10
This commit is contained in:
259
Quizzer-8/Quizzer/Implementations/KeyCloak.cs
Normal file
259
Quizzer-8/Quizzer/Implementations/KeyCloak.cs
Normal file
@@ -0,0 +1,259 @@
|
||||
using Quizzer.OpenIDConnect;
|
||||
using Newtonsoft.Json;
|
||||
using Quizzer.OpenIDConnect;
|
||||
|
||||
namespace Quizzer.Implementations
|
||||
{
|
||||
public class KeyCloak
|
||||
{
|
||||
private bool isDebug;
|
||||
private bool isOK;
|
||||
private bool isTeacher;
|
||||
private string? accessToken;
|
||||
private string? classlessId;
|
||||
private string? teachersId;
|
||||
private string? developersId;
|
||||
private string? studentsId;
|
||||
|
||||
/// <summary>
|
||||
/// This method uses the OAuth Resource Owners Credentials Flow to get an Access Token to provide
|
||||
/// Authorization to the APIs.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string GetAccessToken()
|
||||
{
|
||||
var client = new HttpClient();
|
||||
// https://auth.c.ucnit.eu/realms/UCNit/protocol/openid-connect/token
|
||||
string theURL = "https://" + MyConfiguration.Get()["API_SERVER"] + "/realms/" + MyConfiguration.Get()["API_REALM"] + "/protocol/openid-connect/token";
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, theURL);
|
||||
var collection = new List<KeyValuePair<string, string>>();
|
||||
collection.Add(new("client_id", MyConfiguration.Get()["API_CLIENTID"]));
|
||||
collection.Add(new("client_secret", MyConfiguration.Get()["API_SECRET"]));
|
||||
collection.Add(new("grant_type", "client_credentials"));
|
||||
var content = new FormUrlEncodedContent(collection);
|
||||
request.Content = content;
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("GetAccessToken");
|
||||
Console.WriteLine("(POST) " + theURL);
|
||||
Console.WriteLine("client_id: " + MyConfiguration.Get()["API_CLIENTID"]);
|
||||
Console.WriteLine("client_secret: " + MyConfiguration.Get()["API_SECRET"]);
|
||||
Console.WriteLine("grant_type: client_credentials");
|
||||
}
|
||||
var response = client.SendAsync(request).Result;
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
string jsonString = response.Content.ReadAsStringAsync().Result;
|
||||
object responseData = JsonConvert.DeserializeObject(jsonString);
|
||||
// return the Access Token.
|
||||
accessToken = ((dynamic)responseData).access_token;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(request.RequestUri);
|
||||
Console.WriteLine(ex.Message);
|
||||
accessToken = null;
|
||||
}
|
||||
// return the Access Token.
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public KeyCloak()
|
||||
{
|
||||
isDebug = MyConfiguration.Get()["DEBUG"] == "Y";
|
||||
try
|
||||
{
|
||||
accessToken = GetAccessToken();
|
||||
this.isOK = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.isOK = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeyCloakIsOK() { return isOK; }
|
||||
|
||||
public List<KCGroups> KeyCloakGetGroups()
|
||||
{
|
||||
var client = new HttpClient();
|
||||
// https://{{Server}}/admin/realms/{{Realm}}/groups
|
||||
string theURL = "https://" + MyConfiguration.Get()["API_SERVER"] + "/admin/realms/" + MyConfiguration.Get()["API_REALM"] + "/groups";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, theURL);
|
||||
request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("KeyCloakGetGroups");
|
||||
Console.WriteLine("(GET) " + theURL);
|
||||
Console.WriteLine("Authorization Bearer " + accessToken);
|
||||
}
|
||||
var response = client.SendAsync(request).Result;
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine("KeyCloakGetGroupsAsync");
|
||||
}
|
||||
string jsonString = response.Content.ReadAsStringAsync().Result;
|
||||
List<KCGroups> groups = JsonConvert.DeserializeObject<List<KCGroups>>(jsonString);
|
||||
foreach (KCGroups group in groups)
|
||||
{
|
||||
if (group.name == "ClassLess") classlessId = group.id;
|
||||
if (group.name == "developer") developersId = group.id;
|
||||
if (group.name == "teacher") teachersId = group.id;
|
||||
if (group.name == "student") studentsId = group.id;
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
public string? KeyCloakClassLess()
|
||||
{
|
||||
if (classlessId == null) _ = KeyCloakGetGroups();
|
||||
return classlessId;
|
||||
}
|
||||
|
||||
public string? KeyCloakTeacher()
|
||||
{
|
||||
if (teachersId == null) _ = KeyCloakGetGroups();
|
||||
return teachersId;
|
||||
}
|
||||
|
||||
public string? KeyCloakStudent()
|
||||
{
|
||||
if (studentsId == null) _ = KeyCloakGetGroups();
|
||||
return studentsId;
|
||||
}
|
||||
|
||||
public List<KCGroups> KeyCloakGetUsersGroups(string theUser)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
// https://{{Server}}/admin/realms/{{Realm}}/users/{{kajeID}}/groups
|
||||
string theURL = "https://" + MyConfiguration.Get()["API_SERVER"] + "/admin/realms/" + MyConfiguration.Get()["API_REALM"] + "/users/" + theUser + "/groups";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, theURL);
|
||||
request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("KeyCloakGetUsersGroups");
|
||||
Console.WriteLine("(GET) " + theURL);
|
||||
Console.WriteLine("Authorization Bearer " + accessToken);
|
||||
}
|
||||
var response = client.SendAsync(request).Result;
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine("KeyCloakGetUsersGroupsAsync for user: [" + theUser + "]");
|
||||
}
|
||||
string jsonString = response.Content.ReadAsStringAsync().Result;
|
||||
List<KCGroups> groups = JsonConvert.DeserializeObject<List<KCGroups>>(jsonString);
|
||||
isTeacher = false;
|
||||
foreach (KCGroups group in groups)
|
||||
{
|
||||
if (group.name == "teacher" || group.name == "developer") isTeacher = true;
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("in group: " + group.name);
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
public bool KeyCloakLeaveGroup(string theUser, string theGroup)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
string theURL = "https://" + MyConfiguration.Get()["API_SERVER"] + "/admin/realms/" + MyConfiguration.Get()["API_REALM"] + "/users/" + theUser + "/groups/" + theGroup;
|
||||
var request = new HttpRequestMessage(HttpMethod.Delete, theURL);
|
||||
request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("KeyCloakLeaveGroup");
|
||||
Console.WriteLine("(DELETE) " + theURL);
|
||||
Console.WriteLine("Authorization Bearer " + accessToken);
|
||||
}
|
||||
var response = client.SendAsync(request).Result;
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeyCloakJoinGroup(string theUser, string theGroup)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
string theURL = "https://" + MyConfiguration.Get()["API_SERVER"] + "/admin/realms/" + MyConfiguration.Get()["API_REALM"] + "/users/" + theUser + "/groups/" + theGroup;
|
||||
var request = new HttpRequestMessage(HttpMethod.Put, theURL);
|
||||
request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("KeyCloakJoinGroup");
|
||||
Console.WriteLine("(PUT) " + theURL);
|
||||
Console.WriteLine("Authorization Bearer " + accessToken);
|
||||
}
|
||||
var response = client.SendAsync(request).Result;
|
||||
try
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine("KeyCloakJoinGroup: [" + theGroup + "] for user: [" + theUser + "]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void KeyCloakToggleMembership(string theUser, string theGroup)
|
||||
{
|
||||
List<KCGroups> myGroups = KeyCloakGetUsersGroups(theUser);
|
||||
if (isDebug)
|
||||
{
|
||||
foreach (KCGroups group in myGroups)
|
||||
{
|
||||
Console.WriteLine("{0} member of {1}", theUser, group.name);
|
||||
}
|
||||
}
|
||||
foreach (KCGroups group in myGroups)
|
||||
{
|
||||
if (group.id == theGroup)
|
||||
{
|
||||
KeyCloakLeaveGroup(theUser, theGroup);
|
||||
if (isDebug) Console.WriteLine("{0} left {1}", theUser, theGroup);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
// if we get here, then create membership
|
||||
KeyCloakJoinGroup(theUser, theGroup);
|
||||
if (isDebug) Console.WriteLine("{0} joined {1}", theUser, theGroup);
|
||||
}
|
||||
|
||||
public bool KeyCloakIsTeacher() { return isTeacher; }
|
||||
}
|
||||
|
||||
public class KCUserGroups
|
||||
{
|
||||
public string? id { get; set; }
|
||||
public string? name { get; set; }
|
||||
public string? path { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class KCGroups : KCUserGroups
|
||||
{
|
||||
public List<object> subGroups { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user