Ejemplo n.º 1
0
        public string GenerateToken(UserTokenInfo tokenInfo)
        {
            if (tokenInfo == null)
            {
                throw new ArgumentNullException(nameof(tokenInfo));
            }

            var config = _jwtConfig.CurrentValue;

            var identity = new ClaimsIdentity();

            identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, tokenInfo.Id.ToString(CultureInfo.InvariantCulture.NumberFormat), ClaimValueTypes.Integer64));
            identity.AddClaim(new Claim(VersionClaimType, tokenInfo.Version.ToString(CultureInfo.InvariantCulture.NumberFormat), ClaimValueTypes.Integer64));

            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Subject            = identity,
                Issuer             = config.Issuer,
                Audience           = config.Audience,
                SigningCredentials = new SigningCredentials(_tokenSecurityKey, SecurityAlgorithms.HmacSha384),
                IssuedAt           = _clock.GetCurrentTime(),
                Expires            = tokenInfo.ExpireAt,
                NotBefore          = _clock.GetCurrentTime() // I must explicitly set this or it will use the current time by default and mock is not work in which case test will not pass.
            };

            var token       = _tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = _tokenHandler.WriteToken(token);

            return(tokenString);
        }
Ejemplo n.º 2
0
        public async Task <UserTokenCreateResult> CreateTokenAsync(string username, string password, DateTime?expireAt = null)
        {
            expireAt = expireAt?.MyToUtc();

            if (username == null)
            {
                throw new ArgumentNullException(nameof(username));
            }
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }

            var userId = await _userService.VerifyCredential(username, password);

            var user = await _userService.GetUserAsync(userId);

            var token = _userTokenService.GenerateToken(new UserTokenInfo
            {
                Id       = user.Id,
                Version  = user.Version,
                ExpireAt = expireAt ?? _clock.GetCurrentTime() + TimeSpan.FromSeconds(_tokenOptionsMonitor.CurrentValue.DefaultExpireSeconds)
            });

            _logger.LogInformation(Resource.LogTokenCreate, user.Username, userId);

            return(new UserTokenCreateResult {
                Token = token, User = user
            });
        }
Ejemplo n.º 3
0
        public async Task <ICacheableDataDigest> SetAvatarAsync(long userId, ByteData avatar)
        {
            if (avatar is null)
            {
                throw new ArgumentNullException(nameof(avatar));
            }

            await _imageService.ValidateAsync(avatar.Data, avatar.ContentType, true);

            await _basicUserService.ThrowIfUserNotExist(userId);

            var entity = await _database.UserAvatars.Where(a => a.UserId == userId).SingleOrDefaultAsync();

            await using var transaction = await _database.Database.BeginTransactionAsync();

            var tag = await _dataManager.RetainEntryAsync(avatar.Data);

            var now = _clock.GetCurrentTime();

            if (entity is null)
            {
                var newEntity = new UserAvatarEntity
                {
                    DataTag      = tag,
                    Type         = avatar.ContentType,
                    LastModified = now,
                    UserId       = userId
                };
                _database.Add(newEntity);
            }
            else
            {
                if (entity.DataTag is not null)
                {
                    await _dataManager.FreeEntryAsync(entity.DataTag);
                }

                entity.DataTag      = tag;
                entity.Type         = avatar.ContentType;
                entity.LastModified = now;
            }

            await _database.SaveChangesAsync();

            await transaction.CommitAsync();

            _logger.LogInformation(Resource.LogSetAvatar, userId);

            return(new CacheableDataDigest(tag, now));
        }
Ejemplo n.º 4
0
        public async Task <ActionResult <HttpCreateTokenResponse> > Create([FromBody] HttpCreateTokenRequest request)
        {
            try
            {
                DateTime?expireTime = null;
                if (request.Expire is not null)
                {
                    expireTime = _clock.GetCurrentTime().AddDays(request.Expire.Value);
                }

                var result = await _userTokenManager.CreateTokenAsync(request.Username, request.Password, expireTime);

                return(new HttpCreateTokenResponse
                {
                    Token = result.Token,
                    User = await _mapper.MapAsync <HttpUser>(result.User, Url, User)
                });
            }
            catch (EntityNotExistException)
            {
                return(BadRequestWithCommonResponse(ErrorCodes.TokenController.CreateBadCredential, Resource.MessageTokenCreateBadCredential));
            }
            catch (BadPasswordException)
            {
                return(BadRequestWithCommonResponse(ErrorCodes.TokenController.CreateBadCredential, Resource.MessageTokenCreateBadCredential));
            }
        }
