generated from karsten.jeppesen/KAJE-Template
260 lines
9.8 KiB
C#
260 lines
9.8 KiB
C#
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; }
|
|
}
|
|
|
|
}
|