Compare commits
1 Commits
04-02-a
...
fab-displa
Author | SHA1 | Date | |
---|---|---|---|
d59c786a26 |
@ -1,116 +0,0 @@
|
|||||||
# AppSettings
|
|
||||||
|
|
||||||
## User Secrets Initialization
|
|
||||||
|
|
||||||
- [app-secrets](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-9.0&tabs=windows)
|
|
||||||
|
|
||||||
```bash 1733926424710 = 638695232247100000 = Wed Dec 11 2024 07:13:44 GMT-0700 (Mountain Standard Time)
|
|
||||||
dotnet user-secrets -p File-Folder-Helper.csproj init
|
|
||||||
```
|
|
||||||
|
|
||||||
- [app-secrets](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-9.0&tabs=windows)
|
|
||||||
|
|
||||||
## User Secrets Add Entry
|
|
||||||
|
|
||||||
```bash 1733926491404 = 638695232914040000 = Wed Dec 11 2024 07:14:50 GMT-0700 (Mountain Standard Time)
|
|
||||||
dotnet user-secrets -p File-Folder-Helper.csproj set Name Value
|
|
||||||
```
|
|
||||||
|
|
||||||
## Optional Symbolic Link in Windows
|
|
||||||
|
|
||||||
- Similar to Linux command ```ln -s```
|
|
||||||
|
|
||||||
```bash 1733926521307 = 638695233213070000 = Wed Dec 11 2024 07:15:20 GMT-0700 (Mountain Standard Time)
|
|
||||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.UserSecrets" "C:\Users\phares\AppData\Roaming\Microsoft\UserSecrets\8da397d4-13ec-4576-9722-3c79cad25563"
|
|
||||||
```
|
|
||||||
|
|
||||||
## .NET Package Reference
|
|
||||||
|
|
||||||
```xml 1733926548840 = 638695233488400000 = Wed Dec 11 2024 07:15:48 GMT-0700 (Mountain Standard Time)
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example Record (Class)
|
|
||||||
|
|
||||||
- ToString is optional for recursive debug and isn't used in code
|
|
||||||
- Verify method helps debug where project is looking for configuration entries
|
|
||||||
- ```configurationRoot.Get<AppSettings>();``` is builtin method to deserialize
|
|
||||||
- JsonSerializerContext is optional for using AOT builds
|
|
||||||
|
|
||||||
```csharp 1733926601507 = 638695234015070000 = Wed Dec 11 2024 07:16:41 GMT-0700 (Mountain Standard Time)
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models;
|
|
||||||
|
|
||||||
public record AppSettings(string Company,
|
|
||||||
string DefaultNoteType,
|
|
||||||
string[] ExcludeDirectoryNames,
|
|
||||||
string[] ExcludeSchemes,
|
|
||||||
string PersonBirthdayFormat,
|
|
||||||
string[] ValidImageFormatExtensions,
|
|
||||||
string WorkingDirectoryName)
|
|
||||||
{
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Verify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
|
||||||
{
|
|
||||||
if (appSettings?.Company is null || string.IsNullOrEmpty(appSettings.Company))
|
|
||||||
{
|
|
||||||
List<string> paths = [];
|
|
||||||
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
|
||||||
{
|
|
||||||
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
|
||||||
continue;
|
|
||||||
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
|
||||||
continue;
|
|
||||||
paths.Add(physicalFileProvider.Root);
|
|
||||||
}
|
|
||||||
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AppSettings Get(IConfigurationRoot configurationRoot)
|
|
||||||
{
|
|
||||||
AppSettings? result;
|
|
||||||
#pragma warning disable IL3050, IL2026
|
|
||||||
result = configurationRoot.Get<AppSettings>();
|
|
||||||
#pragma warning restore IL3050, IL2026
|
|
||||||
Verify(configurationRoot, result);
|
|
||||||
if (result is null)
|
|
||||||
throw new Exception("Not set!");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(AppSettings))]
|
|
||||||
internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## AddUserSecrets to Program.cs
|
|
||||||
|
|
||||||
```csharp 1733926619366 = 638695234193660000 = Wed Dec 11 2024 07:16:58 GMT-0700 (Mountain Standard Time)
|
|
||||||
builder.Configuration.AddUserSecrets<Program>();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Get Instance of Record to Program.cs
|
|
||||||
|
|
||||||
```csharp 1733926659168 = 638695234591680000 = Wed Dec 11 2024 07:17:38 GMT-0700 (Mountain Standard Time)
|
|
||||||
AppSettings appSettings = AppSettings.Get(builder.Configuration);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Add Instance to be Used as Dependency Injected Object
|
|
||||||
|
|
||||||
```csharp 1733926695948 = 638695234959480000 = Wed Dec 11 2024 07:18:15 GMT-0700 (Mountain Standard Time)
|
|
||||||
builder.Services.AddSingleton(appSettings);
|
|
||||||
```
|
|
@ -1,138 +0,0 @@
|
|||||||
# VSCode SSH
|
|
||||||
|
|
||||||
- Allows using VSCode to build code as if you were on remote machine.
|
|
||||||
- Remote machine will still need dotnet SDK
|
|
||||||
|
|
||||||
## Offline Installer
|
|
||||||
|
|
||||||
- Download and copy to servers that can't reach github.com
|
|
||||||
|
|
||||||
- [openssh-portable](https://github.com/PowerShell/openssh-portable)
|
|
||||||
|
|
||||||
## PowerShell Installer
|
|
||||||
|
|
||||||
- PowerShell Administrator
|
|
||||||
|
|
||||||
```PowerShell Administrator 1736187016914 = 638717838169140000 = Mon Jan 06 2025 11:10:16 GMT-0700 (Mountain Standard Time)
|
|
||||||
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
|
|
||||||
# Install the OpenSSH Client
|
|
||||||
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
|
|
||||||
# Install the OpenSSH Server
|
|
||||||
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Generation
|
|
||||||
|
|
||||||
- Run with any user
|
|
||||||
|
|
||||||
```PowerShell 1736187033768 = 638717838337680000 = Mon Jan 06 2025 11:10:33 GMT-0700 (Mountain Standard Time)
|
|
||||||
ssh-keygen -t ed25519
|
|
||||||
```
|
|
||||||
|
|
||||||
## Authentication via Public Key
|
|
||||||
|
|
||||||
- PowerShell Administrator
|
|
||||||
|
|
||||||
```PowerShell Administrator 1736187105777 = 638717839057770000 = Mon Jan 06 2025 11:11:45 GMT-0700 (Mountain Standard Time)
|
|
||||||
copy $env:USERPROFILE\.ssh\id_ed25519.pub C:\ProgramData\ssh\authorized_keys
|
|
||||||
copy $env:USERPROFILE\.ssh\id_ed25519.pub C:\ProgramData\ssh\administrators_authorized_keys
|
|
||||||
icacls.exe "C:\ProgramData\ssh\authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
|
|
||||||
icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
|
|
||||||
```
|
|
||||||
|
|
||||||
- Configuration allows for public key authentication
|
|
||||||
- Removes higher risk password authentication
|
|
||||||
|
|
||||||
```conf 1736187108739 = 638717839087390000 = Mon Jan 06 2025 11:11:48 GMT-0700 (Mountain Standard Time)
|
|
||||||
...
|
|
||||||
PubkeyAuthentication yes
|
|
||||||
...
|
|
||||||
PasswordAuthentication no
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Firewall
|
|
||||||
|
|
||||||
- Open Windows Firewall with Advanced Security GUI
|
|
||||||
- Add new Inbound Rule for port 22
|
|
||||||
- Change Profiles to only enable domain
|
|
||||||
- Change scope to remote ip for your machine
|
|
||||||
|
|
||||||
```bash 1736187743528 = 638717845435280000 = Mon Jan 06 2025 11:22:23 GMT-0700 (Mountain Standard Time)
|
|
||||||
wf.msc
|
|
||||||
```
|
|
||||||
|
|
||||||
- Exported list for the two inbound rules
|
|
||||||
|
|
||||||
```tsv 1736187853968 = 638717846539680000 = Mon Jan 06 2025 11:24:13 GMT-0700 (Mountain Standard Time)
|
|
||||||
Name Group Profile Enabled Action Override Program Local Address Remote Address Protocol Local Port Remote Port Authorized Users Authorized Computers Authorized Local Principals Local User Owner Application Package
|
|
||||||
OpenSSH SSH Server Preview (sshd) Private Yes Allow No C:\Program Files\OpenSSH\sshd.exe Any Any TCP 22 Any Any Any Any Any Any
|
|
||||||
SSH Domain Yes Allow No Any Any 10.64.233.125 TCP 22 Any Any Any Any Any Any
|
|
||||||
```
|
|
||||||
|
|
||||||
- Command line add inbound rule SSH
|
|
||||||
|
|
||||||
```bash 1736188562695 = 638717853626950000 = Mon Jan 06 2025 11:36:02 GMT-0700 (Mountain Standard Time)
|
|
||||||
netsh advfirewall firewall add rule name="SSH" dir=in action=allow enable=yes profile=domain remoteip=10.64.233.125 localport=22 protocol=TCP
|
|
||||||
```
|
|
||||||
|
|
||||||
- Command line to add remote IP
|
|
||||||
|
|
||||||
```bash 1736188289189 = 638717850891890000 = Mon Jan 06 2025 11:31:28 GMT-0700 (Mountain Standard Time)
|
|
||||||
netsh advfirewall firewall set rule name="SSH" new remoteip=10.64.233.125
|
|
||||||
```
|
|
||||||
|
|
||||||
- Command line to enable rule
|
|
||||||
|
|
||||||
```bash 1736188447588 = 638717852475880000 = Mon Jan 06 2025 11:34:07 GMT-0700 (Mountain Standard Time)
|
|
||||||
netsh advfirewall firewall set rule name="SSH" new enable=yes
|
|
||||||
```
|
|
||||||
|
|
||||||
## Local Key Generation
|
|
||||||
|
|
||||||
- Replace user
|
|
||||||
- Run on local machine
|
|
||||||
- Add output to remote machine
|
|
||||||
|
|
||||||
```PowerShell 1736190383218 = 638717871832180000 = Mon Jan 06 2025 12:06:22 GMT-0700 (Mountain Standard Time)
|
|
||||||
ssh-keygen -t ed25519
|
|
||||||
more "C:/Users/user/.ssh/id_ed25519.pub"
|
|
||||||
echo "C:\ProgramData\ssh\authorized_keys"
|
|
||||||
echo "C:\ProgramData\ssh\administrators_authorized_keys"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Test Connection
|
|
||||||
|
|
||||||
- Replace user and machine
|
|
||||||
|
|
||||||
```bash 1736187372778 = 638717841727780000 = Mon Jan 06 2025 11:16:12 GMT-0700 (Mountain Standard Time)
|
|
||||||
ssh user@machine.infineon.com -i C:/Users/user/.ssh/id_ed25519
|
|
||||||
```
|
|
||||||
|
|
||||||
## VSCode
|
|
||||||
|
|
||||||
- Install VSCode extension ms-vscode-remote.remote-ssh
|
|
||||||
- Add machine to VSCode Remote Explorer
|
|
||||||
- Example after adding machine to Remote Explorer "C:\Users\phares\.ssh\config"
|
|
||||||
|
|
||||||
```conf 1736189363973 = 638717861639730000 = Mon Jan 06 2025 11:49:23 GMT-0700 (Mountain Standard Time)
|
|
||||||
Host mestsa003.infineon.com
|
|
||||||
HostName mestsa003.infineon.com
|
|
||||||
User mesphares
|
|
||||||
IdentityFile C:/Users/phares/.ssh/id_ed25519
|
|
||||||
|
|
||||||
Host mestsa05ec.infineon.com
|
|
||||||
HostName mestsa05ec.infineon.com
|
|
||||||
User mesphares
|
|
||||||
IdentityFile C:/Users/phares/.ssh/id_ed25519
|
|
||||||
|
|
||||||
Host mestsa07ec.infineon.com
|
|
||||||
HostName mestsa07ec.infineon.com
|
|
||||||
User mesphares
|
|
||||||
IdentityFile C:/Users/phares/.ssh/id_ed25519
|
|
||||||
|
|
||||||
Host messa010ec.infineon.com
|
|
||||||
HostName messa010ec.infineon.com
|
|
||||||
User mesphares
|
|
||||||
IdentityFile C:/Users/phares/.ssh/id_ed25519
|
|
||||||
```
|
|
@ -8,38 +8,27 @@ updated: 2023-07-08T03:32:53.694Z
|
|||||||
|
|
||||||
## DNS Order
|
## DNS Order
|
||||||
|
|
||||||
- [dns-entry](https://smptools.infineon.com/smptinyurl/orderable/?name=SSO-New%20DNS%20Entry%20%281%29)
|
https://smptools.infineon.com/smptinyurl/orderable/?name=SSO-New%20DNS%20Entry%20%281%29
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Self-signed Certificate
|
## Server Certificate (SSL/TLS) Order
|
||||||
|
|
||||||
|
https://smptools.infineon.com/smptinyurl/orderable/?name=SSO-Certificate%20Request
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd "C:\Program Files\Git\usr\bin"
|
cd "C:\Program Files\Git\usr\bin"
|
||||||
openssl
|
openssl
|
||||||
req -x509 -nodes -days 365 -newkey rsa:2048 -keyout "L:\Git\NGINX-Conf\conf\includes\localhost.key" -out "L:\Git\NGINX-Conf\conf\includes\localhost.crt" -config "L:\Git\NGINX-Conf\conf\includes\localhost.conf"
|
req -x509 -nodes -days 365 -newkey rsa:2048 -keyout L:\Git\NGINX-Conf\conf\includes\localhost.key -out L:\Git\NGINX-Conf\conf\includes\localhost.crt -config L:\Git\NGINX-Conf\conf\includes\localhost.conf
|
||||||
|
req -newkey rsa:2048 -keyout L:\Git\NGINX-Conf\conf\includes\localhost.key -out L:\Git\NGINX-Conf\conf\includes\certificate-signing-request.csr -config L:\Git\NGINX-Conf\conf\includes\localhost.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
```conf
|
|
||||||
ssl_certificate "includes/localhost.crt";
|
|
||||||
ssl_certificate_key "includes/localhost.key";
|
|
||||||
```
|
|
||||||
|
|
||||||
## Server Certificate (SSL/TLS) Order
|
|
||||||
|
|
||||||
- [certificate-request](https://smptools.infineon.com/smptinyurl/orderable/?name=SSO-Certificate%20Request)
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Example for eaf-dev-reporting.mes.infineon.com
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd "C:\Program Files\Git\usr\bin"
|
# ssl_certificate "includes/localhost.crt";
|
||||||
openssl
|
# ssl_certificate_key "includes/localhost.key";
|
||||||
req -newkey rsa:2048 -keyout "L:\Git\NGINX-Conf\conf\includes\eaf-dev-reporting.mes.infineon.com.key" -out "L:\Git\NGINX-Conf\conf\includes\certificate-signing-request.csr" -config "L:\Git\NGINX-Conf\conf\includes\eaf-dev-reporting.mes.infineon.com.conf"
|
|
||||||
```
|
|
||||||
|
|
||||||
```conf
|
|
||||||
ssl_certificate "includes/eaf-dev-reporting.mes.infineon.com.cer";
|
ssl_certificate "includes/eaf-dev-reporting.mes.infineon.com.cer";
|
||||||
ssl_password_file "includes/eaf-dev-reporting.mes.infineon.com.pass";
|
ssl_password_file "includes/eaf-dev-reporting.mes.infineon.com.pass";
|
||||||
ssl_certificate_key "includes/eaf-dev-reporting.mes.infineon.com.key";
|
ssl_certificate_key "includes/eaf-dev-reporting.mes.infineon.com.key";
|
||||||
|
@ -8,32 +8,30 @@ updated: 2023-11-10T16:14:48.030Z
|
|||||||
|
|
||||||
I have determined a useful method to provisioning and managing fab display clients(slideshows).
|
I have determined a useful method to provisioning and managing fab display clients(slideshows).
|
||||||
One of the main struggles here is maintenance of the device. Such as remote access. For a non fab client, by default the logged in user has to verify connections. The second struggle is that the display turns off after a period of time.
|
One of the main struggles here is maintenance of the device. Such as remote access. For a non fab client, by default the logged in user has to verify connections. The second struggle is that the display turns off after a period of time.
|
||||||
## Configuring Auto Logon
|
|
||||||
<ul>
|
|
||||||
I have had an account setup in the INFINEON domain. This account can be used as it has a password that never expires. The password is stored in the Mesa FI password manager on IShare. [Available here](https://ishare.na.infineon.com/sites/MesaFI/FI%20Internal/KeePass/FICredentials.kdbx)</li>
|
|
||||||
<li>We need to configure auto logon. So using an account with admin rights we need to open Regedit. </li>
|
|
||||||
<li>Once we are in regedit we navigate to: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon</li>
|
|
||||||
<li>
|
|
||||||
Then we need to create and set three keys and their respective string values.
|
|
||||||
<ul>
|
|
||||||
<li>AutoAdminLogon - 1
|
|
||||||
<li>DefaultUserName - MesaDisplay
|
|
||||||
<li>DefaultPassword - See FI Keepass file.
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
##Configuring SlideShow at Startup
|
## Configuring Auto Logon
|
||||||
|
|
||||||
|
I have had an account setup in the INFINEON domain. This account can be used as it has a password that never expires. The password is stored in the Mesa FI password manager on IShare. [Available here](https://ishare.na.infineon.com/sites/MesaFI/FI%20Internal/KeePass/FICredentials.kdbx)
|
||||||
|
|
||||||
|
- We need to configure auto logon. So using an account with admin rights we need to open Regedit.
|
||||||
|
- Once we are in regedit we navigate to: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
|
||||||
|
- Then we need to create and set three keys and their respective string values.
|
||||||
|
- AutoAdminLogon - 1
|
||||||
|
- DefaultUserName - MesaDisplay
|
||||||
|
- DefaultPassword - See FI Keepass file.
|
||||||
|
|
||||||
|
## Configuring SlideShow at Startup
|
||||||
The slideshow I was wishing to display was on a website. So what I did was create a batch script that opened edge with the url to the slideshow as an argument.
|
The slideshow I was wishing to display was on a website. So what I did was create a batch script that opened edge with the url to the slideshow as an argument.
|
||||||
See the batch script in the code block below. I then created a task to run at logon of any user to execute this script. Important to note. The default setting pushed via Group Policy will set the screen timeout. At the direction of local IT have decided to use an application called MouseJiggle to keep the screen on. That will need to be set in the batch script as well. The switches -j -z -m will ensure the application starts hidden.
|
See the batch script in the code block below. I then created a task to run at logon of any user to execute this script. Important to note. The default setting pushed via Group Policy will set the screen timeout. At the direction of local IT have decided to use an application called MouseJiggle to keep the screen on. That will need to be set in the batch script as well. The switches -j -z -m will ensure the application starts hidden.
|
||||||
```
|
|
||||||
start "edge" "c:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" "https://messa004.infineon.com/fabtime717/Home.html?SlideShowView=1&HomePageTab=Cleanroom_Slide_Show&HomePageUserID=3443&LinkerUserID=&CurrentChart=5&Width=1150&Height=620&CurrentChart=4&AutoPlay=30" --start-fullscreen
|
```bash
|
||||||
start C:\users\%USERNAME%\Desktop\MouseJiggle.exe -j -z -m
|
start "edge" "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" "https://messa004.infineon.com/fabtime717/Home.html?SlideShowView=1&HomePageTab=Cleanroom_Slide_Show&HomePageUserID=3443&LinkerUserID=&CurrentChart=5&Width=1150&Height=620&CurrentChart=4&AutoPlay=30" --start-fullscreen
|
||||||
|
start "C:\users\%USERNAME%\Desktop\MouseJiggle.exe" -j -z -m
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuring VNC for remote management
|
## Configuring VNC for remote management
|
||||||
|
|
||||||
This is a bit of a workaround because again the VNC settings are pushed via Group policy.
|
This is a bit of a workaround because again the VNC settings are pushed via Group policy.
|
||||||
|
|
||||||
1. First request and install RealVNC server to be installed via the IFX AppStore.
|
1. First request and install RealVNC server to be installed via the IFX AppStore.
|
||||||
@ -45,7 +43,6 @@ Windows Registry Editor Version 5.00
|
|||||||
|
|
||||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\RealVNC\vncserver]
|
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\RealVNC\vncserver]
|
||||||
"QueryConnect"="0"
|
"QueryConnect"="0"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
4. I then create a task to run immediately at logon and repeating every 30 minutes that runs the regedit.exe file. This must be run with highest permissions and with the local SYSTEM account.
|
4. I then create a task to run immediately at logon and repeating every 30 minutes that runs the regedit.exe file. This must be run with highest permissions and with the local SYSTEM account.
|
||||||
|
Reference in New Issue
Block a user