Ejemplo n.º 5
0
        private HardwareStatus ParseV4StatusElements(IReadOnlyList <string> elements)
        {
            log.Info("V4 status");
            var elementsLength = elements.Count;

            if (elementsLength != 23)
            {
                var message = $"V4 GINF packet had wrong number of elements: expected 23, found {elementsLength}";
                log.Error(message);
                var ex = new ArgumentException(message, "status");
                ex.Data["V4 Status Elements"] = elements;
                ex.Data["ExpectedElements"]   = 23;
                ex.Data["ActualElements"]     = elementsLength;
                throw ex;
            }

            try
            {
                var status = new HardwareStatus
                {
                    TimeStamp            = timeSource.GetCurrentTime(),
                    FirmwareVersion      = elements[0],
                    DomeCircumference    = Convert.ToInt16(elements[1]),
                    HomePosition         = Convert.ToInt16(elements[2]),
                    Coast                = Convert.ToInt16(elements[3]),
                    CurrentAzimuth       = Convert.ToInt16(elements[4]),
                    Slaved               = elements[5] == "1" ? true : false,
                    ShutterSensor        = (SensorState)Enum.Parse(typeof(SensorState), elements[6]),
                    DsrSensor            = (SensorState)Enum.Parse(typeof(SensorState), elements[7]),
                    AtHome               = elements[8] == "0" ? true : false,
                    HomeCounterClockwise = Convert.ToInt16(elements[9]),
                    HomeClockwise        = Convert.ToInt16(elements[10]),
                    UserPins             = Convert.ToByte(elements[11]),
                    WeatherAge           = Convert.ToInt16(elements[12]),
                    WindDirection        = Convert.ToInt16(elements[13]),
                    WindSpeed            = Convert.ToInt16(elements[14]),
                    Temperature          = Convert.ToInt16(elements[15]),
                    Humidity             = Convert.ToInt16(elements[16]),
                    Wetness              = Convert.ToInt16(elements[17]),
                    Snow         = Convert.ToInt16(elements[18]),
                    WindPeak     = Convert.ToInt16(elements[19]),
                    Lx200Azimuth = Convert.ToInt16(elements[20]),
                    DeadZone     = Convert.ToInt16(elements[21]),
                    Offset       = Convert.ToInt16(elements[22])
                };
                return(status);
            }
            catch (Exception ex)
            {
                log.Error(ex, "Exception while parsing GINF packet");
                ex.Data["V4 Status Elements"] = elements;
                throw;
            }
        }
Ejemplo n.º 6
0
        public async Task BackupAsync(CancellationToken cancellationToken = default)
        {
            var backupDirPath = _pathProvider.GetDatabaseBackupDirectory();

            Directory.CreateDirectory(backupDirPath);
            var fileName = _clock.GetCurrentTime().ToString("yyyy-MM-ddTHH-mm-ss", CultureInfo.InvariantCulture);
            var path     = Path.Combine(backupDirPath, fileName);
            await _database.Database.ExecuteSqlInterpolatedAsync($"VACUUM INTO {path}", cancellationToken);

            _logger.LogWarning(Resource.DatabaseBackupServiceFinishBackup, path);
        }
Ejemplo n.º 7
0
        protected TimelineEntity CreateNewTimelineEntity(string?name, long ownerId)
        {
            var currentTime = _clock.GetCurrentTime();

            return(new TimelineEntity
            {
                Name = name,
                NameLastModified = currentTime,
                OwnerId = ownerId,
                Visibility = TimelineVisibility.Register,
                CreateTime = currentTime,
                LastModified = currentTime,
                CurrentPostLocalId = 0,
                Members = new List <TimelineMemberEntity>()
            });
        }
