repo_description: The only Kubernetes dashboard you need
repo_topics: aks appops argocd continuous-deployment dashboard deployment deployment-automation deployment-pipeline deployment-strategy devtron eks gitops gke hacktoberfest kubectl kubernetes kubernetes-dashboard kubernetes-deployment release-automation workflow-engine
code: /*
   * Copyright (c) 2020-2024. Devtron Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License 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.
   */
  
  package restHandler
  
  import (
  	"encoding/json"
  	"github.com/devtron-labs/devtron/pkg/build/git/gitProvider"
  	"github.com/devtron-labs/devtron/pkg/build/git/gitProvider/bean"
  	"github.com/devtron-labs/devtron/pkg/build/git/gitProvider/read"
  	"net/http"
  
  	"github.com/devtron-labs/devtron/api/restHandler/common"
  	"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
  	"github.com/devtron-labs/devtron/pkg/auth/user"
  	delete2 "github.com/devtron-labs/devtron/pkg/delete"
  	"github.com/devtron-labs/devtron/pkg/pipeline"
  	"github.com/devtron-labs/devtron/pkg/team"
  	"github.com/gorilla/mux"
  	"go.uber.org/zap"
  	"gopkg.in/go-playground/validator.v9"
  )
  
  const GIT_ACCOUNT_DELETE_SUCCESS_RESP = "Git account deleted successfully."
  
  type GitProviderRestHandler interface {
  	SaveGitRepoConfig(w http.ResponseWriter, r *http.Request)
  	GetGitProviders(w http.ResponseWriter, r *http.Request)
  	FetchAllGitProviders(w http.ResponseWriter, r *http.Request)
  	FetchOneGitProviders(w http.ResponseWriter, r *http.Request)
  	UpdateGitRepoConfig(w http.ResponseWriter, r *http.Request)
  	DeleteGitRepoConfig(w http.ResponseWriter, r *http.Request)
  }
  
  type GitProviderRestHandlerImpl struct {
  	dockerRegistryConfig   pipeline.DockerRegistryConfig
  	logger                 *zap.SugaredLogger
  	gitRegistryConfig      gitProvider.GitRegistryConfig
  	gitProviderReadService read.GitProviderReadService
  	userAuthService        user.UserService
  	validator              *validator.Validate
  	enforcer               casbin.Enforcer
  	teamService            team.TeamService
  	deleteServiceFullMode  delete2.DeleteServiceFullMode
  }
  
  func NewGitProviderRestHandlerImpl(dockerRegistryConfig pipeline.DockerRegistryConfig,
  	logger *zap.SugaredLogger,
  	gitRegistryConfig gitProvider.GitRegistryConfig,
  	userAuthService user.UserService,
  	validator *validator.Validate, enforcer casbin.Enforcer, teamService team.TeamService,
  	deleteServiceFullMode delete2.DeleteServiceFullMode,
  	gitProviderReadService read.GitProviderReadService) *GitProviderRestHandlerImpl {
  	return &GitProviderRestHandlerImpl{
  		dockerRegistryConfig:   dockerRegistryConfig,
  		logger:                 logger,
  		gitRegistryConfig:      gitRegistryConfig,
  		gitProviderReadService: gitProviderReadService,
  		userAuthService:        userAuthService,
  		validator:              validator,
  		enforcer:               enforcer,
  		teamService:            teamService,
  		deleteServiceFullMode:  deleteServiceFullMode,
  	}
  }
  
  func (impl GitProviderRestHandlerImpl) SaveGitRepoConfig(w http.ResponseWriter, r *http.Request) {
  	decoder := json.NewDecoder(r.Body)
  	userId, err := impl.userAuthService.GetLoggedInUser(r)
  	if userId == 0 || err != nil {
  		common.HandleUnauthorized(w, r)
  		return
  	}
  	var bean bean.GitRegistry
  	err = decoder.Decode(&bean)
  	if err != nil {
  		impl.logger.Errorw("request err, SaveGitRepoConfig", "err", err, "payload", bean)
  		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
  		return
  	}
  	bean.UserId = userId
  	impl.logger.Infow("request payload, SaveGitRepoConfig", "err", err, "payload", bean)
  	err = impl.validator.Struct(bean)
  	if err != nil {
  		impl.logger.Errorw("validation err, SaveGitRepoConfig", "err", err, "payload", bean)
  		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
  		return
  	}
  
  	// RBAC enforcer applying
  	token := r.Header.Get("token")
  	if ok := impl.enforcer.Enforce(token, casbin.ResourceGit, casbin.ActionCreate, bean.Name); !ok {
  		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
  		return
  	}
  	//RBAC enforcer Ends
  
  	res, err := impl.gitRegistryConfig.Create(&bean)
  	if err != nil {
  		impl.logger.Errorw("Failed to create git provider", "gitProviderName", bean.Name, "err", err)
  		// Use enhanced error response with resource context
  		common.WriteJsonRespWithResourceContext(w, err, nil, 0, "git provider", bean.Name)
  		return
  	}
  	common.WriteJsonResp(w, err, res, http.StatusOK)
  }
  
  func (impl GitProviderRestHandlerImpl) GetGitProviders(w http.ResponseWriter, r *http.Request) {
  	res, err := impl.gitProviderReadService.GetAll()
  	if err != nil {
  		impl.logger.Errorw("Failed to get git providers", "err", err)
  		// Use enhanced error response for service errors
  		common.WriteJsonRespWithResourceContext(w, err, nil, 0, "git providers", "all")
  		return
  	}
  
  	common.WriteJsonResp(w, err, res, http.StatusOK)
  }
  
  func (impl GitProviderRestHandlerImpl) FetchAllGitProviders(w http.ResponseWriter, r *http.Request) {
  	res, err := impl.gitProviderReadService.FetchAllGitProviders()
  	if err != nil {
  		impl.logger.Errorw("service err, FetchAllGitProviders", "err", err)
  		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
  		return
  	}
  
  	// RBAC enforcer applying
  	token := r.Header.Get("token")
  	result := make([]bean.GitRegistry, 0)
  	for _, item := range res {
  		if ok := impl.enforcer.Enforce(token, casbin.ResourceGit, casbin.ActionGet, item.Name); ok {
  			result = append(result, item)
  		}
  	}
  	//RBAC enforcer Ends
  
  	common.WriteJsonResp(w, err, result, http.StatusOK)
  }
  
  func (impl GitProviderRestHandlerImpl) FetchOneGitProviders(w http.ResponseWriter, r *http.Request) {
  	params := mux.Vars(r)
  	id := params["id"]
  	res, err := impl.gitProviderReadService.FetchOneGitProvider(id)
  	if err != nil {
  		impl.logger.Errorw("service err, FetchOneGitProviders", "err", err, "id", id)
  		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
  		return
  	}
  
  	// RBAC enforcer applying
  	token := r.Header.Get("token")
  	if ok := impl.enforcer.Enforce(token, casbin.ResourceGit, casbin.ActionGet, res.Name); !ok {
  		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
  		return
  	}
  	//RBAC enforcer Ends
  
  	common.WriteJsonResp(w, err, res, http.StatusOK)
  }
  
  func (impl GitProviderRestHandlerImpl) UpdateGitRepoConfig(w http.ResponseWriter, r *http.Request) {
  	decoder := json.NewDecoder(r.Body)
  	userId, err := impl.userAuthService.GetLoggedInUser(r)
  	if userId == 0 || err != nil {
  		common.HandleUnauthorized(w, r)
  		return
  	}
  	var bean bean.GitRegistry
  	err = decoder.Decode(&bean)
  	if err != nil {
  		impl.logger.Errorw("request err, UpdateGitRepoConfig", "err", err, "gitRegistryId", bean.Id)
  		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
  		return
  	}
  	bean.UserId = userId
  	impl.logger.Infow("request payload, UpdateGitRepoConfig", "gitRegistryId", bean.Id)
  	err = impl.validator.Struct(bean)
  	if err != nil {
  		impl.logger.Errorw("validation err, UpdateGitRepoConfig", "err", err, "gitRegistryId", bean.Id)
  		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
  		return
  	}
  	// RBAC enforcer applying
  	token := r.Header.Get("token")
  	if ok := impl.enforcer.Enforce(token, casbin.ResourceGit, casbin.ActionUpdate, bean.Name); !ok {
  		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
  		return
  	}
  	//RBAC enforcer Ends
  
  	res, err := impl.gitRegistryConfig.Update(&bean)
  	if err != nil {
  		impl.logger.Errorw("service err, UpdateGitRepoConfig", "err", err, "gitRegistryId", bean.Id)
  		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
  		return
  	}
  	common.WriteJsonResp(w, err, res, http.StatusOK)
  }
  
  func (impl GitProviderRestHandlerImpl) DeleteGitRepoConfig(w http.ResponseWriter, r *http.Request) {
  	decoder := json.NewDecoder(r.Body)
  	userId, err := impl.userAuthService.GetLoggedInUser(r)
  	if userId == 0 || err != nil {
  		common.HandleUnauthorized(w, r)
  		return
  	}
  	var bean bean.GitRegistry
  	err = decoder.Decode(&bean)
  	if err != nil {
  		impl.logger.Errorw("request err, DeleteGitRepoConfig", "err", err, "payload", bean)
  		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
  		return
  	}
  	bean.UserId = userId
  	impl.logger.Infow("request payload, DeleteGitRepoConfig", "payload", bean)
  	err = impl.validator.Struct(bean)
  	if err != nil {
  		impl.logger.Errorw("validation err, DeleteGitRepoConfig", "err", err, "payload", bean)
  		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
  		return
  	}
  	// RBAC enforcer applying
  	token := r.Header.Get("token")
  	if ok := impl.enforcer.Enforce(token, casbin.ResourceGit, casbin.ActionCreate, bean.Name); !ok {
  		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
  		return
  	}
  	//RBAC enforcer Ends
  	err = impl.deleteServiceFullMode.DeleteGitProvider(&bean)
  	if err != nil {
  		impl.logger.Errorw("error in deleting git account", "err", err, "payload", bean)
  		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
  		return
  	}
  	common.WriteJsonResp(w, err, GIT_ACCOUNT_DELETE_SUCCESS_RESP, http.StatusOK)
  }
  