code.gitea.io/gitea@v1.19.3/modules/setting/oauth2.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package setting 5 6 import ( 7 "math" 8 "path/filepath" 9 10 "code.gitea.io/gitea/modules/log" 11 12 "gopkg.in/ini.v1" 13 ) 14 15 // OAuth2UsernameType is enum describing the way gitea 'name' should be generated from oauth2 data 16 type OAuth2UsernameType string 17 18 const ( 19 // OAuth2UsernameUserid oauth2 userid field will be used as gitea name 20 OAuth2UsernameUserid OAuth2UsernameType = "userid" 21 // OAuth2UsernameNickname oauth2 nickname field will be used as gitea name 22 OAuth2UsernameNickname OAuth2UsernameType = "nickname" 23 // OAuth2UsernameEmail username of oauth2 email filed will be used as gitea name 24 OAuth2UsernameEmail OAuth2UsernameType = "email" 25 ) 26 27 func (username OAuth2UsernameType) isValid() bool { 28 switch username { 29 case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail: 30 return true 31 } 32 return false 33 } 34 35 // OAuth2AccountLinkingType is enum describing behaviour of linking with existing account 36 type OAuth2AccountLinkingType string 37 38 const ( 39 // OAuth2AccountLinkingDisabled error will be displayed if account exist 40 OAuth2AccountLinkingDisabled OAuth2AccountLinkingType = "disabled" 41 // OAuth2AccountLinkingLogin account linking login will be displayed if account exist 42 OAuth2AccountLinkingLogin OAuth2AccountLinkingType = "login" 43 // OAuth2AccountLinkingAuto account will be automatically linked if account exist 44 OAuth2AccountLinkingAuto OAuth2AccountLinkingType = "auto" 45 ) 46 47 func (accountLinking OAuth2AccountLinkingType) isValid() bool { 48 switch accountLinking { 49 case OAuth2AccountLinkingDisabled, OAuth2AccountLinkingLogin, OAuth2AccountLinkingAuto: 50 return true 51 } 52 return false 53 } 54 55 // OAuth2Client settings 56 var OAuth2Client struct { 57 RegisterEmailConfirm bool 58 OpenIDConnectScopes []string 59 EnableAutoRegistration bool 60 Username OAuth2UsernameType 61 UpdateAvatar bool 62 AccountLinking OAuth2AccountLinkingType 63 } 64 65 func loadOAuth2ClientFrom(rootCfg ConfigProvider) { 66 sec := rootCfg.Section("oauth2_client") 67 OAuth2Client.RegisterEmailConfirm = sec.Key("REGISTER_EMAIL_CONFIRM").MustBool(Service.RegisterEmailConfirm) 68 OAuth2Client.OpenIDConnectScopes = parseScopes(sec, "OPENID_CONNECT_SCOPES") 69 OAuth2Client.EnableAutoRegistration = sec.Key("ENABLE_AUTO_REGISTRATION").MustBool() 70 OAuth2Client.Username = OAuth2UsernameType(sec.Key("USERNAME").MustString(string(OAuth2UsernameNickname))) 71 if !OAuth2Client.Username.isValid() { 72 log.Warn("Username setting is not valid: '%s', will fallback to '%s'", OAuth2Client.Username, OAuth2UsernameNickname) 73 OAuth2Client.Username = OAuth2UsernameNickname 74 } 75 OAuth2Client.UpdateAvatar = sec.Key("UPDATE_AVATAR").MustBool() 76 OAuth2Client.AccountLinking = OAuth2AccountLinkingType(sec.Key("ACCOUNT_LINKING").MustString(string(OAuth2AccountLinkingLogin))) 77 if !OAuth2Client.AccountLinking.isValid() { 78 log.Warn("Account linking setting is not valid: '%s', will fallback to '%s'", OAuth2Client.AccountLinking, OAuth2AccountLinkingLogin) 79 OAuth2Client.AccountLinking = OAuth2AccountLinkingLogin 80 } 81 } 82 83 func parseScopes(sec *ini.Section, name string) []string { 84 parts := sec.Key(name).Strings(" ") 85 scopes := make([]string, 0, len(parts)) 86 for _, scope := range parts { 87 if scope != "" { 88 scopes = append(scopes, scope) 89 } 90 } 91 return scopes 92 } 93 94 var OAuth2 = struct { 95 Enable bool 96 AccessTokenExpirationTime int64 97 RefreshTokenExpirationTime int64 98 InvalidateRefreshTokens bool 99 JWTSigningAlgorithm string `ini:"JWT_SIGNING_ALGORITHM"` 100 JWTSecretBase64 string `ini:"JWT_SECRET"` 101 JWTSigningPrivateKeyFile string `ini:"JWT_SIGNING_PRIVATE_KEY_FILE"` 102 MaxTokenLength int 103 }{ 104 Enable: true, 105 AccessTokenExpirationTime: 3600, 106 RefreshTokenExpirationTime: 730, 107 InvalidateRefreshTokens: false, 108 JWTSigningAlgorithm: "RS256", 109 JWTSigningPrivateKeyFile: "jwt/private.pem", 110 MaxTokenLength: math.MaxInt16, 111 } 112 113 func loadOAuth2From(rootCfg ConfigProvider) { 114 if err := rootCfg.Section("oauth2").MapTo(&OAuth2); err != nil { 115 log.Fatal("Failed to OAuth2 settings: %v", err) 116 return 117 } 118 119 if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) { 120 OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile) 121 } 122 }