/*
* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading;
using Amazon.CognitoIdentityProvider;
using Amazon.CognitoIdentityProvider.Model;
using Amazon.Extensions.CognitoAuthentication.Util;
namespace Amazon.Extensions.CognitoAuthentication
{
public partial class CognitoDevice
{
///
/// The device key associated with the device. DeviceKey can only be configured
/// through the constructor and the GetDevice method.
///
public string DeviceKey { get; private set; }
///
/// The device attributes associated with the device. DeviceAttributes can only be
/// configured through the constructor and the GetDevice method.
///
public Dictionary DeviceAttributes { get; private set; }
///
/// The creation time for the device. CreateDate can only be configured
/// through the constructor and once set cannot be changed.
///
public DateTime CreateDate { get; private set; }
///
/// The last modified time for the device. LastModified can only be configured
/// through the constructor and the GetDevice method.
///
public DateTime LastModified { get; private set; }
///
/// The last authenticated time for the device. LastAuthenticated can only be configured
/// through the constructor and the GetDevice method.
///
public DateTime LastAuthenticated { get; private set; }
///
/// The user associated with the device. User can only be configured
/// through the constructor, and once set it cannot be changed.
///
public CognitoUser User { get; private set; }
///
/// The group device key of the associated device
///
public string GroupDeviceKey { get; set; }
///
/// The device secret of the associated device
///
public string DeviceSecret { get; set; }
///
/// Creates an instance of CognitoDevice
///
/// The device key for the device
/// The attributes for the device
/// The creation date for the device
/// The last modified date for the device
/// The last authenticated date for the device
/// The CognitoUser associated with the device
public CognitoDevice(string deviceKey,
IDictionary deviceAttributes,
DateTime createDate,
DateTime lastModified,
DateTime lastAuthenticated,
CognitoUser user)
{
if (deviceKey == null)
{
throw new ArgumentNullException("deviceKey", "deviceKey cannot be null.");
}
if(deviceAttributes == null)
{
throw new ArgumentNullException("deviceAttributes", "deviceAttributes cannot be null.");
}
this.DeviceKey = deviceKey;
this.DeviceAttributes = new Dictionary(deviceAttributes);
this.CreateDate = createDate;
this.LastModified = lastModified;
this.LastAuthenticated = lastAuthenticated;
this.User = user;
}
///
/// Creates an instance of CognitoDevice
///
/// A DeviceType object to create the CognitoDevice from
/// The CognitoUser associated with the device
public CognitoDevice(DeviceType device, CognitoUser user)
{
if (device == null)
{
throw new ArgumentNullException("device", "Device cannot be null.");
}
this.DeviceKey = device.DeviceKey;
this.CreateDate = device.DeviceCreateDate;
this.LastModified = device.DeviceLastModifiedDate;
this.LastAuthenticated = device.DeviceLastAuthenticatedDate;
this.User = user;
this.DeviceAttributes = CreateDictionaryFromAttributeList(device.DeviceAttributes);
}
///
/// Gets a device attrbute based on the attribute name
///
/// The name of the desired attribute
/// Returns a device attrbute based on the attribute name
public string GetDeviceAttribute(string attributeName)
{
string attributeValue = null;
if (DeviceAttributes.ContainsKey(attributeName))
{
attributeValue = DeviceAttributes[attributeName];
}
return attributeValue;
}
///
/// Gets the name of the device
///
/// Returns the name of the device
public string GetDeviceName()
{
return GetDeviceAttribute(CognitoConstants.DeviceAttrName);
}
///
/// Gets the device from the Cognito service using the device key and user's access
/// token using an asynchronous call
///
public async Task GetDeviceAsync()
{
await GetDeviceAsync(default);
}
///
/// Gets the device from the Cognito service using the device key and user's access
/// token using an asynchronous call
///
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation
public async Task GetDeviceAsync(CancellationToken cancellationToken)
{
GetDeviceRequest getDeviceRequest = CreateGetDeviceRequest();
GetDeviceResponse getDeviceResponse =
await User.Provider.GetDeviceAsync(getDeviceRequest, cancellationToken).ConfigureAwait(false);
UpdateThisDevice(getDeviceResponse.Device);
}
///
/// Forgets the device associated with the CognitoDevice's device key using
/// an asynchronous call
///
public Task ForgetDeviceAsync()
{
return ForgetDeviceAsync(default);
}
///
/// Forgets the device associated with the CognitoDevice's device key using
/// an asynchronous call
///
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation
public Task ForgetDeviceAsync(CancellationToken cancellationToken)
{
ForgetDeviceRequest forgetDeviceRequest = CreateForgetDeviceRequest();
return User.Provider.ForgetDeviceAsync(forgetDeviceRequest, cancellationToken);
}
///
/// Updates the device status to be remembered using an asynchronous call
///
public Task RememberThisDeviceAsync()
{
return RememberThisDeviceAsync(default);
}
///
/// Updates the device status to be remembered using an asynchronous call
///
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation
public Task RememberThisDeviceAsync(CancellationToken cancellationToken)
{
UpdateDeviceStatusRequest updateRequest =
CreateUpdateDeviceStatusRequest(new DeviceRememberedStatusType(CognitoConstants.DeviceAttrRemembered));
return User.Provider.UpdateDeviceStatusAsync(updateRequest, cancellationToken);
}
///
/// Updates the device status to not be remembered using an asynchronous call
///
public Task DoNotRememberThisDeviceAsync()
{
return DoNotRememberThisDeviceAsync(default);
}
///
/// Updates the device status to not be remembered using an asynchronous call
///
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation
public Task DoNotRememberThisDeviceAsync(CancellationToken cancellationToken)
{
UpdateDeviceStatusRequest updateRequest =
CreateUpdateDeviceStatusRequest(new DeviceRememberedStatusType(CognitoConstants.DeviceAttrNotRemembered));
return User.Provider.UpdateDeviceStatusAsync(updateRequest, cancellationToken);
}
private GetDeviceRequest CreateGetDeviceRequest()
{
if (User.SessionTokens == null || !User.SessionTokens.IsValid())
{
throw new NotAuthorizedException("User is not authorized.");
}
GetDeviceRequest getDeviceRequest = new GetDeviceRequest()
{
AccessToken = User.SessionTokens.AccessToken,
DeviceKey = DeviceKey
};
return getDeviceRequest;
}
///
/// Internal method to update the properties of the current CognitoDevice object
///
///
private void UpdateThisDevice(DeviceType device)
{
if (device == null)
{
throw new InternalErrorException("Service returned null object, this device was not updated.");
}
if (!string.Equals(device.DeviceKey, this.DeviceKey))
{
throw new InternalErrorException("Device keys don't match, this device was not updated.");
}
DeviceAttributes = CreateDictionaryFromAttributeList(device.DeviceAttributes);
LastModified = device.DeviceLastModifiedDate;
LastAuthenticated = device.DeviceLastAuthenticatedDate;
}
private ForgetDeviceRequest CreateForgetDeviceRequest()
{
if (User.SessionTokens == null || !User.SessionTokens.IsValid())
{
throw new NotAuthorizedException("User is not authorized.");
}
ForgetDeviceRequest forgetDeviceRequest = new ForgetDeviceRequest()
{
AccessToken = User.SessionTokens.AccessToken,
DeviceKey = DeviceKey
};
return forgetDeviceRequest;
}
private UpdateDeviceStatusRequest CreateUpdateDeviceStatusRequest(DeviceRememberedStatusType deviceRememberedStatus)
{
if (User.SessionTokens == null || !User.SessionTokens.IsValid())
{
throw new NotAuthorizedException("User is not authorized.");
}
UpdateDeviceStatusRequest updateDeviceStatusRequest = new UpdateDeviceStatusRequest()
{
AccessToken = User.SessionTokens.AccessToken,
DeviceKey = DeviceKey,
DeviceRememberedStatus = deviceRememberedStatus
};
return updateDeviceStatusRequest;
}
///
/// Internal method for creating a dictionary of attrbutes from a list of AttributeType objects
///
///
///
private Dictionary CreateDictionaryFromAttributeList(IList attributes)
{
Dictionary attributesDict = new Dictionary();
foreach(AttributeType attribute in attributes)
{
attributesDict.Add(attribute.Name, attribute.Value);
}
return attributesDict;
}
}
}