diff --git a/modules/structs/auth_oauth2.go b/modules/structs/auth_oauth2.go new file mode 100644 index 0000000000..af1f87facd --- /dev/null +++ b/modules/structs/auth_oauth2.go @@ -0,0 +1,54 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// CreateUserOption create user options +type CreateAuthOauth2Option struct { + AuthenticationName string `json:"authentication_name" binding:"Required"` + ProviderIconURL string `json:"provider_icon_url"` + ProviderClientID string `json:"provider_client_id" binding:"Required"` + ProviderClientSecret string `json:"provider_client_secret" binding:"Required"` + ProviderAutoDiscoveryURL string `json:"provider_auto_discovery_url" binding:"Required"` + + SkipLocal2FA bool `json:"skip_local_2fa"` + AdditionalScopes string `json:"additional_scopes"` + RequiredClaimName string `json:"required_claim_name"` + RequiredClaimValue string `json:"required_claim_value"` + + ClaimNameProvidingGroupNameForSource string `json:"claim_name_providingGroupNameForSource"` + GroupClaimValueForAdministratorUsers string `json:"group_claim_value_for_administrator_users"` + GroupClaimValueForRestrictedUsers string `json:"group_claim_value_for_restricted_users"` + MapClaimedGroupsToOrganizationTeams string `json:"map_claimed_groups_to_organization_teams"` + + RemoveUsersFromSyncronizedTeams bool `json:"RemoveUsersFromSyncronizedTeams"` + EnableUserSyncronization bool `json:"EnableUserSyncronization"` + AuthenticationSourceIsActive bool `json:"AuthenticationSourceIsActive"` +} + +// EditUserOption edit user options +type EditAuthOauth2Option struct { + // // required: true + SourceID int64 `json:"source_id"` + + AuthenticationName string `json:"authentication_name" binding:"Required"` + ProviderIconURL string `json:"provider_icon_url"` + ProviderClientID string `json:"provider_client_id" binding:"Required"` + ProviderClientSecret string `json:"provider_client_secret" binding:"Required"` + ProviderAutoDiscoveryURL string `json:"provider_auto_discovery_url" binding:"Required"` + + SkipLocal2FA bool `json:"skip_local_2fa"` + AdditionalScopes string `json:"additional_scopes"` + RequiredClaimName string `json:"required_claim_name"` + RequiredClaimValue string `json:"required_claim_value"` + + ClaimNameProvidingGroupNameForSource string `json:"claim_name_providingGroupNameForSource"` + GroupClaimValueForAdministratorUsers string `json:"group_claim_value_for_administrator_users"` + GroupClaimValueForRestrictedUsers string `json:"group_claim_value_for_restricted_users"` + MapClaimedGroupsToOrganizationTeams string `json:"map_claimed_groups_to_organization_teams"` + + RemoveUsersFromSyncronizedTeams bool `json:"RemoveUsersFromSyncronizedTeams"` + EnableUserSyncronization bool `json:"EnableUserSyncronization"` + AuthenticationSourceIsActive bool `json:"AuthenticationSourceIsActive"` +} diff --git a/routers/api/v1/admin/auth_oauth.go b/routers/api/v1/admin/auth_oauth.go new file mode 100644 index 0000000000..32422ebedf --- /dev/null +++ b/routers/api/v1/admin/auth_oauth.go @@ -0,0 +1,81 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package admin + +import ( + "fmt" + "net/http" + "net/url" + + auth_model "code.gitea.io/gitea/models/auth" + api "code.gitea.io/gitea/modules/structs" + + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/auth/source/oauth2" + "code.gitea.io/gitea/services/context" +) + +// CreateOauthAuth create a new external authentication for oauth2 +func CreateOauthAuth(ctx *context.APIContext) { + form := web.GetForm(ctx).(*api.CreateAuthOauth2Option) + + var scopes []string + // for _, s := range strings.Split(form.Oauth2Scopes, ",") { + // s = strings.TrimSpace(s) + // if s != "" { + // scopes = append(scopes, s) + // } + // } + + discoveryURL, err := url.Parse(form.ProviderAutoDiscoveryURL) + if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") { + fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", form.ProviderAutoDiscoveryURL) + + // todo: implement handling + } + + config := &oauth2.Source{ + Provider: "openidConnect", + ClientID: form.ProviderClientID, + ClientSecret: form.ProviderClientSecret, + OpenIDConnectAutoDiscoveryURL: form.ProviderAutoDiscoveryURL, + CustomURLMapping: nil, + IconURL: form.ProviderIconURL, + Scopes: scopes, + RequiredClaimName: form.RequiredClaimName, + RequiredClaimValue: form.RequiredClaimValue, + SkipLocalTwoFA: form.SkipLocal2FA, + + GroupClaimName: form.ClaimNameProvidingGroupNameForSource, + RestrictedGroup: form.GroupClaimValueForRestrictedUsers, + AdminGroup: form.GroupClaimValueForAdministratorUsers, + GroupTeamMap: form.MapClaimedGroupsToOrganizationTeams, + GroupTeamMapRemoval: form.RemoveUsersFromSyncronizedTeams, + } + + auth_model.CreateSource(ctx, &auth_model.Source{ + Type: auth_model.OAuth2, + Name: form.AuthenticationName, + IsActive: true, + Cfg: config, + }) + + ctx.Status(http.StatusCreated) + + // ctx.JSON(http.StatusCreated, convert.ToUser(ctx, u, ctx.Doer)) +} + +// EditOauthAuth api for modifying a authentication method +func EditOauthAuth(ctx *context.APIContext) { +} + +// DeleteOauthAuth api for deleting a authentication method +func DeleteOauthAuth(ctx *context.APIContext) { +} + +// // SearchOauthAuth API for getting information of the configured authentication methods according the filter conditions +func SearchOauthAuth(ctx *context.APIContext) { + +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index b9b590725b..d1f3c8dd9b 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1649,6 +1649,10 @@ func Routes() *web.Router { }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(false, true), reqToken(), reqTeamMembership(), checkTokenPublicOnly()) m.Group("/admin", func() { + m.Group("/identity-auth", func() { + m.Post("/new", admin.CreateOauthAuth) + }) + m.Group("/cron", func() { m.Get("", admin.ListCronTasks) m.Post("/{task}", admin.PostCronTask)