Ejemplo n.º 8
0
        /// <summary>Initializes a new instance of the <see cref="SimulatorStateMachine" /> class.</summary>
        /// <param name="timeSource">A source of the current time.</param>
        /// <param name="simulatorConfiguration"></param>
        public SimulatorStateMachine(IClock timeSource, SimulatorConfiguration simulatorConfiguration, ILog logger)
        {
            Contract.Requires(timeSource != null);
            log                 = logger;
            Configuration       = simulatorConfiguration;
            this.timeSource     = timeSource;
            DomeSupportRingOpen = false;
            ShutterStuck        = false;
            HardwareStatus      = new HardwareStatus
            {
                AtHome               = false,
                Coast                = 1,
                CurrentAzimuth       = 0,
                DeadZone             = 3,
                DomeCircumference    = 414,
                DsrSensor            = SensorState.Indeterminate,
                FirmwareVersion      = "V4",
                HomeClockwise        = 16,
                HomeCounterClockwise = 1,
                HomePosition         = 8,
                Humidity             = 255,
                Lx200Azimuth         = 999,
                Offset               = 0,
                ShutterSensor        = SensorState.Indeterminate,
                Slaved               = false,
                Snow = 255,
                // For weather items, 255 means no data
                Temperature   = 255,
                TimeStamp     = timeSource.GetCurrentTime(),
                UserPins      = 0,
                WeatherAge    = 128,
                WindDirection = 255,
                WindPeak      = 255,
                WindSpeed     = 255
            };

            SetAzimuthDependentSensorsAndStates();

            // Set the starting state and begin receiving.
            SimulatorState.Transition(new StateStartup(this));
            var receiveObservable = receiveSubject.AsObservable();

            receiveSubscription = receiveObservable.Subscribe(InputStimulus, EndOfSimulation);
        }
Ejemplo n.º 9
0
        public async Task <bool> AddHighlightTimelineAsync(long timelineId, long?operatorId)
        {
            await _timelineService.ThrowIfTimelineNotExist(timelineId);

            if (operatorId.HasValue)
            {
                await _userService.ThrowIfUserNotExist(operatorId.Value);
            }

            var alreadyIs = await _database.HighlightTimelines.AnyAsync(t => t.TimelineId == timelineId);

            if (alreadyIs)
            {
                return(false);
            }

            _database.HighlightTimelines.Add(new HighlightTimelineEntity {
                TimelineId = timelineId, OperatorId = operatorId, AddTime = _clock.GetCurrentTime(), Order = await _database.HighlightTimelines.CountAsync() + 1
            });
            await _database.SaveChangesAsync();

            return(true);
        }
Ejemplo n.º 10
0
        public async Task ChangePropertyAsync(long id, TimelineChangePropertyParams newProperties)
        {
            if (newProperties is null)
            {
                throw new ArgumentNullException(nameof(newProperties));
            }

            if (newProperties.Name is not null)
            {
                CheckTimelineName(newProperties.Name, nameof(newProperties));
            }

            if (newProperties.Color is not null)
            {
                var(result, message) = _colorValidator.Validate(newProperties.Color);
                if (!result)
                {
                    throw new ArgumentException(message, nameof(newProperties));
                }
            }

            var entity = await _database.Timelines.Where(t => t.Id == id).SingleOrDefaultAsync();

            if (entity is null)
            {
                throw CreateTimelineNotExistException(id);
            }

            var changed     = false;
            var nameChanged = false;

            if (newProperties.Name is not null)
            {
                var conflict = await _database.Timelines.AnyAsync(t => t.Name == newProperties.Name);

                if (conflict)
                {
                    throw CreateTimelineConflictException(newProperties.Name);
                }

                entity.Name = newProperties.Name;

                changed     = true;
                nameChanged = true;
            }

            if (newProperties.Title != null)
            {
                changed      = true;
                entity.Title = newProperties.Title;
            }

            if (newProperties.Description != null)
            {
                changed            = true;
                entity.Description = newProperties.Description;
            }

            if (newProperties.Visibility.HasValue)
            {
                changed           = true;
                entity.Visibility = newProperties.Visibility.Value;
            }

            if (newProperties.Color is not null)
            {
                changed      = true;
                entity.Color = newProperties.Color;
            }

            if (changed)
            {
                var currentTime = _clock.GetCurrentTime();
                entity.LastModified = currentTime;
                if (nameChanged)
                {
                    entity.NameLastModified = currentTime;
                }
            }

            await _database.SaveChangesAsync();

            _logger.LogInformation(Resource.LogTimelineUpdated, id);
        }
