123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014 |
- /*
- Technitium DNS Server
- Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- using DnsServerCore.Auth;
- using Microsoft.AspNetCore.Http;
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Text.Json;
- using System.Threading.Tasks;
- namespace DnsServerCore
- {
- sealed class WebServiceAuthApi
- {
- #region variables
- readonly DnsWebService _dnsWebService;
- #endregion
- #region constructor
- public WebServiceAuthApi(DnsWebService dnsWebService)
- {
- _dnsWebService = dnsWebService;
- }
- #endregion
- #region private
- private void WriteCurrentSessionDetails(Utf8JsonWriter jsonWriter, UserSession currentSession, bool includeInfo)
- {
- if (currentSession.Type == UserSessionType.ApiToken)
- {
- jsonWriter.WriteString("username", currentSession.User.Username);
- jsonWriter.WriteString("tokenName", currentSession.TokenName);
- jsonWriter.WriteString("token", currentSession.Token);
- }
- else
- {
- jsonWriter.WriteString("displayName", currentSession.User.DisplayName);
- jsonWriter.WriteString("username", currentSession.User.Username);
- jsonWriter.WriteString("token", currentSession.Token);
- }
- if (includeInfo)
- {
- jsonWriter.WritePropertyName("info");
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("version", _dnsWebService.GetServerVersion());
- jsonWriter.WriteString("uptimestamp", _dnsWebService._uptimestamp);
- jsonWriter.WriteString("dnsServerDomain", _dnsWebService.DnsServer.ServerDomain);
- jsonWriter.WriteNumber("defaultRecordTtl", _dnsWebService._zonesApi.DefaultRecordTtl);
- jsonWriter.WriteBoolean("useSoaSerialDateScheme", _dnsWebService.DnsServer.AuthZoneManager.UseSoaSerialDateScheme);
- jsonWriter.WriteBoolean("dnssecValidation", _dnsWebService.DnsServer.DnssecValidation);
- jsonWriter.WritePropertyName("permissions");
- jsonWriter.WriteStartObject();
- for (int i = 1; i <= 11; i++)
- {
- PermissionSection section = (PermissionSection)i;
- jsonWriter.WritePropertyName(section.ToString());
- jsonWriter.WriteStartObject();
- jsonWriter.WriteBoolean("canView", _dnsWebService._authManager.IsPermitted(section, currentSession.User, PermissionFlag.View));
- jsonWriter.WriteBoolean("canModify", _dnsWebService._authManager.IsPermitted(section, currentSession.User, PermissionFlag.Modify));
- jsonWriter.WriteBoolean("canDelete", _dnsWebService._authManager.IsPermitted(section, currentSession.User, PermissionFlag.Delete));
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndObject();
- jsonWriter.WriteEndObject();
- }
- }
- private void WriteUserDetails(Utf8JsonWriter jsonWriter, User user, UserSession currentSession, bool includeMoreDetails, bool includeGroups)
- {
- jsonWriter.WriteString("displayName", user.DisplayName);
- jsonWriter.WriteString("username", user.Username);
- jsonWriter.WriteBoolean("disabled", user.Disabled);
- jsonWriter.WriteString("previousSessionLoggedOn", user.PreviousSessionLoggedOn);
- jsonWriter.WriteString("previousSessionRemoteAddress", user.PreviousSessionRemoteAddress.ToString());
- jsonWriter.WriteString("recentSessionLoggedOn", user.RecentSessionLoggedOn);
- jsonWriter.WriteString("recentSessionRemoteAddress", user.RecentSessionRemoteAddress.ToString());
- if (includeMoreDetails)
- {
- jsonWriter.WriteNumber("sessionTimeoutSeconds", user.SessionTimeoutSeconds);
- jsonWriter.WritePropertyName("memberOfGroups");
- jsonWriter.WriteStartArray();
- List<Group> memberOfGroups = new List<Group>(user.MemberOfGroups);
- memberOfGroups.Sort();
- foreach (Group group in memberOfGroups)
- {
- if (group.Name.Equals("Everyone", StringComparison.OrdinalIgnoreCase))
- continue;
- jsonWriter.WriteStringValue(group.Name);
- }
- jsonWriter.WriteEndArray();
- jsonWriter.WritePropertyName("sessions");
- jsonWriter.WriteStartArray();
- List<UserSession> sessions = _dnsWebService._authManager.GetSessions(user);
- sessions.Sort();
- foreach (UserSession session in sessions)
- WriteUserSessionDetails(jsonWriter, session, currentSession);
- jsonWriter.WriteEndArray();
- }
- if (includeGroups)
- {
- List<Group> groups = new List<Group>(_dnsWebService._authManager.Groups);
- groups.Sort();
- jsonWriter.WritePropertyName("groups");
- jsonWriter.WriteStartArray();
- foreach (Group group in groups)
- {
- if (group.Name.Equals("Everyone", StringComparison.OrdinalIgnoreCase))
- continue;
- jsonWriter.WriteStringValue(group.Name);
- }
- jsonWriter.WriteEndArray();
- }
- }
- private static void WriteUserSessionDetails(Utf8JsonWriter jsonWriter, UserSession session, UserSession currentSession)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("username", session.User.Username);
- jsonWriter.WriteBoolean("isCurrentSession", session.Equals(currentSession));
- jsonWriter.WriteString("partialToken", session.Token.AsSpan(0, 16));
- jsonWriter.WriteString("type", session.Type.ToString());
- jsonWriter.WriteString("tokenName", session.TokenName);
- jsonWriter.WriteString("lastSeen", session.LastSeen);
- jsonWriter.WriteString("lastSeenRemoteAddress", session.LastSeenRemoteAddress.ToString());
- jsonWriter.WriteString("lastSeenUserAgent", session.LastSeenUserAgent);
- jsonWriter.WriteEndObject();
- }
- private void WriteGroupDetails(Utf8JsonWriter jsonWriter, Group group, bool includeMembers, bool includeUsers)
- {
- jsonWriter.WriteString("name", group.Name);
- jsonWriter.WriteString("description", group.Description);
- if (includeMembers)
- {
- jsonWriter.WritePropertyName("members");
- jsonWriter.WriteStartArray();
- List<User> members = _dnsWebService._authManager.GetGroupMembers(group);
- members.Sort();
- foreach (User user in members)
- jsonWriter.WriteStringValue(user.Username);
- jsonWriter.WriteEndArray();
- }
- if (includeUsers)
- {
- List<User> users = new List<User>(_dnsWebService._authManager.Users);
- users.Sort();
- jsonWriter.WritePropertyName("users");
- jsonWriter.WriteStartArray();
- foreach (User user in users)
- jsonWriter.WriteStringValue(user.Username);
- jsonWriter.WriteEndArray();
- }
- }
- private void WritePermissionDetails(Utf8JsonWriter jsonWriter, Permission permission, string subItem, bool includeUsersAndGroups)
- {
- jsonWriter.WriteString("section", permission.Section.ToString());
- if (subItem is not null)
- jsonWriter.WriteString("subItem", subItem.Length == 0 ? "." : subItem);
- jsonWriter.WritePropertyName("userPermissions");
- jsonWriter.WriteStartArray();
- List<KeyValuePair<User, PermissionFlag>> userPermissions = new List<KeyValuePair<User, PermissionFlag>>(permission.UserPermissions);
- userPermissions.Sort(delegate (KeyValuePair<User, PermissionFlag> x, KeyValuePair<User, PermissionFlag> y)
- {
- return x.Key.Username.CompareTo(y.Key.Username);
- });
- foreach (KeyValuePair<User, PermissionFlag> userPermission in userPermissions)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("username", userPermission.Key.Username);
- jsonWriter.WriteBoolean("canView", userPermission.Value.HasFlag(PermissionFlag.View));
- jsonWriter.WriteBoolean("canModify", userPermission.Value.HasFlag(PermissionFlag.Modify));
- jsonWriter.WriteBoolean("canDelete", userPermission.Value.HasFlag(PermissionFlag.Delete));
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- jsonWriter.WritePropertyName("groupPermissions");
- jsonWriter.WriteStartArray();
- List<KeyValuePair<Group, PermissionFlag>> groupPermissions = new List<KeyValuePair<Group, PermissionFlag>>(permission.GroupPermissions);
- groupPermissions.Sort(delegate (KeyValuePair<Group, PermissionFlag> x, KeyValuePair<Group, PermissionFlag> y)
- {
- return x.Key.Name.CompareTo(y.Key.Name);
- });
- foreach (KeyValuePair<Group, PermissionFlag> groupPermission in groupPermissions)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("name", groupPermission.Key.Name);
- jsonWriter.WriteBoolean("canView", groupPermission.Value.HasFlag(PermissionFlag.View));
- jsonWriter.WriteBoolean("canModify", groupPermission.Value.HasFlag(PermissionFlag.Modify));
- jsonWriter.WriteBoolean("canDelete", groupPermission.Value.HasFlag(PermissionFlag.Delete));
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- if (includeUsersAndGroups)
- {
- List<User> users = new List<User>(_dnsWebService._authManager.Users);
- users.Sort();
- List<Group> groups = new List<Group>(_dnsWebService._authManager.Groups);
- groups.Sort();
- jsonWriter.WritePropertyName("users");
- jsonWriter.WriteStartArray();
- foreach (User user in users)
- jsonWriter.WriteStringValue(user.Username);
- jsonWriter.WriteEndArray();
- jsonWriter.WritePropertyName("groups");
- jsonWriter.WriteStartArray();
- foreach (Group group in groups)
- jsonWriter.WriteStringValue(group.Name);
- jsonWriter.WriteEndArray();
- }
- }
- #endregion
- #region public
- public async Task LoginAsync(HttpContext context, UserSessionType sessionType)
- {
- HttpRequest request = context.Request;
- string username = request.GetQueryOrForm("user");
- string password = request.GetQueryOrForm("pass");
- string tokenName = (sessionType == UserSessionType.ApiToken) ? request.GetQueryOrForm("tokenName") : null;
- bool includeInfo = request.GetQueryOrForm("includeInfo", bool.Parse, false);
- IPEndPoint remoteEP = context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader);
- UserSession session = await _dnsWebService._authManager.CreateSessionAsync(sessionType, tokenName, username, password, remoteEP.Address, request.Headers.UserAgent);
- _dnsWebService._log.Write(remoteEP, "[" + session.User.Username + "] User logged in.");
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteCurrentSessionDetails(jsonWriter, session, includeInfo);
- }
- public void Logout(HttpContext context)
- {
- string token = context.Request.GetQueryOrForm("token");
- UserSession session = _dnsWebService._authManager.DeleteSession(token);
- if (session is not null)
- {
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] User logged out.");
- _dnsWebService._authManager.SaveConfigFile();
- }
- }
- public void GetCurrentSessionDetails(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteCurrentSessionDetails(jsonWriter, session, true);
- }
- public void ChangePassword(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (session.Type != UserSessionType.Standard)
- throw new DnsWebServiceException("Access was denied.");
- string password = context.Request.GetQueryOrForm("pass");
- session.User.ChangePassword(password);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Password was changed successfully.");
- _dnsWebService._authManager.SaveConfigFile();
- }
- public void GetProfile(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteUserDetails(jsonWriter, session.User, session, true, false);
- }
- public void SetProfile(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (session.Type != UserSessionType.Standard)
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- if (request.TryGetQueryOrForm("displayName", out string displayName))
- session.User.DisplayName = displayName;
- if (request.TryGetQueryOrForm("sessionTimeoutSeconds", int.Parse, out int sessionTimeoutSeconds))
- session.User.SessionTimeoutSeconds = sessionTimeoutSeconds;
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] User profile was updated successfully.");
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteUserDetails(jsonWriter, session.User, session, true, false);
- }
- public void ListSessions(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("sessions");
- jsonWriter.WriteStartArray();
- List<UserSession> sessions = new List<UserSession>(_dnsWebService._authManager.Sessions);
- sessions.Sort();
- foreach (UserSession activeSession in sessions)
- {
- if (!activeSession.HasExpired())
- WriteUserSessionDetails(jsonWriter, activeSession, session);
- }
- jsonWriter.WriteEndArray();
- }
- public void CreateApiToken(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string username = request.GetQueryOrForm("user");
- string tokenName = request.GetQueryOrForm("tokenName");
- IPEndPoint remoteEP = context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader);
- UserSession createdSession = _dnsWebService._authManager.CreateApiToken(tokenName, username, remoteEP.Address, request.Headers.UserAgent);
- _dnsWebService._log.Write(remoteEP, "[" + session.User.Username + "] API token [" + tokenName + "] was created successfully for user: " + username);
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WriteString("username", createdSession.User.Username);
- jsonWriter.WriteString("tokenName", createdSession.TokenName);
- jsonWriter.WriteString("token", createdSession.Token);
- }
- public void DeleteSession(HttpContext context, bool isAdminContext)
- {
- UserSession session = context.GetCurrentSession();
- if (isAdminContext)
- {
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- }
- string strPartialToken = context.Request.GetQueryOrForm("partialToken");
- if (session.Token.StartsWith(strPartialToken))
- throw new InvalidOperationException("Invalid operation: cannot delete current session.");
- string token = null;
- foreach (UserSession activeSession in _dnsWebService._authManager.Sessions)
- {
- if (activeSession.Token.StartsWith(strPartialToken))
- {
- token = activeSession.Token;
- break;
- }
- }
- if (token is null)
- throw new DnsWebServiceException("No such active session was found for partial token: " + strPartialToken);
- if (!isAdminContext)
- {
- UserSession sessionToDelete = _dnsWebService._authManager.GetSession(token);
- if (sessionToDelete.User != session.User)
- throw new DnsWebServiceException("Access was denied.");
- }
- UserSession deletedSession = _dnsWebService._authManager.DeleteSession(token);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] User session [" + strPartialToken + "] was deleted successfully for user: " + deletedSession.User.Username);
- _dnsWebService._authManager.SaveConfigFile();
- }
- public void ListUsers(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- List<User> users = new List<User>(_dnsWebService._authManager.Users);
- users.Sort();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("users");
- jsonWriter.WriteStartArray();
- foreach (User user in users)
- {
- jsonWriter.WriteStartObject();
- WriteUserDetails(jsonWriter, user, null, false, false);
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- }
- public void CreateUser(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string displayName = request.QueryOrForm("displayName");
- string username = request.GetQueryOrForm("user");
- string password = request.GetQueryOrForm("pass");
- User user = _dnsWebService._authManager.CreateUser(displayName, username, password);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] User account was created successfully with username: " + user.Username);
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteUserDetails(jsonWriter, user, null, false, false);
- }
- public void GetUserDetails(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string username = request.GetQueryOrForm("user");
- bool includeGroups = request.GetQueryOrForm("includeGroups", bool.Parse, false);
- User user = _dnsWebService._authManager.GetUser(username);
- if (user is null)
- throw new DnsWebServiceException("No such user exists: " + username);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteUserDetails(jsonWriter, user, null, true, includeGroups);
- }
- public void SetUserDetails(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string username = request.GetQueryOrForm("user");
- User user = _dnsWebService._authManager.GetUser(username);
- if (user is null)
- throw new DnsWebServiceException("No such user exists: " + username);
- if (request.TryGetQueryOrForm("displayName", out string displayName))
- user.DisplayName = displayName;
- if (request.TryGetQueryOrForm("newUser", out string newUsername))
- _dnsWebService._authManager.ChangeUsername(user, newUsername);
- if (request.TryGetQueryOrForm("disabled", bool.Parse, out bool disabled) && (session.User != user)) //to avoid self lockout
- {
- user.Disabled = disabled;
- if (user.Disabled)
- {
- foreach (UserSession userSession in _dnsWebService._authManager.Sessions)
- {
- if (userSession.Type == UserSessionType.ApiToken)
- continue;
- if (userSession.User == user)
- _dnsWebService._authManager.DeleteSession(userSession.Token);
- }
- }
- }
- if (request.TryGetQueryOrForm("sessionTimeoutSeconds", int.Parse, out int sessionTimeoutSeconds))
- user.SessionTimeoutSeconds = sessionTimeoutSeconds;
- string newPassword = request.QueryOrForm("newPass");
- if (!string.IsNullOrWhiteSpace(newPassword))
- {
- int iterations = request.GetQueryOrForm("iterations", int.Parse, User.DEFAULT_ITERATIONS);
- user.ChangePassword(newPassword, iterations);
- }
- string memberOfGroups = request.QueryOrForm("memberOfGroups");
- if (memberOfGroups is not null)
- {
- string[] parts = memberOfGroups.Split(',');
- Dictionary<string, Group> groups = new Dictionary<string, Group>(parts.Length);
- foreach (string part in parts)
- {
- if (part.Length == 0)
- continue;
- Group group = _dnsWebService._authManager.GetGroup(part);
- if (group is null)
- throw new DnsWebServiceException("No such group exists: " + part);
- groups.Add(group.Name.ToLowerInvariant(), group);
- }
- //ensure user is member of everyone group
- Group everyone = _dnsWebService._authManager.GetGroup(Group.EVERYONE);
- groups[everyone.Name.ToLowerInvariant()] = everyone;
- if (session.User == user)
- {
- //ensure current admin user is member of administrators group to avoid self lockout
- Group admins = _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS);
- groups[admins.Name.ToLowerInvariant()] = admins;
- }
- user.SyncGroups(groups);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] User account details were updated successfully for user: " + username);
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteUserDetails(jsonWriter, user, null, true, false);
- }
- public void DeleteUser(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- string username = context.Request.GetQueryOrForm("user");
- if (session.User.Username.Equals(username, StringComparison.OrdinalIgnoreCase))
- throw new InvalidOperationException("Invalid operation: cannot delete current user.");
- if (!_dnsWebService._authManager.DeleteUser(username))
- throw new DnsWebServiceException("Failed to delete user: " + username);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] User account was deleted successfully with username: " + username);
- _dnsWebService._authManager.SaveConfigFile();
- }
- public void ListGroups(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- List<Group> groups = new List<Group>(_dnsWebService._authManager.Groups);
- groups.Sort();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("groups");
- jsonWriter.WriteStartArray();
- foreach (Group group in groups)
- {
- if (group.Name.Equals("Everyone", StringComparison.OrdinalIgnoreCase))
- continue;
- jsonWriter.WriteStartObject();
- WriteGroupDetails(jsonWriter, group, false, false);
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- }
- public void CreateGroup(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string groupName = request.GetQueryOrForm("group");
- string description = request.GetQueryOrForm("description", "");
- Group group = _dnsWebService._authManager.CreateGroup(groupName, description);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Group was created successfully with name: " + group.Name);
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteGroupDetails(jsonWriter, group, false, false);
- }
- public void GetGroupDetails(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string groupName = request.GetQueryOrForm("group");
- bool includeUsers = request.GetQueryOrForm("includeUsers", bool.Parse, false);
- Group group = _dnsWebService._authManager.GetGroup(groupName);
- if (group is null)
- throw new DnsWebServiceException("No such group exists: " + groupName);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteGroupDetails(jsonWriter, group, true, includeUsers);
- }
- public void SetGroupDetails(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string groupName = request.GetQueryOrForm("group");
- Group group = _dnsWebService._authManager.GetGroup(groupName);
- if (group is null)
- throw new DnsWebServiceException("No such group exists: " + groupName);
- if (request.TryGetQueryOrForm("newGroup", out string newGroup))
- _dnsWebService._authManager.RenameGroup(group, newGroup);
- if (request.TryGetQueryOrForm("description", out string description))
- group.Description = description;
- string members = request.QueryOrForm("members");
- if (members is not null)
- {
- string[] parts = members.Split(',');
- Dictionary<string, User> users = new Dictionary<string, User>();
- foreach (string part in parts)
- {
- if (part.Length == 0)
- continue;
- User user = _dnsWebService._authManager.GetUser(part);
- if (user is null)
- throw new DnsWebServiceException("No such user exists: " + part);
- users.Add(user.Username, user);
- }
- if (group.Name.Equals("administrators", StringComparison.OrdinalIgnoreCase))
- users[session.User.Username] = session.User; //ensure current admin user is member of administrators group to avoid self lockout
- _dnsWebService._authManager.SyncGroupMembers(group, users);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Group details were updated successfully for group: " + groupName);
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WriteGroupDetails(jsonWriter, group, true, false);
- }
- public void DeleteGroup(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- string groupName = context.Request.GetQueryOrForm("group");
- if (!_dnsWebService._authManager.DeleteGroup(groupName))
- throw new DnsWebServiceException("Failed to delete group: " + groupName);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Group was deleted successfully with name: " + groupName);
- _dnsWebService._authManager.SaveConfigFile();
- }
- public void ListPermissions(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- List<Permission> permissions = new List<Permission>(_dnsWebService._authManager.Permissions);
- permissions.Sort();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("permissions");
- jsonWriter.WriteStartArray();
- foreach (Permission permission in permissions)
- {
- jsonWriter.WriteStartObject();
- WritePermissionDetails(jsonWriter, permission, null, false);
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- }
- public void GetPermissionDetails(HttpContext context, PermissionSection section)
- {
- UserSession session = context.GetCurrentSession();
- HttpRequest request = context.Request;
- string strSubItem = null;
- switch (section)
- {
- case PermissionSection.Unknown:
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- section = request.GetQueryOrFormEnum<PermissionSection>("section");
- break;
- case PermissionSection.Zones:
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- strSubItem = request.GetQueryOrForm("zone").TrimEnd('.');
- break;
- default:
- throw new InvalidOperationException();
- }
- bool includeUsersAndGroups = request.GetQueryOrForm("includeUsersAndGroups", bool.Parse, false);
- if (strSubItem is not null)
- {
- if (!_dnsWebService._authManager.IsPermitted(section, strSubItem, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- }
- Permission permission;
- if (strSubItem is null)
- permission = _dnsWebService._authManager.GetPermission(section);
- else
- permission = _dnsWebService._authManager.GetPermission(section, strSubItem);
- if (permission is null)
- throw new DnsWebServiceException("No permissions exists for section: " + section.ToString() + (strSubItem is null ? "" : "/" + strSubItem));
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WritePermissionDetails(jsonWriter, permission, strSubItem, includeUsersAndGroups);
- }
- public void SetPermissionsDetails(HttpContext context, PermissionSection section)
- {
- UserSession session = context.GetCurrentSession();
- HttpRequest request = context.Request;
- string strSubItem = null;
- switch (section)
- {
- case PermissionSection.Unknown:
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Administration, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- section = request.GetQueryOrFormEnum<PermissionSection>("section");
- break;
- case PermissionSection.Zones:
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- strSubItem = request.GetQueryOrForm("zone").TrimEnd('.');
- break;
- default:
- throw new InvalidOperationException();
- }
- if (strSubItem is not null)
- {
- if (!_dnsWebService._authManager.IsPermitted(section, strSubItem, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- }
- Permission permission;
- if (strSubItem is null)
- permission = _dnsWebService._authManager.GetPermission(section);
- else
- permission = _dnsWebService._authManager.GetPermission(section, strSubItem);
- if (permission is null)
- throw new DnsWebServiceException("No permissions exists for section: " + section.ToString() + (strSubItem is null ? "" : "/" + strSubItem));
- string strUserPermissions = request.QueryOrForm("userPermissions");
- if (strUserPermissions is not null)
- {
- string[] parts = strUserPermissions.Split('|');
- Dictionary<User, PermissionFlag> userPermissions = new Dictionary<User, PermissionFlag>();
- for (int i = 0; i < parts.Length; i += 4)
- {
- if (parts[i].Length == 0)
- continue;
- User user = _dnsWebService._authManager.GetUser(parts[i]);
- bool canView = bool.Parse(parts[i + 1]);
- bool canModify = bool.Parse(parts[i + 2]);
- bool canDelete = bool.Parse(parts[i + 3]);
- if (user is not null)
- {
- PermissionFlag permissionFlag = PermissionFlag.None;
- if (canView)
- permissionFlag |= PermissionFlag.View;
- if (canModify)
- permissionFlag |= PermissionFlag.Modify;
- if (canDelete)
- permissionFlag |= PermissionFlag.Delete;
- userPermissions[user] = permissionFlag;
- }
- }
- permission.SyncPermissions(userPermissions);
- }
- string strGroupPermissions = request.QueryOrForm("groupPermissions");
- if (strGroupPermissions is not null)
- {
- string[] parts = strGroupPermissions.Split('|');
- Dictionary<Group, PermissionFlag> groupPermissions = new Dictionary<Group, PermissionFlag>();
- for (int i = 0; i < parts.Length; i += 4)
- {
- if (parts[i].Length == 0)
- continue;
- Group group = _dnsWebService._authManager.GetGroup(parts[i]);
- bool canView = bool.Parse(parts[i + 1]);
- bool canModify = bool.Parse(parts[i + 2]);
- bool canDelete = bool.Parse(parts[i + 3]);
- if (group is not null)
- {
- PermissionFlag permissionFlag = PermissionFlag.None;
- if (canView)
- permissionFlag |= PermissionFlag.View;
- if (canModify)
- permissionFlag |= PermissionFlag.Modify;
- if (canDelete)
- permissionFlag |= PermissionFlag.Delete;
- groupPermissions[group] = permissionFlag;
- }
- }
- //ensure administrators group always has all permissions
- Group admins = _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS);
- groupPermissions[admins] = PermissionFlag.ViewModifyDelete;
- switch (section)
- {
- case PermissionSection.Zones:
- //ensure DNS administrators group always has all permissions
- Group dnsAdmins = _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS);
- groupPermissions[dnsAdmins] = PermissionFlag.ViewModifyDelete;
- break;
- case PermissionSection.DhcpServer:
- //ensure DHCP administrators group always has all permissions
- Group dhcpAdmins = _dnsWebService._authManager.GetGroup(Group.DHCP_ADMINISTRATORS);
- groupPermissions[dhcpAdmins] = PermissionFlag.ViewModifyDelete;
- break;
- }
- permission.SyncPermissions(groupPermissions);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Permissions were updated successfully for section: " + section.ToString() + (string.IsNullOrEmpty(strSubItem) ? "" : "/" + strSubItem));
- _dnsWebService._authManager.SaveConfigFile();
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- WritePermissionDetails(jsonWriter, permission, strSubItem, false);
- }
- #endregion
- }
- }
|