public async Task <OAuthUser> RegisterViaGithub(GithubRegistrationData data, GithubUserInfo githubUserInfo) { var githubUser = new OAuthUser(); if (!oAuthService.IsGithubUserRegistered(githubUserInfo.Id)) { var user = dbContext.Users.FirstOrDefault(u => u.Email == githubUserInfo.Email); if (user == null) { user = dbContext.Users.Add(new User { UserName = githubUserInfo.Login, Email = githubUserInfo.Email, IsActive = true, ActivationToken = null }).Entity; } githubUser = new OAuthUser { User = user, OAuthId = githubUserInfo.Id, Email = githubUserInfo.Email, Login = githubUserInfo.Login }; dbContext.OAuthUsers.Add(githubUser); await dbContext.SaveChangesAsync(); } return(githubUser); }
public async Task <IActionResult> GithubCallback([FromQuery] IDictionary <string, string> query) { if (query["code"] == null) { return(Redirect("/")); } Dictionary <string, string> parameters = new Dictionary <string, string>(); parameters["code"] = query["code"]; parameters["client_id"] = _oauthConfig.Value.Github.client_id; parameters["redirect_uri"] = $"https://{this.Request.Host}/Auth/GithubCallback"; parameters["client_secret"] = _oauthConfig.Value.Github.client_secret; parameters["state"] = Guid.NewGuid().ToString(); GithubToken userToken = await requester.Post <GithubToken>("https://github.com/login/oauth/access_token", parameters); if (userToken == null) { TempData["error"] = "Could not link your Github account."; return(Redirect("/")); } if (string.IsNullOrEmpty(userToken.access_token)) { TempData["error"] = "Could not link your account. Provider (Github) returned no info."; return(Redirect("/")); } Dictionary <string, string> headers = new Dictionary <string, string>(); headers.Add("Authorization", $"token {userToken.access_token}"); GithubUserInfo userinfo = await requester.Get <GithubUserInfo>("https://api.github.com/user", headers); if (userinfo is null) { TempData["error"] = "Github identity could not be resolved."; return(Redirect("/")); } // Fetching data var userWithMatchingToken = await _context.Users.Where(c => c.Credentials.Any(cred => cred.Provider == AuthProvider.GITHUB && cred.Token == userinfo.Id)).FirstOrDefaultAsync(); var userWithMatchingEmail = await _context.Users.Where(c => userinfo.Email != null && c.Email == userinfo.Email).FirstOrDefaultAsync(); // If user is logged in and the auth token is not registered yet, link. if (HttpContext.Session.GetString("user") != null) { var user = await _context.Users.Where(c => c.Id == HttpContext.Session.GetString("user")).Include("Credentials").FirstOrDefaultAsync(); // If someone already has that token OR there is a user that has the email but is not the same user. if (userWithMatchingToken != null || (userWithMatchingEmail != null && userWithMatchingEmail.Email != user.Email)) { TempData["error"] = "This Github account is already linked!"; return(Redirect("/")); } if (user.Credentials == null) { user.Credentials = new List <Credential>(); } // Adding the token and saving user.Credentials.Add(new Credential(AuthProvider.GITHUB, userinfo.Id)); await _context.SaveChangesAsync(); TempData["info"] = "You have linked your Github account!"; return(Redirect("/")); } // If user is NOT logged in, check if linked to some account, and log user in. if (userWithMatchingToken != null) { HttpContext.Session.SetString("user", userWithMatchingToken.Id); return(Redirect("/")); } // If NOT linked, create a new account ONLY if that email is not used already.` if (userinfo.Email != null && userWithMatchingEmail?.Email == userinfo.Email) { TempData["error"] = "This Github account's email has been used to create an account here, so you can not link it!"; return(Redirect("/")); } // Creating a new account: User u = new User(userinfo.Email, "", new Credential(AuthProvider.GITHUB, userinfo.Id)); _context.Users.Add(u); await _context.SaveChangesAsync(); // Assigning user id to session HttpContext.Session.SetString("user", u.Id); // Setting info alert TempData["info"] = "You have successfully created an account with Github!"; return(Redirect("/")); }
public IHttpActionResult Get(string code, string state) { bool checkResult = false; string fromQQ = Encryption.AesDecrypt(state); var tokenModel = githubConnector.AccessToken(code, ref checkResult); // 获取Access Token if (tokenModel != null) { if (!tokenModel.scope.Contains("repo") || tokenModel.scope == null) // 用户手动更改了权限,向用户返回权限不足信息 { CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "抱歉,您申请的权限不足,绑定失败!"); return(BadRequest("权限不足")); } // 调用Github API获取用户数据 try { GithubUserInfo userInfo = githubConnector.GetUserInfo(tokenModel.access_token); // 用户信息 List <GithubRepositoryInfo> repositories = githubConnector.GetRepositories(tokenModel.access_token); // 授权用户的所有仓库信息 using (var context = new GithubWatcherContext()) { var user = context.GithubBindings.FirstOrDefault(s => s.GithubUserName == userInfo.Login); // 如果不存在,则往数据库中添加信息 if (user == null) { GithubBinding newBinding = new GithubBinding(); newBinding.QQ = fromQQ; newBinding.GithubUserName = userInfo.Login; newBinding.AccessToken = tokenModel.access_token; context.GithubBindings.Add(newBinding); CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "绑定Github账户" + userInfo.Login + "成功!"); } else if (user.QQ == fromQQ) { if (user.AccessToken == tokenModel.access_token) { CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "您已经绑定过该Github账户!"); } else { // 更新accessToken user.AccessToken = tokenModel.access_token; CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "您已经绑定过该Github账户,已为您刷新Access Token,请尽快完成仓库绑定操作。"); } } else { CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "抱歉,该Github账户已被其他用户绑定!"); } foreach (var repository in repositories) { var query = context.RepositoryInformations.FirstOrDefault(s => s.GithubUserName == userInfo.Login && s.Repository == repository.FullName); // 如果不存在,则往数据库中添加信息 if (query == null) { RepositoryInformation newRepositoryInfo = new RepositoryInformation(); newRepositoryInfo.GithubUserName = userInfo.Login; newRepositoryInfo.Repository = repository.FullName; context.RepositoryInformations.Add(newRepositoryInfo); } } context.SaveChanges(); return(Ok("绑定成功!")); } } catch (Exception e) { if (e.Message.Contains("基础连接已经关闭: 发送时发生错误")) { CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "您的访问过于频繁,请稍后再试!"); } else { CQ.Api.SendPrivateMessage(Convert.ToInt64(fromQQ), "错误:" + e.Message + "请联系管理员QQ:2426837192!"); } return(BadRequest(e.Message)); } } return(BadRequest("获取Access Token失败!")); }