Ejemplo n.º 11
0
        public async Task <TimelinePostEntity> CreatePostAsync(long timelineId, long authorId, TimelinePostCreateRequest request)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (request.Color is not null)
            {
                CheckColor(request.Color, nameof(request));
            }

            if (request.DataList is null)
            {
                throw new ArgumentException(Resource.ExceptionDataListNull, nameof(request));
            }

            if (request.DataList.Count == 0)
            {
                throw new ArgumentException(Resource.ExceptionDataListEmpty, nameof(request));
            }

            if (request.DataList.Count > 100)
            {
                throw new ArgumentException(Resource.ExceptionDataListTooLarge, nameof(request));
            }

            for (int index = 0; index < request.DataList.Count; index++)
            {
                var data = request.DataList[index];

                switch (data.ContentType)
                {
                case MimeTypes.ImageGif:
                case MimeTypes.ImageJpeg:
                case MimeTypes.ImagePng:
                case MimeTypes.ImageWebp:
                    try
                    {
                        await _imageValidator.ValidateAsync(data.Data, data.ContentType);
                    }
                    catch (ImageException e)
                    {
                        throw new TimelinePostCreateDataException(index, Resource.ExceptionPostDataImageInvalid, e);
                    }
                    break;

                case MimeTypes.TextPlain:
                case MimeTypes.TextMarkdown:
                    try
                    {
                        new UTF8Encoding(false, true).GetString(data.Data);
                    }
                    catch (DecoderFallbackException e)
                    {
                        throw new TimelinePostCreateDataException(index, Resource.ExceptionPostDataNotValidUtf8, e);
                    }
                    break;

                default:
                    throw new TimelinePostCreateDataException(index, Resource.ExceptionPostDataUnsupportedType);
                }
            }

            request.Time = request.Time?.MyToUtc();

            await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);

            await _basicUserService.ThrowIfUserNotExist(authorId);

            var currentTime = _clock.GetCurrentTime();
            var finalTime   = request.Time ?? currentTime;

            await using var transaction = await _database.Database.BeginTransactionAsync();

            var postEntity = new TimelinePostEntity
            {
                AuthorId    = authorId,
                TimelineId  = timelineId,
                Time        = finalTime,
                LastUpdated = currentTime,
                Color       = request.Color
            };

            var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).SingleAsync();

            timelineEntity.CurrentPostLocalId += 1;
            postEntity.LocalId = timelineEntity.CurrentPostLocalId;
            _database.TimelinePosts.Add(postEntity);
            await _database.SaveChangesAsync();

            List <string> dataTags = new List <string>();

            for (int index = 0; index < request.DataList.Count; index++)
            {
                var data = request.DataList[index];

                var tag = await _dataManager.RetainEntryAsync(data.Data);

                _database.TimelinePostData.Add(new TimelinePostDataEntity
                {
                    DataTag     = tag,
                    Kind        = data.ContentType,
                    Index       = index,
                    PostId      = postEntity.Id,
                    LastUpdated = currentTime,
                });
            }

            await _database.SaveChangesAsync();

            await transaction.CommitAsync();

            _logger.LogInformation(Resource.LogTimelinePostCreated, timelineId, postEntity.Id);

            return(postEntity);
        }
Ejemplo n.º 12
0
        public async Task <UserEntity> ModifyUserAsync(long id, ModifyUserParams?param)
        {
            if (param is not null)
            {
                if (param.Username is not null)
                {
                    CheckUsernameFormat(param.Username, nameof(param));
                }

                if (param.Password is not null)
                {
                    CheckPasswordFormat(param.Password, nameof(param));
                }

                if (param.Nickname is not null)
                {
                    CheckNicknameFormat(param.Nickname, nameof(param));
                }
            }

            var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();

            if (entity is null)
            {
                throw CreateUserNotExistException(id);
            }

            if (param is not null)
            {
                var  now = _clock.GetCurrentTime();
                bool updateLastModified = false;

                var username = param.Username;
                if (username is not null && username != entity.Username)
                {
                    var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == username);

                    if (conflict)
                    {
                        throw CreateUsernameConflictException(username);
                    }

                    entity.Username           = username;
                    entity.UsernameChangeTime = now;
                    updateLastModified        = true;
                }

                var password = param.Password;
                if (password is not null)
                {
                    entity.Password = _passwordService.HashPassword(password);
                    entity.Version += 1;
                }

                var nickname = param.Nickname;
                if (nickname is not null && nickname != entity.Nickname)
                {
                    entity.Nickname    = nickname;
                    updateLastModified = true;
                }

                if (updateLastModified)
                {
                    entity.LastModified = now;
                }

                await _databaseContext.SaveChangesAsync();

                _logger.LogInformation(Resource.LogUserModified, entity.Username, id);
            }

            return(entity);
        }