initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,137 @@
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui;
using Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome;
using Unity.PlasticSCM.Editor.WebApi;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal static class AutoConfig
{
internal static TokenExchangeResponse PlasticCredentials(
string unityAccessToken,
string serverName,
string projectPath)
{
SetupUnityEditionToken.CreateCloudEditionTokenIfNeeded();
bool isClientConfigConfigured = ClientConfig.IsConfigured();
if (!isClientConfigConfigured)
{
ConfigureClientConf.FromUnityAccessToken(
unityAccessToken, serverName, projectPath);
}
TokenExchangeResponse tokenExchangeResponse = WebRestApiClient.
PlasticScm.TokenExchange(unityAccessToken);
if (tokenExchangeResponse.Error != null)
return tokenExchangeResponse;
CloudEditionWelcomeWindow.JoinCloudServer(
serverName,
tokenExchangeResponse.User,
tokenExchangeResponse.AccessToken);
if (!isClientConfigConfigured)
return tokenExchangeResponse;
ConfigureProfile.ForServerIfNeeded(
serverName,
tokenExchangeResponse.User);
return tokenExchangeResponse;
}
static class ConfigureClientConf
{
internal static void FromUnityAccessToken(
string unityAccessToken,
string serverName,
string projectPath)
{
CredentialsResponse response = WebRestApiClient.
PlasticScm.GetCredentials(unityAccessToken);
if (response.Error != null)
{
UnityEngine.Debug.LogErrorFormat(
PlasticLocalization.GetString(
PlasticLocalization.Name.ErrorGettingCredentialsCloudProject),
response.Error.Message,
response.Error.ErrorCode);
return;
}
ClientConfigData configData = BuildClientConfigData(
serverName, projectPath, response);
ClientConfig.Get().Save(configData);
}
static ClientConfigData BuildClientConfigData(
string serverName,
string projectPath,
CredentialsResponse response)
{
SEIDWorkingMode workingMode = GetWorkingMode(response.Type);
ClientConfigData configData = new ClientConfigData();
configData.WorkspaceServer = serverName;
configData.CurrentWorkspace = projectPath;
configData.WorkingMode = workingMode.ToString();
configData.SecurityConfig = UserInfo.GetSecurityConfigStr(
workingMode,
response.Email,
GetPassword(response.Token, response.Type));
configData.LastRunningEdition = InstalledEdition.Get();
return configData;
}
static string GetPassword(
string token,
CredentialsResponse.TokenType tokenType)
{
if (tokenType == CredentialsResponse.TokenType.Bearer)
return BEARER_PREFIX + token;
return token;
}
static SEIDWorkingMode GetWorkingMode(CredentialsResponse.TokenType tokenType)
{
if (tokenType == CredentialsResponse.TokenType.Bearer)
return SEIDWorkingMode.SSOWorkingMode;
return SEIDWorkingMode.LDAPWorkingMode;
}
const string BEARER_PREFIX = "Bearer ";
}
static class ConfigureProfile
{
internal static void ForServerIfNeeded(string serverName, string user)
{
ProfileManager profileManager = CmConnection.Get().GetProfileManager();
ServerProfile serverProfile = profileManager.GetProfileForServer(serverName);
if (serverProfile != null)
return;
serverProfile = ProfileManager.CreateProfile(
serverName,
SEIDWorkingMode.SSOWorkingMode,
user);
profileManager.SaveProfile(serverProfile);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c21251ff4b7d844292a388e81e47e59
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,93 @@
using Codice.Client.Common;
using Codice.CM.Common;
using PlasticGui;
using PlasticPipe.Certificates;
using Unity.PlasticSCM.Editor.UI;
using UnityEditor;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class ChannelCertificateUiImpl : IChannelCertificateUI
{
internal ChannelCertificateUiImpl()
{
}
CertOperationResult IChannelCertificateUI.AcceptNewServerCertificate(PlasticCertInfo serverCertificate)
{
return GetUserResponse(
PlasticLocalization.GetString(
PlasticLocalization.Name.NewCertificateTitle),
PlasticLocalization.GetString(
PlasticLocalization.Name.NewCertificateMessage),
serverCertificate);
}
CertOperationResult IChannelCertificateUI.AcceptChangedServerCertificate(PlasticCertInfo serverCertificate)
{
return GetUserResponse(
PlasticLocalization.GetString(
PlasticLocalization.Name.ExistingCertificateChangedTitle),
PlasticLocalization.GetString(
PlasticLocalization.Name.ExistingCertificateChangedMessage),
serverCertificate);
}
bool IChannelCertificateUI.AcceptInvalidHostname(string certHostname, string serverHostname)
{
bool result = false;
GUIActionRunner.RunGUIAction(delegate {
result = EditorUtility.DisplayDialog(
PlasticLocalization.GetString(
PlasticLocalization.Name.InvalidCertificateHostnameTitle),
PlasticLocalization.GetString(
PlasticLocalization.Name.InvalidCertificateHostnameMessage,
certHostname, serverHostname),
PlasticLocalization.GetString(PlasticLocalization.Name.YesButton),
PlasticLocalization.GetString(PlasticLocalization.Name.NoButton));
});
return result;
}
CertOperationResult GetUserResponse(
string title, string message, PlasticCertInfo serverCertificate)
{
GuiMessage.GuiMessageResponseButton result =
GuiMessage.GuiMessageResponseButton.Neutral;
GUIActionRunner.RunGUIAction(delegate {
result = GuiMessage.ShowQuestion(
title,
GetCertificateMessageString(message, serverCertificate),
PlasticLocalization.GetString(PlasticLocalization.Name.YesButton),
PlasticLocalization.GetString(PlasticLocalization.Name.CancelButton),
PlasticLocalization.GetString(PlasticLocalization.Name.NoButton));
});
switch (result)
{
case GuiMessage.GuiMessageResponseButton.Positive:
return CertOperationResult.AddToStore;
case GuiMessage.GuiMessageResponseButton.Negative:
return CertOperationResult.DoNotAddToStore;
case GuiMessage.GuiMessageResponseButton.Neutral:
return CertOperationResult.Cancel;
default:
return CertOperationResult.Cancel;
}
}
string GetCertificateMessageString(string message, PlasticCertInfo serverCertificate)
{
return string.Format(message,
CertificateUi.GetCnField(serverCertificate.Subject),
CertificateUi.GetCnField(serverCertificate.Issuer),
serverCertificate.Format,
serverCertificate.ExpirationDateString,
serverCertificate.KeyAlgorithm,
serverCertificate.CertHashString);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 628bc1ed591aa164ab9124ac22e02d9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0b593e05bcd27824eb229f8c6b20e13b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 86d9084a265d35f4db65c4e31e0b6769
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.Threading;
using Codice.LogWrapper;
using PlasticGui.Configuration.CloudEdition.Welcome;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Unity.PlasticSCM.Editor.WebApi;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class AutoLogin : OAuthSignIn.INotify
{
internal enum State : byte
{
Off = 0,
Started = 1,
Running = 2,
ResponseInit = 3,
ResponseEnd = 6,
ResponseSuccess = 7,
OrganizationChoosed = 8,
InitializingPlastic = 9,
ErrorNoToken = 20,
ErrorTokenException = 21,
ErrorResponseNull = 22,
ErrorResponseError = 23,
ErrorTokenEmpty = 24,
ErrorResponseCancel = 25
}
internal string AccessToken;
internal string UserName;
internal void Run()
{
mPlasticWindow = GetPlasticWindow();
if (!string.IsNullOrEmpty(CloudProjectSettings.accessToken))
{
ExchangeTokensAndJoinOrganization(CloudProjectSettings.accessToken);
return;
}
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ErrorNoToken;
}
void OAuthSignIn.INotify.SuccessForConfigure(
List<string> organizations,
bool canCreateAnOrganization,
string userName,
string accessToken)
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ResponseSuccess;
ChooseOrganization(organizations, canCreateAnOrganization);
}
void OAuthSignIn.INotify.SuccessForSSO(string organization)
{
}
void OAuthSignIn.INotify.SuccessForProfile(string email)
{
}
void OAuthSignIn.INotify.SuccessForHomeView(string userName)
{
}
void OAuthSignIn.INotify.SuccessForCredentials(
string email,
string accessToken)
{
}
void OAuthSignIn.INotify.Cancel(string errorMessage)
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ErrorResponseCancel;
}
void ExchangeTokensAndJoinOrganization(string unityAccessToken)
{
int ini = Environment.TickCount;
TokenExchangeResponse response = null;
IThreadWaiter waiter = ThreadWaiter.GetWaiter(10);
waiter.Execute(
/*threadOperationDelegate*/ delegate
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ResponseInit;
response = WebRestApiClient.PlasticScm.TokenExchange(unityAccessToken);
},
/*afterOperationDelegate*/ delegate
{
mLog.DebugFormat(
"TokenExchange time {0} ms",
Environment.TickCount - ini);
if (waiter.Exception != null)
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ErrorTokenException;
ExceptionsHandler.LogException(
"TokenExchangeSetting",
waiter.Exception);
Debug.LogWarning(waiter.Exception.Message);
return;
}
if (response == null)
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ErrorResponseNull;
Debug.LogWarning("Auto Login response null");
return;
}
if (response.Error != null)
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ErrorResponseError;
var warning = string.Format(
"Unable to exchange token: {0} [code {1}]",
response.Error.Message, response.Error.ErrorCode);
mLog.ErrorFormat(warning);
Debug.LogWarning(warning);
return;
}
if (string.IsNullOrEmpty(response.AccessToken))
{
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ErrorTokenEmpty;
var warning = string.Format(
"Access token is empty for user: {0}",
response.User);
mLog.InfoFormat(warning);
Debug.LogWarning(warning);
return;
}
mPlasticWindow.GetWelcomeView().autoLoginState = AutoLogin.State.ResponseEnd;
AccessToken = response.AccessToken;
UserName = response.User;
GetOrganizationList();
});
}
void GetOrganizationList()
{
OAuthSignIn.GetOrganizationsFromAccessToken(
PlasticGui.Plastic.WebRestAPI,
new ProgressControlsForDialogs(),
this,
string.Empty,
CloudProjectSettings.userName,
AccessToken,
OAuthSignIn.Mode.Configure
);
}
void ChooseOrganization(
List<string> organizations,
bool canCreateAnOrganization)
{
mPlasticWindow = GetPlasticWindow();
CloudEditionWelcomeWindow.ShowWindow(
PlasticGui.Plastic.WebRestAPI,
mPlasticWindow.CmConnectionForTesting, null, true);
mCloudEditionWelcomeWindow = CloudEditionWelcomeWindow.GetWelcomeWindow();
mCloudEditionWelcomeWindow.FillUserAndToken(UserName, AccessToken);
if (organizations.Count == 1)
{
mCloudEditionWelcomeWindow.JoinOrganizationAndWelcomePage(organizations[0]);
return;
}
mCloudEditionWelcomeWindow.ShowOrganizationPanelFromAutoLogin(organizations, canCreateAnOrganization);
}
static PlasticWindow GetPlasticWindow()
{
var windows = Resources.FindObjectsOfTypeAll<PlasticWindow>();
PlasticWindow plasticWindow = windows.Length > 0 ? windows[0] : null;
if (plasticWindow == null)
plasticWindow = ShowWindow.Plastic();
return plasticWindow;
}
PlasticWindow mPlasticWindow;
CloudEditionWelcomeWindow mCloudEditionWelcomeWindow;
static readonly ILog mLog = LogManager.GetLogger("TokensExchange");
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 806bdb4f911275c4ca1ee81fde4b4d4f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,343 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using PlasticGui;
using PlasticGui.WebApi;
using Unity.PlasticSCM.Editor.UI.UIElements;
using PlasticGui.Configuration.CloudEdition.Welcome;
using System.Collections.Generic;
using Codice.Client.Common.Servers;
using Codice.Client.Common;
using Codice.Utils;
using Unity.PlasticSCM.Editor.Views.Welcome;
using Codice.CM.Common;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal interface IWelcomeWindowNotify
{
void SuccessForConfigure(List<string> organizations, bool canCreateAnOrganization);
void SuccessForSSO(string organization);
void SuccessForCredentials(string userName, string password);
void SuccessForProfile(string userName);
void SignUpNeeded(string user, string password);
void Back();
}
internal class CloudEditionWelcomeWindow :
EditorWindow,
OAuthSignIn.INotify,
IWelcomeWindowNotify
{
internal static void ShowWindow(
IPlasticWebRestApi restApi,
CmConnection cmConnection,
WelcomeView welcomeView,
bool autoLogin = false)
{
sRestApi = restApi;
sCmConnection = cmConnection;
sAutoLogin = autoLogin;
CloudEditionWelcomeWindow window = GetWindow<CloudEditionWelcomeWindow>();
window.titleContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.SignInToPlasticSCM));
window.minSize = window.maxSize = new Vector2(500, 460);
window.mWelcomeView = welcomeView;
window.Show();
}
internal static CloudEditionWelcomeWindow GetWelcomeWindow()
{
return GetWindow<CloudEditionWelcomeWindow>();
}
void OnEnable()
{
BuildComponents();
}
internal void CancelJoinOrganization()
{
if (sAutoLogin)
{
GetWindow<PlasticWindow>().GetWelcomeView().autoLoginState = AutoLogin.State.Started;
}
}
internal void JoinOrganizationAndWelcomePage(string organization)
{
JoinCloudServer(organization,
mUserName,
mAccessToken);
GetWelcomePage.Run(sRestApi, organization);
}
internal static void JoinCloudServer(
string cloudServer,
string username,
string accessToken)
{
SaveCloudServer.ToPlasticGuiConfig(cloudServer);
SaveCloudServer.ToPlasticGuiConfigFile(
cloudServer, GetPlasticConfigFileToSaveOrganization());
SaveCloudServer.ToPlasticGuiConfigFile(
cloudServer, GetGluonConfigFileToSaveOrganization());
KnownServers.ServersFromCloud.InitializeForWindows(
PlasticGuiConfig.Get().Configuration.DefaultCloudServer);
CloudEditionWelcome.WriteToTokensConf(
cloudServer, username, accessToken);
SetupUnityEditionToken.CreateCloudEditionTokenIfNeeded();
if (sAutoLogin)
{
ClientConfigData clientConfigData = ConfigurationChecker.GetClientConfigData();
clientConfigData.WorkspaceServer = cloudServer;
clientConfigData.WorkingMode = SEIDWorkingMode.SSOWorkingMode.ToString();
clientConfigData.SecurityConfig = username;
ClientConfig.Get().Save(clientConfigData);
GetWindow<PlasticWindow>().GetWelcomeView().autoLoginState = AutoLogin.State.OrganizationChoosed;
}
}
internal void ReplaceRootPanel(VisualElement panel)
{
rootVisualElement.Clear();
rootVisualElement.Add(panel);
}
void OnDestroy()
{
Dispose();
if (mWelcomeView != null)
mWelcomeView.OnUserClosedConfigurationWindow();
}
void Dispose()
{
if (mSignInPanel != null)
mSignInPanel.Dispose();
if (mSSOSignUpPanel != null)
mSSOSignUpPanel.Dispose();
if (mOrganizationPanel != null)
mOrganizationPanel.Dispose();
}
void OAuthSignIn.INotify.SuccessForConfigure(
List<string> organizations,
bool canCreateAnOrganization,
string userName,
string accessToken)
{
ShowOrganizationPanel(
GetWindowTitle(),
organizations,
canCreateAnOrganization);
Focus();
mUserName = userName;
mAccessToken = accessToken;
}
internal void ShowOrganizationPanel(
string title,
List<string> organizations,
bool canCreateAnOrganization)
{
mOrganizationPanel = new OrganizationPanel(
this,
sRestApi,
title,
organizations,
canCreateAnOrganization);
ReplaceRootPanel(mOrganizationPanel);
}
void OAuthSignIn.INotify.SuccessForSSO(string organization)
{
// empty implementation
}
void OAuthSignIn.INotify.SuccessForProfile(string email)
{
// empty implementation
}
void OAuthSignIn.INotify.SuccessForHomeView(string homeView)
{
// empty implementation
}
void OAuthSignIn.INotify.SuccessForCredentials(
string email,
string accessToken)
{
// empty implementation
}
void OAuthSignIn.INotify.Cancel(string errorMessage)
{
Focus();
}
void IWelcomeWindowNotify.SuccessForConfigure(
List<string> organizations,
bool canCreateAnOrganization)
{
ShowOrganizationPanel(
GetWindowTitle(),
organizations,
canCreateAnOrganization);
}
internal void FillUserAndToken(
string userName,
string accessToken)
{
mUserName = userName;
mAccessToken = accessToken;
}
internal void ShowOrganizationPanelFromAutoLogin(
List<string> organizations,
bool canCreateAnOrganization)
{
ShowOrganizationPanel(
GetWindowTitle(),
organizations,
canCreateAnOrganization);
}
void IWelcomeWindowNotify.SuccessForSSO(string organization)
{
// empty implementation
}
void IWelcomeWindowNotify.SuccessForCredentials(string userName, string password)
{
// empty implementation
}
void IWelcomeWindowNotify.SuccessForProfile(string userName)
{
// empty implementation
}
void IWelcomeWindowNotify.SignUpNeeded(
string user,
string password)
{
SwitchToSignUpPage(user, password);
}
void IWelcomeWindowNotify.Back()
{
rootVisualElement.Clear();
rootVisualElement.Add(mTabView);
}
void SwitchToSignUpPage(
string user,
string password)
{
mSSOSignUpPanel.SetSignUpData(user, password);
rootVisualElement.Clear();
rootVisualElement.Add(mTabView);
mTabView.SwitchContent(mSSOSignUpPanel);
}
string GetWindowTitle()
{
return mIsOnSignIn ?
PlasticLocalization.GetString(PlasticLocalization.Name.SignInToPlasticSCM) :
PlasticLocalization.GetString(PlasticLocalization.Name.SignUp);
}
internal static string GetPlasticConfigFileToSaveOrganization()
{
if (PlatformIdentifier.IsMac())
{
return "macgui.conf";
}
return "plasticgui.conf";
}
internal static string GetGluonConfigFileToSaveOrganization()
{
if (PlatformIdentifier.IsMac())
{
return "gluon.conf";
}
return "gameui.conf";
}
void BuildComponents()
{
VisualElement root = rootVisualElement;
root.Clear();
mTabView = new TabView();
mSignInPanel = new SignInPanel(
this,
sRestApi,
sCmConnection);
mSSOSignUpPanel = new SSOSignUpPanel(
this,
sRestApi,
sCmConnection);
mTabView.AddTab(
PlasticLocalization.GetString(PlasticLocalization.Name.SignIn),
mSignInPanel).clicked += () =>
{
mIsOnSignIn = true;
titleContent = new GUIContent(GetWindowTitle());
};
mTabView.AddTab(
PlasticLocalization.GetString(PlasticLocalization.Name.SignUp),
mSSOSignUpPanel).clicked += () =>
{
mIsOnSignIn = false;
titleContent = new GUIContent(GetWindowTitle());
};
root.Add(mTabView);
if (sAutoLogin)
mSignInPanel.SignInWithUnityIdButtonAutoLogin();
}
internal TabView mTabView;
OrganizationPanel mOrganizationPanel;
SignInPanel mSignInPanel;
SSOSignUpPanel mSSOSignUpPanel;
WelcomeView mWelcomeView;
string mUserName;
string mAccessToken;
bool mIsOnSignIn = true;
static IPlasticWebRestApi sRestApi;
static CmConnection sCmConnection;
static bool sAutoLogin = false;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ad54f9e1bb701142b116d0d1ed98437
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,277 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.UIElements;
using PlasticGui.WebApi;
using PlasticGui.Configuration.CloudEdition.Welcome;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class CreateOrganizationPanel :
VisualElement,
IsValidOrganization.INotify,
GetDatacenters.INotify,
CreateOrganization.INotify
{
internal CreateOrganizationPanel(
CloudEditionWelcomeWindow parentWindow,
VisualElement parentPanel,
IPlasticWebRestApi restApi)
{
mParentWindow = parentWindow;
mParentPanel = parentPanel;
mRestApi = restApi;
InitializeLayoutAndStyles();
BuildComponents();
var progressControls = new ProgressControlsForDialogs(new VisualElement[] { mCreateButton, mBackButton });
mProgressControls = progressControls;
mGettingDatacentersProgressContainer.Add(progressControls);
GetDatacenters.Run(
mRestApi, mProgressControls, this);
}
internal void Dispose()
{
mCreateButton.clicked -= CreateButton_Clicked;
mOrganizationNameTextField.UnregisterValueChangedCallback(
OnOrganizationNameTextFieldChanged);
}
void OnOrganizationNameTextFieldChanged(ChangeEvent<string> evt)
{
mOrganizationNameNotification.text = "";
}
void DataCenterClicked(DropdownMenuAction action)
{
mSelectedDatacenter = action.name;
mDatacenter.text = action.name;
}
void DisplayAlert(Label label, string alert, Color color, bool display)
{
label.text = alert;
label.style.color = color;
if (alert.Length > 130)
label.style.marginBottom = 30;
else
label.style.marginBottom = 5;
if (display)
label.RemoveFromClassList("hidden");
else
label.AddToClassList("hidden");
}
void GetDatacenters.INotify.Success(
List<string> datacenters, int defaultDatacenter)
{
mSelectedDatacenter = datacenters.FirstOrDefault();
mDatacenter = new ToolbarMenu { text = mSelectedDatacenter };
foreach (string datacenter in datacenters)
mDatacenter.menu.AppendAction(datacenter, DataCenterClicked, DataCenterActive);
VisualElement datacenterContainer = this.Q<VisualElement>("datacenter");
datacenterContainer.Add(mDatacenter);
}
void GetDatacenters.INotify.Error(string message)
{
DisplayAlert(mDataCenterRetryAlert, message, Color.red, true);
mDataCenterRetryButton.RemoveFromClassList("hidden");
}
void IsValidOrganization.INotify.OrganizationAvailable(string organizationName)
{
if (organizationName != mOrganizationNameTextField.text)
return;
DisplayAlert(
mOrganizationNameNotification,
PlasticLocalization.GetString(PlasticLocalization.Name.Available),
Color.green,
true);
}
void IsValidOrganization.INotify.OrganizationUnavailable(string organizationName)
{
if (organizationName != mOrganizationNameTextField.text)
return;
DisplayAlert(
mOrganizationNameNotification,
PlasticLocalization.GetString(PlasticLocalization.Name.Unavailable),
Color.red,
true);
}
void IsValidOrganization.INotify.ValidationFailed(string validationResult)
{
DisplayAlert(
mOrganizationNameNotification,
validationResult,
Color.red,
true);
}
void IsValidOrganization.INotify.Error(string organizationName, string message)
{
if (organizationName != mOrganizationNameTextField.text)
return;
DisplayAlert(
mOrganizationNameNotification,
message,
Color.red,
true);
}
void CreateOrganization.INotify.Success(string organizationName)
{
mParentWindow.ReplaceRootPanel(new CreatedOrganizationPanel(
organizationName,
mParentWindow));
}
void CreateOrganization.INotify.ValidationFailed(
CreateOrganization.ValidationResult validationResult)
{
if (validationResult.OrganizationError != null)
DisplayAlert(
mOrganizationNameNotification,
validationResult.OrganizationError,
Color.red,
true);
if (validationResult.DatacenterError != null)
DisplayAlert(
mOrganizationNameNotification,
validationResult.DatacenterError,
Color.red,
true);
}
void CreateOrganization.INotify.OrganizationUnavailable()
{
DisplayAlert(
mOrganizationNameNotification,
PlasticLocalization.GetString(PlasticLocalization.Name.Unavailable),
Color.red,
true);
}
void CreateOrganization.INotify.Error(string message)
{
mProgressControls.ShowError(message);
}
void OrganizationNameTextBox_DelayedTextChanged()
{
IsValidOrganization.Run(
mRestApi, mOrganizationNameTextField.text, this);
}
void GetDatacentersRetryButton_Click()
{
mDataCenterRetryContainer.AddToClassList("hidden");
GetDatacenters.Run(mRestApi, mProgressControls, this);
}
void BackButton_Clicked()
{
mParentWindow.ReplaceRootPanel(mParentPanel);
}
void CreateButton_Clicked()
{
CreateOrganization.Run(
mRestApi,
new CreateOrganization.Data(
mOrganizationNameTextField.text,
mDatacenter.text,
false),
mProgressControls,
this);
}
DropdownMenuAction.Status DataCenterActive(DropdownMenuAction action)
{
if (action.name == mSelectedDatacenter)
return DropdownMenuAction.Status.Checked;
return DropdownMenuAction.Status.Normal;
}
void BuildComponents()
{
mOrganizationNameTextField = this.Q<TextField>("orgName");
mOrganizationNameTextField.RegisterValueChangedCallback(
x => OrganizationNameTextBox_DelayedTextChanged());
mOrganizationNameNotification = this.Q<Label>("orgNameNotification");
mDataCenterRetryContainer = this.Q<VisualElement>("dataCenterRetryContainer");
mDataCenterRetryAlert = this.Q<Label>("dataCenterRetryAlert");
mDataCenterRetryButton = this.Q<Button>("dataCenterRetryButton");
mDataCenterRetryButton.clicked += GetDatacentersRetryButton_Click;
mBackButton = this.Q<Button>("back");
mBackButton.clicked += BackButton_Clicked;
mCreateButton = this.Q<Button>("create");
mCreateButton.clicked += CreateButton_Clicked;
mGettingDatacentersProgressContainer = this.Q<VisualElement>("gettingDatacenters");
mOrganizationNameTextField.RegisterValueChangedCallback(
OnOrganizationNameTextFieldChanged);
mOrganizationNameTextField.FocusOnceLoaded();
this.SetControlText<Label>("createLabel",
PlasticLocalization.Name.CreateOrganizationTitle);
this.SetControlLabel<TextField>("orgName",
PlasticLocalization.Name.OrganizationName);
this.SetControlText<Label>("datacenterLabel",
PlasticLocalization.Name.Datacenter);
this.SetControlText<Button>("back",
PlasticLocalization.Name.BackButton);
this.SetControlText<Button>("create",
PlasticLocalization.Name.CreateButton);
}
void InitializeLayoutAndStyles()
{
this.LoadLayout(typeof(CreateOrganizationPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(CreateOrganizationPanel).Name);
}
CloudEditionWelcomeWindow mParentWindow;
VisualElement mParentPanel;
TextField mOrganizationNameTextField;
Label mOrganizationNameNotification;
VisualElement mDataCenterRetryContainer;
Label mDataCenterRetryAlert;
Button mDataCenterRetryButton;
ToolbarMenu mDatacenter;
Button mBackButton;
Button mCreateButton;
VisualElement mGettingDatacentersProgressContainer;
string mSelectedDatacenter;
IProgressControls mProgressControls;
readonly IPlasticWebRestApi mRestApi;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2104516cde04b204884f055f58f980d3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,54 @@
using UnityEngine.UIElements;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.UIElements;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class CreatedOrganizationPanel : VisualElement
{
internal CreatedOrganizationPanel(string organizationName, CloudEditionWelcomeWindow parentWindow)
{
mOrganizationName = organizationName;
mParentWindow = parentWindow;
InitializeLayoutAndStyles();
BuildComponents();
}
void BuildComponents()
{
this.SetControlText<Label>("createdTitle",
PlasticLocalization.Name.CreatedOrganizationTitle);
this.SetControlText<Label>("createdExplanation",
PlasticLocalization.Name.CreatedOrganizationExplanation, mOrganizationName);
this.Q<Button>("continue").clicked += ContinueButton_Clicked;
this.SetControlText<Button>("continue",
PlasticLocalization.Name.ContinueButton);
}
void InitializeLayoutAndStyles()
{
this.LoadLayout(typeof(CreatedOrganizationPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(CreatedOrganizationPanel).Name);
}
void ContinueButton_Clicked()
{
mParentWindow.JoinOrganizationAndWelcomePage(mOrganizationName);
mParentWindow.Close();
}
internal void Dispose()
{
this.Q<Button>("continue").clicked -= ContinueButton_Clicked;
}
string mOrganizationName;
CloudEditionWelcomeWindow mParentWindow;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8add2d9bdefea9d4ead4e1c5163c87c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,161 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.UIElements;
using PlasticGui.WebApi;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class OrganizationPanel : VisualElement
{
internal OrganizationPanel(
CloudEditionWelcomeWindow parentWindow,
IPlasticWebRestApi restApi,
string title,
List<string> organizations,
bool canCreateAnOrganization)
{
mParentWindow = parentWindow;
mRestApi = restApi;
mOrganizations = organizations;
InitializeLayoutAndStyles();
BuildComponents(title, canCreateAnOrganization);
}
void BuildComponents(string title, bool canCreateAnOrganization)
{
mParentWindow.titleContent = new UnityEngine.GUIContent(title);
this.SetControlText<Label>("confirmationMessage",
PlasticLocalization.Name.SignedUpTitle);
if (mOrganizations.Count == 1)
{
BuildSingleOrganizationSection(mOrganizations.First());
mJoinSingleOrganizationButton = this.Q<Button>("joinSingleOrganizationButton");
mJoinSingleOrganizationButton.clicked += JoinOrganizationButton_clicked;
}
else if (mOrganizations.Count > 1)
{
BuildMultipleOrganizationsSection(mOrganizations);
mJoinMultipleOrganizationsButton = this.Q<Button>("joinMultipleOrganizationsButton");
mJoinMultipleOrganizationsButton.clicked += JoinOrganizationButton_clicked;
mOrganizationToJoin = mOrganizations.First();
}
if (canCreateAnOrganization)
{
BuildCreateOrganizationSection(!mOrganizations.Any());
mCreateOrganizationButton = this.Q<Button>("createOrganizationButton");
mCreateOrganizationButton.clicked += CreateOrganizationButton_Clicked;
}
}
internal void Dispose()
{
mParentWindow.CancelJoinOrganization();
if (mJoinSingleOrganizationButton != null)
mJoinSingleOrganizationButton.clicked -= JoinOrganizationButton_clicked;
if (mJoinMultipleOrganizationsButton != null)
mJoinMultipleOrganizationsButton.clicked -= JoinOrganizationButton_clicked;
if (mCreateOrganizationButton != null)
mCreateOrganizationButton.clicked -= CreateOrganizationButton_Clicked;
}
private void JoinOrganizationButton_clicked()
{
mParentWindow.JoinOrganizationAndWelcomePage(mOrganizationToJoin);
// TODO: Closing the window for now. Need to connect this event to the main on boarding
// workflow.
mParentWindow.Close();
}
private void CreateOrganizationButton_Clicked()
{
mParentWindow.ReplaceRootPanel(new CreateOrganizationPanel(mParentWindow, this, mRestApi));
}
void BuildSingleOrganizationSection(string organizationName)
{
mOrganizationToJoin = organizationName;
this.Query<VisualElement>("joinSingleOrganization").First().RemoveFromClassList("display-none");
this.SetControlText<Label>("joinSingleOrganizationLabel",
PlasticLocalization.Name.YouBelongToOrganization, organizationName);
this.SetControlText<Button>("joinSingleOrganizationButton",
PlasticLocalization.Name.JoinButton);
}
void BuildMultipleOrganizationsSection(List<string> organizationNames)
{
this.Query<VisualElement>("joinMultipleOrganizations").First().RemoveFromClassList("display-none");
this.SetControlText<Label>("joinMultipleOrganizationsLabel",
PlasticLocalization.Name.YouBelongToSeveralOrganizations);
VisualElement organizationDropdown = this.Query<VisualElement>("organizationDropdown").First();
ToolbarMenu toolbarMenu = new ToolbarMenu
{
text = organizationNames.FirstOrDefault()
};
foreach (string name in organizationNames)
{
toolbarMenu.menu.AppendAction(name, x =>
{
toolbarMenu.text = name;
mOrganizationToJoin = name;
}, DropdownMenuAction.AlwaysEnabled);
organizationDropdown.Add(toolbarMenu);
}
this.SetControlText<Button>("joinMultipleOrganizationsButton",
PlasticLocalization.Name.JoinButton);
}
void BuildCreateOrganizationSection(bool firstOrganization)
{
this.Query<VisualElement>("createOrganization").First().RemoveFromClassList("display-none");
PlasticLocalization.Name createOrganizationLabelName = firstOrganization ?
PlasticLocalization.Name.CreateFirstOrganizationLabel :
PlasticLocalization.Name.CreateOtherOrganizationLabel;
this.SetControlText<Label>("createOrganizationLabel",
createOrganizationLabelName);
this.SetControlText<Button>("createOrganizationButton",
PlasticLocalization.Name.CreateButton);
}
void InitializeLayoutAndStyles()
{
this.LoadLayout(typeof(OrganizationPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(OrganizationPanel).Name);
}
List<string> mOrganizations;
Button mJoinSingleOrganizationButton = null;
Button mJoinMultipleOrganizationsButton = null;
Button mCreateOrganizationButton = null;
public string mOrganizationToJoin = "";
readonly CloudEditionWelcomeWindow mParentWindow;
readonly IPlasticWebRestApi mRestApi;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 615ff93ab52eb8242a9194d4f711676f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,276 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.WebApi;
using PlasticGui.Configuration.CloudEdition;
using PlasticGui.Configuration.CloudEdition.Welcome;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.UIElements;
using PlasticGui.WebApi.Responses;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class SSOSignUpPanel :
VisualElement,
SignUp.INotify
{
internal SSOSignUpPanel(
CloudEditionWelcomeWindow parentWindow,
IPlasticWebRestApi restApi,
CmConnection cmConnection)
{
mParentWindow = parentWindow;
mRestApi = restApi;
mCmConnection = cmConnection;
InitializeLayoutAndStyles();
BuildComponents();
}
internal void SetSignUpData(
string user,
string password)
{
mUserNameTextField.value = user;
mPasswordTextField.value = password;
CleanNotificationLabels();
}
internal void Dispose()
{
mSignUpButton.clicked -= SignUpButton_Clicked;
mTermsOfServiceButton.clicked -= TermsOfServiceButton_Clicked;
mPrivacyPolicyButton.clicked -= PrivacyPolicyButton_Clicked;
mPrivacyPolicyStatementButton.clicked -= PrivacyPolicyStatementButton_Clicked;
mUserNameTextField.UnregisterValueChangedCallback(
UserNameTextBox_TextChanged);
mPasswordTextField.UnregisterValueChangedCallback(
PasswordTextBox_TextChanged);
mConfirmPasswordTextField.UnregisterValueChangedCallback(
ConfirmPasswordTextBox_TextChanged);
}
void UserNameTextBox_TextChanged(ChangeEvent<string> evt)
{
CleanNotification(mUserNotificationLabel);
}
void PasswordTextBox_TextChanged(ChangeEvent<string> evt)
{
CleanNotification(mPasswordNotificationLabel);
}
void ConfirmPasswordTextBox_TextChanged(ChangeEvent<string> evt)
{
CleanNotification(mConfirmPasswordNotificationLabel);
}
void SignUpButton_Clicked()
{
CleanNotificationLabels();
SignUp.Run(
mRestApi,
new SaveCloudEditionCreds(),
new SignUp.Data(
mUserNameTextField.text,
mPasswordTextField.text,
mConfirmPasswordTextField.text,
false),
mProgressControls,
this,
false);
}
void SignUpWithUnityButton_clicked()
{
mWaitingSignInPanel = new WaitingSignInPanel(
mParentWindow,
mParentWindow,
mRestApi,
mCmConnection);
mParentWindow.ReplaceRootPanel(mWaitingSignInPanel);
mWaitingSignInPanel.OAuthSignInForConfigure(SsoProvider.UNITY_URL_ACTION);
}
void TermsOfServiceButton_Clicked()
{
Application.OpenURL(SignUp.TERMS_OF_SERVICE_URL);
}
void PrivacyPolicyButton_Clicked()
{
Application.OpenURL(SignUp.PRIVACY_POLICY_URL);
}
void PrivacyPolicyStatementButton_Clicked()
{
Application.OpenURL(SignUp.PRIVACY_POLICY_URL);
}
void BuildComponents()
{
mUserNameTextField = this.Q<TextField>("emailField");
mUserNameTextField.label = PlasticLocalization.GetString(
PlasticLocalization.Name.Email);
mUserNameTextField.RegisterValueChangedCallback(
UserNameTextBox_TextChanged);
mUserNotificationLabel = this.Q<Label>("emailNotification");
mPasswordTextField = this.Q<TextField>("passwordField");
mPasswordTextField.label = PlasticLocalization.GetString(
PlasticLocalization.Name.Password);
mPasswordTextField.RegisterValueChangedCallback(
PasswordTextBox_TextChanged);
mConfirmPasswordTextField = this.Q<TextField>("confirmPasswordField");
mConfirmPasswordTextField.label = PlasticLocalization.GetString(
PlasticLocalization.Name.ConfirmPassword);
mConfirmPasswordTextField.RegisterValueChangedCallback(
ConfirmPasswordTextBox_TextChanged);
mPasswordNotificationLabel = this.Q<Label>("passwordNotificationLabel");
mConfirmPasswordNotificationLabel = this.Q<Label>("confirmPasswordNotificationLabel");
mSignUpButton = this.Q<Button>("signUp");
mSignUpButton.text = PlasticLocalization.GetString(PlasticLocalization.Name.SignUp);
mSignUpButton.clicked += SignUpButton_Clicked;
string[] signUpText = PlasticLocalization.GetString(
PlasticLocalization.Name.SignUpAgreeToShort).Split('{', '}');
Label signUpAgreePt1 = this.Q<Label>("signUpAgreePt1");
signUpAgreePt1.text = signUpText[0];
mTermsOfServiceButton = this.Q<Button>("termsOfService");
mTermsOfServiceButton.text = PlasticLocalization.GetString(PlasticLocalization.Name.TermsOfService);
mTermsOfServiceButton.clicked += TermsOfServiceButton_Clicked;
Label signUpAgreePt2 = this.Q<Label>("signUpAgreePt2");
signUpAgreePt2.text = signUpText[2];
mPrivacyPolicyButton = this.Q<Button>("privacyPolicy");
mPrivacyPolicyButton.text = PlasticLocalization.GetString(PlasticLocalization.Name.PrivacyPolicy);
mPrivacyPolicyButton.clicked += PrivacyPolicyButton_Clicked;
this.SetControlImage("unityIcon", Images.Name.ButtonSsoSignInUnity);
mSignUpWithUnityButton = this.Q<Button>("unityIDButton");
mSignUpWithUnityButton.text = PlasticLocalization.GetString(PlasticLocalization.Name.SignInWithUnityID);
mSignUpWithUnityButton.clicked += SignUpWithUnityButton_clicked;
this.SetControlText<Label>("privacyStatementText",
PlasticLocalization.Name.PrivacyStatementText,
PlasticLocalization.GetString(PlasticLocalization.Name.PrivacyStatement));
mPrivacyPolicyStatementButton = this.Q<Button>("privacyStatement");
mPrivacyPolicyStatementButton.text = PlasticLocalization.GetString(
PlasticLocalization.Name.PrivacyStatement);
mPrivacyPolicyStatementButton.clicked += PrivacyPolicyStatementButton_Clicked;
// TODO: add controls to disable and disable control logic
mProgressControls = new ProgressControlsForDialogs(new VisualElement[] { mSignUpButton, mSignUpWithUnityButton });
mProgressContainer = this.Q<VisualElement>("progressContainer");
mProgressContainer.Add((VisualElement)mProgressControls);
}
void InitializeLayoutAndStyles()
{
AddToClassList("grow");
this.LoadLayout(typeof(SSOSignUpPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(SSOSignUpPanel).Name);
}
void CleanNotificationLabels()
{
CleanNotification(mUserNotificationLabel);
CleanNotification(mPasswordNotificationLabel);
CleanNotification(mConfirmPasswordNotificationLabel);
}
static void ShowNotification(Label label, string text)
{
label.text = text;
label.RemoveFromClassList("hidden");
}
static void CleanNotification(Label label)
{
label.text = "";
label.AddToClassList("hidden");
}
void SignUp.INotify.Success(List<string> organizations, bool canCreateAnOrganization)
{
mParentWindow.ShowOrganizationPanel(
PlasticLocalization.GetString(PlasticLocalization.Name.SignUp),
organizations,
canCreateAnOrganization);
}
void SignUp.INotify.SuccessForHomeView(string userName)
{
}
void SignUp.INotify.ValidationFailed(SignUp.ValidationResult validationResult)
{
if (validationResult.UserError != null)
ShowNotification(mUserNotificationLabel, validationResult.UserError);
if (validationResult.ClearPasswordError != null)
ShowNotification(mPasswordNotificationLabel, validationResult.ClearPasswordError);
if (validationResult.ClearPasswordConfirmationError != null)
ShowNotification(mConfirmPasswordNotificationLabel, validationResult.ClearPasswordConfirmationError);
}
void SignUp.INotify.LoginNeeded(Login.Data loginData, string message)
{
Debug.Log("LoginNeeded");
throw new NotImplementedException();
//mWelcomeForm.SwitchToLoginPage(
// loginData.User, loginData.ClearPassword, message);
}
void SignUp.INotify.Error(string message)
{
mProgressControls.ShowError(message);
}
Button mTermsOfServiceButton;
Button mPrivacyPolicyButton;
Button mPrivacyPolicyStatementButton;
TextField mUserNameTextField;
TextField mPasswordTextField;
TextField mConfirmPasswordTextField;
Label mUserNotificationLabel;
Label mPasswordNotificationLabel;
Label mConfirmPasswordNotificationLabel;
Button mSignUpButton;
Button mSignUpWithUnityButton;
VisualElement mProgressContainer;
IProgressControls mProgressControls;
WaitingSignInPanel mWaitingSignInPanel;
readonly CloudEditionWelcomeWindow mParentWindow;
readonly IPlasticWebRestApi mRestApi;
readonly CmConnection mCmConnection;
//TODO: remove this once Google sign up functionality is added
const bool hideGoogleSignUpButton = true;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1284741c63bbe7742a2d359492947023
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,130 @@
using UnityEngine;
using UnityEngine.UIElements;
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.WebApi.Responses;
using PlasticGui.WebApi;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.UIElements;
using PlasticGui.Configuration.CloudEdition.Welcome;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class SignInPanel : VisualElement
{
internal SignInPanel(
CloudEditionWelcomeWindow parentWindow,
IPlasticWebRestApi restApi,
CmConnection cmConnection)
{
mParentWindow = parentWindow;
mRestApi = restApi;
mCmConnection = cmConnection;
InitializeLayoutAndStyles();
BuildComponents();
}
internal void Dispose()
{
mSignInWithUnityIdButton.clicked -= SignInWithUnityIdButton_Clicked;
mSignInWithEmailButton.clicked -= SignInWithEmailButton_Clicked;
mPrivacyPolicyStatementButton.clicked -= PrivacyPolicyStatementButton_Clicked;
if (mSignInWithEmailPanel != null)
mSignInWithEmailPanel.Dispose();
if (mWaitingSignInPanel != null)
mWaitingSignInPanel.Dispose();
}
void SignInWithEmailButton_Clicked()
{
mSignInWithEmailPanel = new SignInWithEmailPanel(
mParentWindow,
mParentWindow,
mRestApi);
mParentWindow.ReplaceRootPanel(mSignInWithEmailPanel);
}
internal void SignInWithUnityIdButton_Clicked()
{
mWaitingSignInPanel = new WaitingSignInPanel(
mParentWindow,
mParentWindow,
mRestApi,
mCmConnection);
mParentWindow.ReplaceRootPanel(mWaitingSignInPanel);
mWaitingSignInPanel.OAuthSignInForConfigure(SsoProvider.UNITY_URL_ACTION);
}
internal void SignInWithUnityIdButtonAutoLogin()
{
mWaitingSignInPanel = new WaitingSignInPanel(
mParentWindow,
mParentWindow,
mRestApi,
mCmConnection);
mParentWindow.ReplaceRootPanel(mWaitingSignInPanel);
}
void PrivacyPolicyStatementButton_Clicked()
{
// TODO: update when dll is avaiable PlasticGui.Configuration.CloudEdition.Welcome
// SignUp.PRIVACY_POLICY_URL
Application.OpenURL(SignUp.PRIVACY_POLICY_URL);
}
void BuildComponents()
{
this.SetControlImage("iconUnity",
Images.Name.ButtonSsoSignInUnity);
mSignInWithUnityIdButton = this.Query<Button>("unityIDButton").First();
mSignInWithUnityIdButton.text = PlasticLocalization.GetString(
PlasticLocalization.Name.SignInWithUnityID);
mSignInWithUnityIdButton.clicked += SignInWithUnityIdButton_Clicked;
this.SetControlImage("iconEmail",
Images.Name.ButtonSsoSignInEmail);
mSignInWithEmailButton = this.Query<Button>("emailButton").First();
mSignInWithEmailButton.text = PlasticLocalization.GetString(
PlasticLocalization.Name.SignInWithEmail);
mSignInWithEmailButton.clicked += SignInWithEmailButton_Clicked;
this.SetControlText<Label>("privacyStatementText",
PlasticLocalization.Name.PrivacyStatementText,
PlasticLocalization.GetString(PlasticLocalization.Name.PrivacyStatement));
mPrivacyPolicyStatementButton = this.Query<Button>("privacyStatement").First();
mPrivacyPolicyStatementButton.text = PlasticLocalization.GetString(
PlasticLocalization.Name.PrivacyStatement);
mPrivacyPolicyStatementButton.clicked += PrivacyPolicyStatementButton_Clicked;
}
void InitializeLayoutAndStyles()
{
AddToClassList("grow");
this.LoadLayout(typeof(SignInPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(SignInPanel).Name);
}
SignInWithEmailPanel mSignInWithEmailPanel;
WaitingSignInPanel mWaitingSignInPanel;
Button mSignInWithUnityIdButton;
Button mSignInWithEmailButton;
Button mPrivacyPolicyStatementButton;
readonly CloudEditionWelcomeWindow mParentWindow;
readonly IPlasticWebRestApi mRestApi;
readonly CmConnection mCmConnection;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bba806fdb20eb5a4da6cc856323d6273
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,175 @@
using System.Collections.Generic;
using Unity.PlasticSCM.Editor.UI.UIElements;
using UnityEngine.UIElements;
using PlasticGui;
using PlasticGui.Configuration.CloudEdition.Welcome;
using PlasticGui.Configuration.CloudEdition;
using PlasticGui.WebApi;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class SignInWithEmailPanel :
VisualElement,
Login.INotify
{
internal SignInWithEmailPanel(
CloudEditionWelcomeWindow parentWindow,
IWelcomeWindowNotify notify,
IPlasticWebRestApi restApi)
{
mParentWindow = parentWindow;
mNotify = notify;
mRestApi = restApi;
InitializeLayoutAndStyles();
BuildComponents();
}
internal void Dispose()
{
mSignInButton.clicked -= SignInButton_Clicked;
mBackButton.clicked -= BackButton_Clicked;
}
void SignInButton_Clicked()
{
CleanNotificationLabels();
Login.Run(
mRestApi,
new SaveCloudEditionCreds(),
mEmailField.text,
mPasswordField.text,
string.Empty,
string.Empty,
Login.Mode.Configure,
mProgressControls,
this);
}
void BackButton_Clicked()
{
mNotify.Back();
}
void Login.INotify.SuccessForConfigure(
List<string> organizations,
bool canCreateAnOrganization,
string userName,
string password)
{
mNotify.SuccessForConfigure(
organizations,
canCreateAnOrganization);
}
void Login.INotify.SuccessForSSO(
string organization)
{
mNotify.SuccessForSSO(organization);
}
void Login.INotify.SuccessForProfile(
string userName)
{
mNotify.SuccessForProfile(userName);
}
void Login.INotify.SuccessForCredentials(string userName, string password)
{
mNotify.SuccessForCredentials(userName, password);
}
void Login.INotify.SuccessForHomeView(string userName)
{
}
void Login.INotify.ValidationFailed(
Login.ValidationResult validationResult)
{
if (validationResult.UserError != null)
{
mEmailNotificationLabel.text = validationResult.UserError;
}
if (validationResult.PasswordError != null)
{
mPasswordNotificationLabel.text = validationResult.PasswordError;
}
}
void Login.INotify.SignUpNeeded(
Login.Data loginData)
{
mNotify.SignUpNeeded(loginData.User, loginData.ClearPassword);
}
void Login.INotify.Error(
string message)
{
mProgressControls.ShowError(message);
}
void CleanNotificationLabels()
{
mEmailNotificationLabel.text = string.Empty;
mPasswordNotificationLabel.text = string.Empty;
}
void BuildComponents()
{
mEmailField = this.Q<TextField>("email");
mPasswordField = this.Q<TextField>("password");
mEmailNotificationLabel = this.Q<Label>("emailNotification");
mPasswordNotificationLabel = this.Q<Label>("passwordNotification");
mSignInButton = this.Q<Button>("signIn");
mBackButton = this.Q<Button>("back");
mProgressContainer = this.Q<VisualElement>("progressContainer");
mSignInButton.clicked += SignInButton_Clicked;
mBackButton.clicked += BackButton_Clicked;
mEmailField.FocusOnceLoaded();
mProgressControls = new ProgressControlsForDialogs(new VisualElement[] { mSignInButton });
mProgressContainer.Add((VisualElement)mProgressControls);
this.SetControlText<Label>("signInLabel",
PlasticLocalization.Name.SignInWithEmail);
this.SetControlLabel<TextField>("email",
PlasticLocalization.Name.Email);
this.SetControlLabel<TextField>("password",
PlasticLocalization.Name.Password);
this.SetControlText<Button>("signIn",
PlasticLocalization.Name.SignIn);
this.SetControlText<Button>("back",
PlasticLocalization.Name.BackButton);
}
void InitializeLayoutAndStyles()
{
this.LoadLayout(typeof(SignInWithEmailPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(SignInWithEmailPanel).Name);
}
TextField mEmailField;
TextField mPasswordField;
Label mEmailNotificationLabel;
Label mPasswordNotificationLabel;
Button mSignInButton;
Button mBackButton;
VisualElement mProgressContainer;
IProgressControls mProgressControls;
readonly CloudEditionWelcomeWindow mParentWindow;
readonly IWelcomeWindowNotify mNotify;
readonly IPlasticWebRestApi mRestApi;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85f4628ae66f0eb439e59db66adbc696
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,104 @@
using Codice.Client.Common;
using PlasticGui;
using PlasticGui.Configuration.CloudEdition.Welcome;
using PlasticGui.WebApi;
using Unity.PlasticSCM.Editor.UI.UIElements;
using UnityEngine.UIElements;
namespace Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome
{
internal class WaitingSignInPanel : VisualElement
{
internal WaitingSignInPanel(
IWelcomeWindowNotify parentNotify,
OAuthSignIn.INotify notify,
IPlasticWebRestApi restApi,
CmConnection cmConnection)
{
mParentNotify = parentNotify;
mNotify = notify;
mRestApi = restApi;
mCmConnection = cmConnection;
InitializeLayoutAndStyles();
BuildComponents();
}
internal void OAuthSignInForConfigure(string ssoProviderName)
{
mSignIn = new OAuthSignIn();
mSignIn.ForConfigure(
mRestApi,
ssoProviderName,
mProgressControls,
mNotify,
mCmConnection);
ShowWaitingSpinner();
}
internal void Dispose()
{
mCancelButton.clicked -= CancelButton_Clicked;
}
void CancelButton_Clicked()
{
mSignIn.Cancel();
mParentNotify.Back();
}
void BuildComponents()
{
this.SetControlText<Label>("signInToPlasticSCM",
PlasticLocalization.Name.SignInToPlasticSCM);
this.SetControlText<Label>("completeSignInOnBrowser",
PlasticLocalization.Name.CompleteSignInOnBrowser);
mProgressContainer = this.Q<VisualElement>("progressContainer");
mProgressControls = new UI.Progress.ProgressControlsForDialogs();
mCancelButton = this.Query<Button>("cancelButton").First();
mCancelButton.text = PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton);
mCancelButton.clicked += CancelButton_Clicked;
}
void InitializeLayoutAndStyles()
{
this.LoadLayout(typeof(WaitingSignInPanel).Name);
this.LoadStyle("SignInSignUp");
this.LoadStyle(typeof(WaitingSignInPanel).Name);
}
void ShowWaitingSpinner()
{
var spinner = new LoadingSpinner();
mProgressContainer.Add(spinner);
spinner.Start();
var checkinMessageLabel = new Label(mProgressControls.ProgressData.ProgressMessage);
checkinMessageLabel.style.paddingLeft = 10;
mProgressContainer.Add(checkinMessageLabel);
}
Button mCancelButton;
VisualElement mProgressContainer;
OAuthSignIn mSignIn;
UI.Progress.ProgressControlsForDialogs mProgressControls;
readonly IPlasticWebRestApi mRestApi;
readonly CmConnection mCmConnection;
readonly OAuthSignIn.INotify mNotify;
readonly IWelcomeWindowNotify mParentNotify;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 077387e98bf29fb4a97bccfb592cfaf7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.IO;
using Codice.Client.Commands.Mount;
using Codice.Client.Commands.WkTree;
using Codice.Client.Common;
using Codice.Client.Common.GameUI;
using Codice.CM.Common;
using Codice.CM.WorkspaceServer.DataStore.Configuration;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal static class ConfigurePartialWorkspace
{
internal static void AsFullyChecked(WorkspaceInfo wkInfo)
{
string rootPath = WorkspacePath.GetWorkspacePathFromCmPath(
wkInfo.ClientPath, "/", Path.DirectorySeparatorChar);
WorkspaceTreeNode rootWkNode = CmConnection.Get().GetWorkspaceTreeHandler().
WkGetWorkspaceTreeNode(rootPath);
FullyCheckedDirectory rootDirectory = new FullyCheckedDirectory();
rootDirectory.MountId = MountPointId.WORKSPACE_ROOT;
rootDirectory.ItemId = rootWkNode.RevInfo.ItemId;
List<FullyCheckedDirectory> directoryList = new List<FullyCheckedDirectory>();
directoryList.Add(rootDirectory);
FullyCheckedDirectoriesStorage.Save(wkInfo, directoryList);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b3223ee740687445a7e4bc793fa2aae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,160 @@
using UnityEngine;
using UnityEditor;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Codice.CM.Common;
using Codice.Client.Common.Connection;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class CredentialsDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 525, 250);
}
}
internal static AskCredentialsToUser.DialogData RequestCredentials(
string server,
SEIDWorkingMode seidWorkingMode,
EditorWindow parentWindow)
{
CredentialsDialog dialog = Create(
server, seidWorkingMode, new ProgressControlsForDialogs());
ResponseType dialogResult = dialog.RunModal(parentWindow);
return dialog.BuildCredentialsDialogData(dialogResult);
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsDialogTitle));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsDialogExplanation, mServer));
GUILayout.Space(5);
DoEntriesArea();
GUILayout.Space(10);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
GUILayout.Space(10);
DoButtonsArea();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsDialogTitle);
}
AskCredentialsToUser.DialogData BuildCredentialsDialogData(
ResponseType dialogResult)
{
return new AskCredentialsToUser.DialogData(
dialogResult == ResponseType.Ok,
mUser, mPassword, mSaveProfile, mSeidWorkingMode);
}
void DoEntriesArea()
{
mUser = TextEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.UserName), mUser,
ENTRY_WIDTH, ENTRY_X);
GUILayout.Space(5);
mPassword = PasswordEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.Password), mPassword,
ENTRY_WIDTH, ENTRY_X);
GUILayout.Space(5);
mSaveProfile = ToggleEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.RememberCredentialsAsProfile),
mSaveProfile, ENTRY_WIDTH, ENTRY_X);
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonWithValidationAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
CredentialsDialogValidation.AsyncValidation(
BuildCredentialsDialogData(ResponseType.Ok), this, mProgressControls);
}
static CredentialsDialog Create(
string server,
SEIDWorkingMode seidWorkingMode,
ProgressControlsForDialogs progressControls)
{
var instance = CreateInstance<CredentialsDialog>();
instance.mServer = server;
instance.mSeidWorkingMode = seidWorkingMode;
instance.mProgressControls = progressControls;
instance.mEnterKeyAction = instance.OkButtonWithValidationAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
string mUser;
string mPassword = string.Empty;
ProgressControlsForDialogs mProgressControls;
bool mSaveProfile;
string mServer;
SEIDWorkingMode mSeidWorkingMode;
const float ENTRY_WIDTH = 345f;
const float ENTRY_X = 150f;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c46424c57c6462945b14ac0c95281406
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,112 @@
using System;
using UnityEditor;
using Codice.CM.Common;
using System.Threading.Tasks;
using Codice.Client.Common;
using Codice.Client.Common.Connection;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Codice.Client.Common.Threading;
using Unity.PlasticSCM.Editor.WebApi;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class CredentialsUiImpl : AskCredentialsToUser.IGui
{
AskCredentialsToUser.DialogData AskCredentialsToUser.IGui.AskUserForCredentials(string servername, SEIDWorkingMode seidWorkingMode)
{
AskCredentialsToUser.DialogData result = null;
GUIActionRunner.RunGUIAction(delegate
{
result = CredentialsDialog.RequestCredentials(
servername, seidWorkingMode, ParentWindow.Get());
});
return result;
}
void AskCredentialsToUser.IGui.ShowSaveProfileErrorMessage(string message)
{
GUIActionRunner.RunGUIAction(delegate
{
GuiMessage.ShowError(string.Format(
PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsErrorSavingProfile),
message));
});
}
AskCredentialsToUser.DialogData AskCredentialsToUser.IGui.AskUserForSSOCredentials(
string cloudServer)
{
AskCredentialsToUser.DialogData result = null;
GUIActionRunner.RunGUIAction(delegate
{
result = RunSSOCredentialsRequest(
cloudServer, CloudProjectSettings.accessToken);
});
return result;
}
AskCredentialsToUser.DialogData RunSSOCredentialsRequest(
string cloudServer,
string unityAccessToken)
{
if (string.IsNullOrEmpty(unityAccessToken))
{
return SSOCredentialsDialog.RequestCredentials(
cloudServer, ParentWindow.Get());
}
TokenExchangeResponse tokenExchangeResponse =
WaitUntilTokenExchange(unityAccessToken);
// There is no internet connection, so no way to get credentials
if (tokenExchangeResponse == null)
{
return new AskCredentialsToUser.DialogData(
false, null, null, false,
SEIDWorkingMode.SSOWorkingMode);
}
if (tokenExchangeResponse.Error == null)
{
return new AskCredentialsToUser.DialogData(
true,
tokenExchangeResponse.User,
tokenExchangeResponse.AccessToken,
false,
SEIDWorkingMode.SSOWorkingMode);
}
return SSOCredentialsDialog.RequestCredentials(
cloudServer, ParentWindow.Get());
}
static TokenExchangeResponse WaitUntilTokenExchange(
string unityAccessToken)
{
TokenExchangeResponse result = null;
Task.Run(() =>
{
try
{
result = WebRestApiClient.PlasticScm.
TokenExchange(unityAccessToken);
}
catch (Exception ex)
{
ExceptionsHandler.LogException(
"CredentialsUiImpl", ex);
}
}).Wait();
return result;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50d82b3e371b7cc42abc2999039b19cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,196 @@
using UnityEditor;
using UnityEngine;
using Codice.Utils;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class EncryptionConfigurationDialog : PlasticDialog
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 650, 425);
}
}
internal static EncryptionConfigurationDialogData RequestEncryptionPassword(
string server,
EditorWindow parentWindow)
{
EncryptionConfigurationDialog dialog = Create(server);
ResponseType dialogResult = dialog.RunModal(parentWindow);
EncryptionConfigurationDialogData result =
dialog.BuildEncryptionConfigurationData();
result.Result = dialogResult == ResponseType.Ok;
return result;
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.EncryptionConfiguration));
GUILayout.Space(20);
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.EncryptionConfigurationExplanation, mServer));
DoPasswordArea();
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.EncryptionConfigurationRemarks, mServer));
GUILayout.Space(10);
DoNotificationArea();
GUILayout.Space(10);
DoButtonsArea();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.EncryptionConfiguration);
}
EncryptionConfigurationDialogData BuildEncryptionConfigurationData()
{
return new EncryptionConfigurationDialogData(
CryptoServices.GetEncryptedPassword(mPassword.Trim()));
}
void DoPasswordArea()
{
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.EncryptionConfigurationEnterPassword));
GUILayout.Space(5);
mPassword = PasswordEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.Password), mPassword,
PASSWORD_TEXT_WIDTH, PASSWORD_TEXT_X);
GUILayout.Space(5);
mRetypePassword = PasswordEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.RetypePassword), mRetypePassword,
PASSWORD_TEXT_WIDTH, PASSWORD_TEXT_X);
GUILayout.Space(18f);
}
void DoNotificationArea()
{
if (string.IsNullOrEmpty(mErrorMessage))
return;
var rect = GUILayoutUtility.GetRect(
GUILayoutUtility.GetLastRect().width, 30);
EditorGUI.HelpBox(rect, mErrorMessage, MessageType.Error);
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonWithValidationAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
if (IsValidPassword(
mPassword.Trim(), mRetypePassword.Trim(),
out mErrorMessage))
{
mErrorMessage = string.Empty;
OkButtonAction();
return;
}
mPassword = string.Empty;
mRetypePassword = string.Empty;
}
static bool IsValidPassword(
string password, string retypePassword,
out string errorMessage)
{
errorMessage = string.Empty;
if (string.IsNullOrEmpty(password))
{
errorMessage = PlasticLocalization.GetString(
PlasticLocalization.Name.InvalidEmptyPassword);
return false;
}
if (!password.Equals(retypePassword))
{
errorMessage = PlasticLocalization.GetString(
PlasticLocalization.Name.PasswordDoesntMatch);
return false;
}
return true;
}
static EncryptionConfigurationDialog Create(string server)
{
var instance = CreateInstance<EncryptionConfigurationDialog>();
instance.mServer = server;
instance.mEnterKeyAction = instance.OkButtonWithValidationAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
string mPassword = string.Empty;
string mRetypePassword = string.Empty;
string mErrorMessage = string.Empty;
string mServer = string.Empty;
const float PASSWORD_TEXT_WIDTH = 250f;
const float PASSWORD_TEXT_X = 200f;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68d5bb402c52edc48b494a59b8971758
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,36 @@
using UnityEditor;
using Codice.Client.Common.Encryption;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class MissingEncryptionPasswordPromptHandler :
ClientEncryptionServiceProvider.IEncryptioPasswordProvider
{
string ClientEncryptionServiceProvider.IEncryptioPasswordProvider
.GetEncryptionEncryptedPassword(string server)
{
string result = null;
GUIActionRunner.RunGUIAction(delegate
{
result = AskForEncryptionPassword(server);
});
return result;
}
string AskForEncryptionPassword(string server)
{
EncryptionConfigurationDialogData dialogData =
EncryptionConfigurationDialog.RequestEncryptionPassword(server, ParentWindow.Get());
if (!dialogData.Result)
return null;
return dialogData.EncryptedPassword;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f6e4f3809c687045b21461609e2f78b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,287 @@
using UnityEngine;
using UnityEditor;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
using Codice.CM.Common;
using Codice.Client.Common.Connection;
using Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome;
using PlasticGui.Configuration.CloudEdition.Welcome;
using System.Collections.Generic;
using PlasticGui.WebApi.Responses;
using PlasticGui.Configuration.CloudEdition;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class SSOCredentialsDialog : PlasticDialog, OAuthSignIn.INotify, Login.INotify
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 525, 450);
}
}
internal static AskCredentialsToUser.DialogData RequestCredentials(
string cloudServer,
EditorWindow parentWindow)
{
SSOCredentialsDialog dialog = Create(
cloudServer, new ProgressControlsForDialogs());
ResponseType dialogResult = dialog.RunModal(parentWindow);
return dialog.BuildCredentialsDialogData(dialogResult);
}
protected override void OnModalGUI()
{
Title(PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsDialogTitle));
Paragraph(PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsDialogExplanation, mServer));
GUILayout.Space(20);
DoEntriesArea();
GUILayout.Space(10);
DrawProgressForDialogs.For(
mProgressControls.ProgressData);
GUILayout.Space(10);
DoButtonsArea();
}
protected override string GetTitle()
{
return PlasticLocalization.GetString(
PlasticLocalization.Name.CredentialsDialogTitle);
}
AskCredentialsToUser.DialogData BuildCredentialsDialogData(
ResponseType dialogResult)
{
return new AskCredentialsToUser.DialogData(
dialogResult == ResponseType.Ok,
mEmail, mPassword, false, SEIDWorkingMode.SSOWorkingMode);
}
void OAuthSignIn.INotify.SuccessForSSO(string organization)
{
OkButtonAction();
}
void OAuthSignIn.INotify.SuccessForProfile(string email)
{
OkButtonAction();
}
void OAuthSignIn.INotify.SuccessForCredentials(
string email,
string accessToken)
{
OkButtonAction();
}
void OAuthSignIn.INotify.SuccessForHomeView(string usrName)
{
}
void OAuthSignIn.INotify.Cancel(string errorMessage)
{
CancelButtonAction();
}
void OAuthSignIn.INotify.SuccessForConfigure(
List<string> organizations,
bool canCreateAnOrganization,
string userName,
string accessToken)
{
mEmail = userName;
mPassword = accessToken;
if (!organizations.Contains(mServer))
{
CancelButtonAction();
return;
}
CloudEditionWelcomeWindow.JoinCloudServer(
mServer, userName, accessToken);
GetWindow<PlasticWindow>().InitializePlastic();
OkButtonAction();
}
void DoButtonsArea()
{
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
DoOkButton();
DoCancelButton();
return;
}
DoCancelButton();
DoOkButton();
}
}
internal void OAuthSignInForConfigure(string ssoProviderName)
{
OAuthSignIn mSignIn = new OAuthSignIn();
mSignIn.ForConfigure(
PlasticGui.Plastic.WebRestAPI,
ssoProviderName,
mProgressControls,
this,
GetWindow<PlasticWindow>().CmConnectionForTesting);
}
void DoUnityIDButton()
{
if (NormalButton("Sign in with Unity ID"))
{
OAuthSignInForConfigure(SsoProvider.UNITY_URL_ACTION);
}
}
void DoEntriesArea()
{
Paragraph("Sign in with Unity ID");
GUILayout.Space(5);
DoUnityIDButton();
GUILayout.Space(25);
Paragraph(" --or-- ");
Paragraph("Sign in with email");
mEmail = TextEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.Email), mEmail,
ENTRY_WIDTH, ENTRY_X);
GUILayout.Space(5);
mPassword = PasswordEntry(PlasticLocalization.GetString(
PlasticLocalization.Name.Password), mPassword,
ENTRY_WIDTH, ENTRY_X);
}
void DoOkButton()
{
if (!AcceptButton(PlasticLocalization.GetString(
PlasticLocalization.Name.OkButton)))
return;
OkButtonWithValidationAction();
}
void DoCancelButton()
{
if (!NormalButton(PlasticLocalization.GetString(
PlasticLocalization.Name.CancelButton)))
return;
CancelButtonAction();
}
void OkButtonWithValidationAction()
{
Login.Run(
PlasticGui.Plastic.WebRestAPI,
new SaveCloudEditionCreds(),
mEmail,
mPassword,
string.Empty,
string.Empty,
Login.Mode.Configure,
mProgressControls,
this);
}
void Login.INotify.SuccessForConfigure(
List<string> organizations,
bool canCreateAnOrganization,
string userName,
string password)
{
OkButtonAction();
}
void Login.INotify.SuccessForSSO(
string organization)
{
OkButtonAction();
}
void Login.INotify.SuccessForCredentials(string userName, string password)
{
OkButtonAction();
}
void Login.INotify.SuccessForProfile(
string userName)
{
OkButtonAction();
}
void Login.INotify.SuccessForHomeView(string userName)
{
}
void Login.INotify.ValidationFailed(
Login.ValidationResult validationResult)
{
CancelButtonAction();
}
void Login.INotify.SignUpNeeded(
Login.Data loginData)
{
CancelButtonAction();
}
void Login.INotify.Error(
string message)
{
CancelButtonAction();
}
static SSOCredentialsDialog Create(
string server,
ProgressControlsForDialogs progressControls)
{
var instance = CreateInstance<SSOCredentialsDialog>();
instance.mServer = server;
instance.mProgressControls = progressControls;
instance.mEnterKeyAction = instance.OkButtonWithValidationAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
return instance;
}
string mEmail;
string mPassword = string.Empty;
ProgressControlsForDialogs mProgressControls;
string mServer;
const float ENTRY_WIDTH = 345f;
const float ENTRY_X = 150f;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1969c6a4a44a474983058896f48d9f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e9d092d8c9e8ffe48882f0c22e0e880d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,314 @@
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using PlasticGui;
using Codice.CM.Common;
using Codice.Client.Common;
using Unity.PlasticSCM.Editor.UI.UIElements;
using PlasticGui.Configuration.TeamEdition;
using PlasticGui.Configuration;
using PlasticGui.WebApi;
using Unity.PlasticSCM.Editor.Views.Welcome;
namespace Unity.PlasticSCM.Editor.Configuration.TeamEdition
{
internal class TeamEditionConfigurationWindow : EditorWindow
{
internal static void ShowWindow(IPlasticWebRestApi restApi, WelcomeView welcomeView)
{
TeamEditionConfigurationWindow window = GetWindow<TeamEditionConfigurationWindow>();
window.mRestApi = restApi;
window.mWelcomeView = welcomeView;
window.titleContent = new GUIContent(
PlasticLocalization.GetString(PlasticLocalization.Name.WelcomeToPlasticSCM));
window.minSize = window.maxSize = new Vector2(650, 300);
window.Show();
}
void OnEnable()
{
InitializeLayoutAndStyles();
BuildComponents();
}
void Dispose()
{
mConnectButton.clicked -= ConnectButton_Clicked;
mCheckConnectionButton.clicked -= CheckConnectionButton_Clicked;
mOkButton.clicked -= OkButton_Clicked;
mCancelButton.clicked -= CancelButton_Clicked;
mServerTextField.UnregisterValueChangedCallback(OnServerTextFieldChanged);
mUseSslToggle.UnregisterValueChangedCallback(OnUseSslToggleChanged);
mLoadingSpinner.Dispose();
}
void ConnectButton_Clicked()
{
ConfigurationConnectServerButtonClickEvent.Click(
server: mUserAssistant.GetProposedServer(),
HideValidation: HideValidation,
ShowError: ShowServerValidationError,
ShowProgress: ShowProgress,
HideProgress: HideProgress,
ShowNotification: ShowServerNotificationMessage,
DisableButtons: () => { mConnectButton.SetEnabled(false); },
EnableButtons: () => { mConnectButton.SetEnabled(true); },
UpdatePasswordEntries: (seidWorkingMode) =>
{
UpdatePasswordEntries(ValidateServerAndCreds.
IsPasswordRequired(seidWorkingMode));
},
NotifyWorkingMode: (mode) => { mSEIDWorkingMode = mode; },
NotifyConnectedStatus: (b) => { });
mUserTextField.SetEnabled(true);
}
void OnDestroy()
{
Dispose();
if (mWelcomeView != null)
mWelcomeView.OnUserClosedConfigurationWindow();
}
void CheckConnectionButton_Clicked()
{
ConfigurationCheckCredentialsButtonClickEvent.Click(
mSEIDWorkingMode,
mUserTextField.value,
mPasswordTextField.value,
Edition.Team,
mUserAssistant,
HideCredentialsValidationError,
ShowCheckCredentialsError,
ShowProgress,
HideProgress,
ShowNotification: ShowCredentialsNotificationMessage,
DisableButtons: () => { mCheckConnectionButton.SetEnabled(false); mConnectButton.SetEnabled(false); },
EnableButtons: () => { mCheckConnectionButton.SetEnabled(true); mConnectButton.SetEnabled(true); },
NotifyWorkingMode: (mode) => { mSEIDWorkingMode = mode; },
NotifyConnectedStatus: (status) => { },
restApi: mRestApi,
cmConnection: CmConnection.Get());
}
void CancelButton_Clicked()
{
Close();
}
void OkButton_Clicked()
{
if (!ValidateServerAndCreds.IsValidInput(
mUserAssistant.GetProposedServer(),
mUserTextField.value,
mSEIDWorkingMode,
mPasswordTextField.value,
ShowCheckCredentialsError))
{
return;
}
ConfigurationActions.SaveClientConfig(
mServerTextField.value,
mSEIDWorkingMode,
mUserTextField.value,
mPasswordTextField.value);
Close();
}
void HideCredentialsValidationError()
{
mCredentialsLabel.RemoveFromClassList("error");
mCredentialsLabel.AddToClassList("visibility-hidden");
}
void BuildComponents()
{
VisualElement root = rootVisualElement;
root.Query<Label>("plasticConfigurationTitle").First().text =
PlasticLocalization.GetString(PlasticLocalization.Name.PlasticConfigurationTitle);
root.SetControlText<Label>(
"plasticConfigurationExplanation",
PlasticLocalization.Name.PlasticConfigurationExplanation);
root.SetControlText<Label>("configurationServerInfo",
PlasticLocalization.Name.PlasticSCMServerLabel);
root.SetControlText<Button>(
"connect",
PlasticLocalization.Name.Connect);
root.SetControlText<Label>("useSsl",
PlasticLocalization.Name.UseSsl);
root.SetControlText<Label>("configurationUserNameInfo",
PlasticLocalization.Name.ConfigurationUserNameInfo);
root.SetControlText<Label>("configurationCredentialsInfo",
PlasticLocalization.Name.ConfigurationCredentialsInfo);
root.SetControlText<Button>("check",
PlasticLocalization.Name.Check);
root.SetControlText<Label>("credentialsOk",
PlasticLocalization.Name.CredentialsOK);
root.SetControlText<Button>("okButton",
PlasticLocalization.Name.OkButton);
root.SetControlText<Button>("cancelButton",
PlasticLocalization.Name.CancelButton);
mSpinnerContainer = root.Query<VisualElement>("spinnerContainer").First();
mSpinnerLabel = root.Query<Label>("spinnerLabel").First();
mLoadingSpinner = new LoadingSpinner();
mSpinnerContainer.Add(mLoadingSpinner);
mSpinnerContainer.AddToClassList("visibility-hidden");
mCheckConnectionButton = root.Query<Button>("check").First();
mCheckConnectionButton.clicked += CheckConnectionButton_Clicked;
mConnectButton = root.Query<Button>("connect").First();
mConnectButton.clicked += ConnectButton_Clicked;
mServerTextField = root.Query<TextField>("serverTextField").First();
mServerTextField.RegisterValueChangedCallback(OnServerTextFieldChanged);
mUseSslToggle = root.Query<Toggle>("useSslToogle").First();
mUseSslToggle.RegisterValueChangedCallback(OnUseSslToggleChanged);
mUserTextField = root.Query<TextField>("userTextField").First();
mUserTextField.SetEnabled(false);
mPasswordTextField = root.Query<TextField>("passwordTextField").First();
mPasswordTextField.isPasswordField = true;
mConnectedLabel = root.Query<Label>("connectedLabel").First();
mCredentialsLabel = root.Query<Label>("credentialsOk").First();
mOkButton = root.Query<Button>("okButton").First();
mOkButton.clicked += OkButton_Clicked;
mCancelButton = root.Query<Button>("cancelButton").First();
mCancelButton.clicked += CancelButton_Clicked;
}
void OnUseSslToggleChanged(ChangeEvent<bool> evt)
{
mUserAssistant.OnSslChanged(mServerTextField.value, evt.newValue);
mServerTextField.value = mUserAssistant.GetProposedServer();
}
void InitializeLayoutAndStyles()
{
VisualElement root = rootVisualElement;
root.LoadLayout(typeof(TeamEditionConfigurationWindow).Name);
root.LoadStyle(typeof(TeamEditionConfigurationWindow).Name);
}
void OnServerTextFieldChanged(ChangeEvent<string> evt)
{
mUserAssistant.OnServerChanged(evt.newValue);
mUseSslToggle.value = mUserAssistant.IsSslServer(evt.newValue);
}
void ShowServerNotificationMessage(string message)
{
mConnectedLabel.text = message;
mConnectedLabel.RemoveFromClassList("visibility-hidden");
}
void ShowServerValidationError(string message)
{
mConnectedLabel.text = message;
mConnectedLabel.AddToClassList("error");
mConnectedLabel.RemoveFromClassList("visibility-hidden");
}
void ShowCredentialsNotificationMessage(string message)
{
mCredentialsLabel.text = message;
mCredentialsLabel.RemoveFromClassList("visibility-hidden");
}
void ShowCheckCredentialsError(string message)
{
mCredentialsLabel.text = message;
mCredentialsLabel.AddToClassList("error");
mCredentialsLabel.RemoveFromClassList("visibility-hidden");
}
void HideValidation()
{
mConnectedLabel.RemoveFromClassList("error");
mConnectedLabel.AddToClassList("visibility-hidden");
}
void ShowProgress(string text)
{
mSpinnerLabel.text = text;
mSpinnerContainer.RemoveFromClassList("visibility-hidden");
mSpinnerLabel.RemoveFromClassList("visibility-hidden");
mLoadingSpinner.Start();
}
void HideProgress()
{
mLoadingSpinner.Stop();
mSpinnerContainer.AddToClassList("visibility-hidden");
mSpinnerLabel.AddToClassList("visibility-hidden");
}
void UpdatePasswordEntries(bool bIsPasswordRequired)
{
if (!bIsPasswordRequired)
{
mPasswordTextField.AddToClassList("display-none");
mUserTextField.SetEnabled(false);
mUserTextField.value = Environment.UserName;
return;
}
mUserTextField.SetEnabled(true);
mPasswordTextField.RemoveFromClassList("display-none");
mUserTextField.SelectAll();
mUserTextField.FocusWorkaround();
}
Button mConnectButton;
Label mConnectedLabel;
TextField mServerTextField;
TextField mPasswordTextField;
Toggle mUseSslToggle;
LoadingSpinner mLoadingSpinner;
Label mSpinnerLabel;
VisualElement mSpinnerContainer;
Button mCheckConnectionButton;
Label mCredentialsLabel;
Button mOkButton;
Button mCancelButton;
SEIDWorkingMode mSEIDWorkingMode = SEIDWorkingMode.UPWorkingMode;
ConfigurationDialogUserAssistant mUserAssistant =
new ConfigurationDialogUserAssistant();
IPlasticWebRestApi mRestApi;
WelcomeView mWelcomeView;
TextField mUserTextField;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c95121e1e2d89e648b9d0aed259caad9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,26 @@
using System.IO;
using Codice.Utils;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal static class ToolConfig
{
internal static string GetUnityPlasticLogConfigFile()
{
return GetConfigFilePath(LOG_CONFIG_FILE);
}
static string GetConfigFilePath(string configfile)
{
string file = Path.Combine(ApplicationLocation.GetAppPath(), configfile);
if (File.Exists(file))
return file;
return UserConfigFolder.GetConfigFile(configfile);
}
const string LOG_CONFIG_FILE = "unityplastic.log.conf";
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee776820547bd654980004e8471df8e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,66 @@
using System.IO;
namespace Unity.PlasticSCM.Editor.Configuration
{
internal class WriteLogConfiguration
{
internal static void For(string logConfigPath)
{
string logDirectoryPath = GetPlasticLogDirectoryPath(logConfigPath);
string relevantLogFile = Path.Combine(logDirectoryPath, RELEVANT_LOG_FILE_NAME);
string debugLogFile = Path.Combine(logDirectoryPath, DEBUG_LOG_FILE_NAME);
using (StreamWriter sw = File.CreateText(logConfigPath))
{
sw.Write(string.Format(
LOG_CONFIGURATION,
relevantLogFile,
debugLogFile));
}
}
static string GetPlasticLogDirectoryPath(string logConfigPath)
{
return Path.Combine(
Directory.GetParent(logConfigPath).FullName,
LOGS_DIRECTORY);
}
const string LOGS_DIRECTORY = "logs";
const string RELEVANT_LOG_FILE_NAME = "unityplastic.relevant.log.txt";
const string DEBUG_LOG_FILE_NAME = "unityplastic.debug.log.txt";
const string LOG_CONFIGURATION =
@"<log4net>
<appender name=""RelevantInfoAppender"" type=""log4net.Appender.RollingFileAppender"">
<file value=""{0}"" />
<appendToFile value=""true"" />
<rollingStyle value=""Size"" />
<maxSizeRollBackups value=""10"" />
<maximumFileSize value=""2MB"" />
<layout type=""log4net.Layout.PatternLayout"">
<conversionPattern value=""%date %username %-5level %logger - %message%newline"" />
</layout>
<filter type=""log4net.Filter.LevelRangeFilter""><levelMin value=""INFO"" /><levelMax value=""FATAL"" /></filter>
</appender>
<appender name=""DebugAppender"" type=""log4net.Appender.RollingFileAppender"">
<file value=""{1}"" />
<appendToFile value=""true"" />
<rollingStyle value=""Size"" />
<maxSizeRollBackups value=""10"" />
<maximumFileSize value=""10MB"" />
<staticLogFileName value=""true"" />
<layout type=""log4net.Layout.PatternLayout"">
<conversionPattern value=""%date %username %-5level %logger - %message%newline"" />
</layout>
</appender>
<root>
<level value=""DEBUG"" />
<appender-ref ref=""RelevantInfoAppender"" />
<appender-ref ref=""DebugAppender"" />
</root>
</log4net>
";
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 332442c8f4f7b1943bb9e12fc97356e4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: